diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java index 990cddd1377..e96f623222c 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java @@ -1968,4 +1968,8 @@ public interface CommonApplicationConstants extends Constants { String preferredVncOption(); String defaultClient(); + + String hideUsedLunsForISCSILabel(); + + String hideUsedLunsForFCPLabel(); } diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/PaginationControl.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/PaginationControl.java index 6fe47f12243..1017d966e7c 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/PaginationControl.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/PaginationControl.java @@ -54,6 +54,10 @@ public void goBack() { @Override public void refresh() { } + + @Override + public void reload() { + } }; interface WidgetUiBinder extends UiBinder { @@ -114,6 +118,11 @@ public void setDataProvider(PagingDataProvider dataProvider) { updateTableControls(); } + public void reload() { + getDataProvider().reload(); + updateTableControls(); + } + @UiHandler("prevPageButton") public void handlePrevPageButtonClick(ClickEvent event) { getDataProvider().goBack(); diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/HasPaging.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/HasPaging.java index ead0b0fd39b..a41de258c27 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/HasPaging.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/HasPaging.java @@ -1,5 +1,7 @@ package org.ovirt.engine.ui.common.widget.table; +import java.util.Collection; + /** * Classes that implement this interface support forward/back paging functionality. * @@ -30,4 +32,18 @@ public interface HasPaging { * Refresh the current page. */ void refresh(); + + /** + * Reload all and go to the first page. + */ + default void reload() { + + } + + /** + * Reload all and go to the first page (with providing access to the items, if needed). + */ + default void reload(Collection items) { + + } } diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/FcpStorageView.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/FcpStorageView.java index 9e1fe060942..4e710d2611a 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/FcpStorageView.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/FcpStorageView.java @@ -2,7 +2,10 @@ import java.util.List; +import org.gwtbootstrap3.client.ui.CheckBox; +import org.ovirt.engine.ui.common.CommonApplicationConstants; import org.ovirt.engine.ui.common.editor.UiCommonEditorDriver; +import org.ovirt.engine.ui.common.gin.AssetProvider; import org.ovirt.engine.ui.common.widget.HasValidation; import org.ovirt.engine.ui.common.widget.PaginationControl; import org.ovirt.engine.ui.common.widget.ValidatedPanelWidget; @@ -11,6 +14,7 @@ import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Style.Unit; +import com.google.gwt.safehtml.shared.SafeHtmlUtils; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Label; @@ -32,14 +36,23 @@ public class FcpStorageView extends AbstractStorageView imp @UiField PaginationControl paginationControl; + @UiField + @Ignore + CheckBox hideUsedLunsCheckBox; + + LunFilter lunFilter; + private final Driver driver = GWT.create(Driver.class); private double panelHeight = 292; private double listHeight = 278; + private static final CommonApplicationConstants constants = AssetProvider.getConstants(); + public FcpStorageView(boolean multiSelection) { initWidget(ViewUiBinder.uiBinder.createAndBindUi(this)); + localize(); driver.initialize(this); this.multiSelection = multiSelection; } @@ -51,6 +64,10 @@ public FcpStorageView(boolean multiSelection, double panelHeight, double listHei this.listHeight = listHeight; } + void localize() { + hideUsedLunsCheckBox.setHTML(SafeHtmlUtils.fromString(constants.hideUsedLunsForFCPLabel())); + } + @Override public void edit(final SanStorageModelBase object) { driver.edit(object); @@ -64,6 +81,8 @@ public void edit(final SanStorageModelBase object) { onIsValidPropertyChange(object); } }); + + initHideUsedLunsCheckBox(); } void onIsValidPropertyChange(Model model) { @@ -105,8 +124,10 @@ public void focus() { protected void initLists(SanStorageModelBase model) { PageFilter pageFilter = new PageFilter(50); + lunFilter = new LunFilter(hideUsedLunsCheckBox.getValue()); SanStorageLunToTargetList sanStorageLunToTargetList = - new SanStorageLunToTargetList(PagingProxyModel.create(pageFilter, model), true, multiSelection); + new SanStorageLunToTargetList(PagingFilteredProxyModel.create(pageFilter, lunFilter, model), + true, multiSelection); sanStorageLunToTargetList.activateItemsUpdate(); paginationControl.setDataProvider(StoragePagingDataProvider.create(pageFilter, sanStorageLunToTargetList)); model.getItemsChangedEvent().addListener((ev, sender, args) -> paginationControl.updateTableControls()); @@ -119,6 +140,15 @@ protected void initLists(SanStorageModelBase model) { contentPanel.setWidget(sanStorageLunToTargetList); } + private void initHideUsedLunsCheckBox() { + hideUsedLunsCheckBox.addValueChangeHandler(event -> { + if (lunFilter != null) { + lunFilter.setIsHideUsedLuns(event.getValue()); + } + paginationControl.reload(); + }); + } + interface Driver extends UiCommonEditorDriver { } diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/FcpStorageView.ui.xml b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/FcpStorageView.ui.xml index 44586b9a5d4..bb8c4089173 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/FcpStorageView.ui.xml +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/FcpStorageView.ui.xml @@ -14,6 +14,12 @@ justify-content: flex-end; border-bottom: none; } + + .hideUsedLunsCheckBox { + font-size: 12px; + padding-left: 23px; + height: 10px; + } @@ -27,6 +33,9 @@ + + + diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/FilteredProxyModel.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/FilteredProxyModel.java new file mode 100644 index 00000000000..2975845115f --- /dev/null +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/FilteredProxyModel.java @@ -0,0 +1,29 @@ +package org.ovirt.engine.ui.common.widget.uicommon.storage; + +import java.util.Collection; + +import org.ovirt.engine.ui.uicommonweb.models.storage.SanStorageModelBase; + +/** + * Create a proxy model that will intercept {@link SanStorageModelBase#getItems()} and filter the items. + * From a logical point of view all data is still one model i.e. user changes are not lost when + * applying the filter and submitting. + */ +public class FilteredProxyModel extends ProxyModelBase { + + private final ModelFilter filter; + + public FilteredProxyModel(SanStorageModelBase model, ModelFilter filter) { + super(model); + this.filter = filter; + } + + public static FilteredProxyModel create(ModelFilter filter, SanStorageModelBase model) { + return new FilteredProxyModel(model, filter); + } + + @Override + public Collection getItems() { + return filter.filter(getModel().getItems()); + } +} diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/IscsiLunToTargetView.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/IscsiLunToTargetView.java index 4bb9ef0cccc..f07c4805b9b 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/IscsiLunToTargetView.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/IscsiLunToTargetView.java @@ -30,6 +30,8 @@ interface ViewUiBinder extends UiBinder { private final double treeHeight; private final boolean multiSelection; + private LunFilter lunFilter; + public IscsiLunToTargetView(double treeHeight, boolean multiSelection) { this.treeHeight = treeHeight; this.multiSelection = multiSelection; @@ -38,6 +40,11 @@ public IscsiLunToTargetView(double treeHeight, boolean multiSelection) { driver.initialize(this); } + public IscsiLunToTargetView(double treeHeight, boolean multiSelection, LunFilter lunFilter) { + this(treeHeight, multiSelection); + this.lunFilter = lunFilter; + } + @Override public void edit(final SanStorageModelBase object) { driver.edit(object); @@ -45,7 +52,8 @@ public void edit(final SanStorageModelBase object) { } void initLists(SanStorageModelBase object) { - sanStorageLunToTargetList = new SanStorageLunToTargetList(object, false, multiSelection); + sanStorageLunToTargetList = new SanStorageLunToTargetList(FilteredProxyModel.create(lunFilter, object), + false, multiSelection); sanStorageLunToTargetList.setTreeContainerHeight(treeHeight); lunsListPanel.add(sanStorageLunToTargetList); } diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/IscsiStorageView.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/IscsiStorageView.java index cd52c5af978..be38b3bac20 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/IscsiStorageView.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/IscsiStorageView.java @@ -2,6 +2,7 @@ import java.util.List; +import org.gwtbootstrap3.client.ui.CheckBox; import org.ovirt.engine.core.compat.StringHelper; import org.ovirt.engine.ui.common.CommonApplicationConstants; import org.ovirt.engine.ui.common.editor.UiCommonEditorDriver; @@ -72,11 +73,18 @@ interface ViewUiBinder extends UiBinder { @Ignore Label subLabel; + @UiField + @Ignore + CheckBox hideUsedLunsCheckBox; + private double treeCollapsedHeight = 245; private double treeExpandedHeight = 355; private double lunsTreeHeight = 405; private double tabContentHeight = 100; + private LunFilter lunFilter; + private SanTargetFilter sanTargetFilter; + private final Driver driver = GWT.create(Driver.class); private static final CommonApplicationConstants constants = AssetProvider.getConstants(); @@ -103,6 +111,7 @@ public IscsiStorageView(boolean multiSelection, void localize() { lunToTargetsTab.setLabel(constants.storageIscsiPopupLunToTargetsTabLabel()); targetsToLunTab.setLabel(constants.storageIscsiPopupTargetsToLunTabLabel()); + hideUsedLunsCheckBox.setHTML(SafeHtmlUtils.fromString(constants.hideUsedLunsForISCSILabel())); } @Override @@ -170,12 +179,17 @@ public void edit(final IscsiStorageModel object) { warning.setVisible(!StringHelper.isNullOrEmpty(warningText)); } }); + + initHideUsedLunsCheckBox(object); } void initLists(IscsiStorageModel object) { + lunFilter = new LunFilter(hideUsedLunsCheckBox.getValue()); + sanTargetFilter = new SanTargetFilter(hideUsedLunsCheckBox.getValue()); // Create discover panel and storage lists - iscsiTargetToLunView = new IscsiTargetToLunView(treeCollapsedHeight, treeExpandedHeight, false, multiSelection); - iscsiLunToTargetView = new IscsiLunToTargetView(lunsTreeHeight, multiSelection); + iscsiTargetToLunView = new IscsiTargetToLunView(treeCollapsedHeight, treeExpandedHeight, false, multiSelection, + sanTargetFilter, lunFilter); + iscsiLunToTargetView = new IscsiLunToTargetView(lunsTreeHeight, multiSelection, lunFilter); // Update Style dialogTabPanel.getElement().getStyle().setHeight(tabContentHeight, Unit.PCT); @@ -243,6 +257,18 @@ public void cleanup() { public void focus() { } + private void initHideUsedLunsCheckBox(IscsiStorageModel object) { + hideUsedLunsCheckBox.addValueChangeHandler(event -> { + if (lunFilter != null) { + lunFilter.setIsHideUsedLuns(event.getValue()); + } + if (sanTargetFilter != null) { + sanTargetFilter.setIsHideUsedLuns(event.getValue()); + } + updateListByGrouping(object); + }); + } + interface WidgetStyle extends CssResource { String barEditDomain(); diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/IscsiStorageView.ui.xml b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/IscsiStorageView.ui.xml index 5ed77f2d97e..5e3a9dbfaaa 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/IscsiStorageView.ui.xml +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/IscsiStorageView.ui.xml @@ -90,6 +90,12 @@ font-size: 12px; padding-left: 50px; } + + .hideUsedLunsCheckBox { + font-size: 12px; + padding-left: 60px; + height: 10px; + } @@ -105,6 +111,9 @@ + + + diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/IscsiTargetToLunView.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/IscsiTargetToLunView.java index f29b17fcf19..c4cdd3f5ade 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/IscsiTargetToLunView.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/IscsiTargetToLunView.java @@ -36,6 +36,9 @@ interface ViewUiBinder extends UiBinder { private boolean hideLeaf; private boolean multiSelection; + private SanTargetFilter sanTargetFilter; + private LunFilter leafLunFilter; + private final Driver driver = GWT.create(Driver.class); public IscsiTargetToLunView(double treeCollapsedHeight, double treeExpandedHeight) { @@ -53,6 +56,14 @@ public IscsiTargetToLunView(double treeCollapsedHeight, double treeExpandedHeigh driver.initialize(this); } + public IscsiTargetToLunView(double treeCollapsedHeight, double treeExpandedHeight, + boolean hideLeaf, boolean multiSelection, SanTargetFilter sanTargetFilter, + LunFilter leafLunFilter) { + this(treeCollapsedHeight, treeExpandedHeight, hideLeaf, multiSelection); + this.sanTargetFilter = sanTargetFilter; + this.leafLunFilter = leafLunFilter; + } + @Override public void edit(final SanStorageModelBase object) { driver.edit(object); @@ -88,7 +99,8 @@ private void setProposeDiscover(boolean proposeDiscover) { void initLists(SanStorageModelBase object) { // Create discover panel and storage lists iscsiDiscoverTargetsView = new IscsiDiscoverTargetsView(); - sanStorageTargetToLunList = new SanStorageTargetToLunList(object, hideLeaf, multiSelection); + sanStorageTargetToLunList = new SanStorageTargetToLunList(FilteredProxyModel.create(sanTargetFilter, object), + hideLeaf, multiSelection, leafLunFilter); // Add view widgets to panel targetsToLunsDiscoverPanel.add(iscsiDiscoverTargetsView); diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/LunFilter.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/LunFilter.java new file mode 100644 index 00000000000..63e0c99673e --- /dev/null +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/LunFilter.java @@ -0,0 +1,29 @@ +package org.ovirt.engine.ui.common.widget.uicommon.storage; + +import java.util.Collection; +import java.util.stream.Collectors; + +import org.ovirt.engine.ui.uicommonweb.models.storage.LunModel; + +/** + * LUN model filter. + */ +public class LunFilter extends LunFilterBase implements ModelFilter { + + public LunFilter(boolean isHideUsedLuns) { + super(isHideUsedLuns); + } + + public Collection filter(Collection items) { + if (items == null || !needFilter()) { + return items; + } + + return items.stream().filter(lunModel -> { + if (getIsHideUsedLuns()) { + return !lunModel.getIsUsed(); + } + return true; + }).collect(Collectors.toList()); + } +} diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/LunFilterBase.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/LunFilterBase.java new file mode 100644 index 00000000000..5b3b7d8148e --- /dev/null +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/LunFilterBase.java @@ -0,0 +1,30 @@ +package org.ovirt.engine.ui.common.widget.uicommon.storage; + +/** + * Base class of LUN model filter. + */ +public class LunFilterBase { + + private boolean isHideUsedLuns; + + public LunFilterBase(boolean isHideUsedLuns) { + this.isHideUsedLuns = isHideUsedLuns; + } + + public boolean getIsHideUsedLuns() { + return isHideUsedLuns; + } + + public void setIsHideUsedLuns(boolean isHideUsedLuns) { + this.isHideUsedLuns = isHideUsedLuns; + } + + /** + * Is it necessary to apply a filter. + * + * @return true - if at least one of the filter fields has a value other than the default value + */ + public boolean needFilter() { + return isHideUsedLuns; + } +} diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/ModelFilter.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/ModelFilter.java new file mode 100644 index 00000000000..b01023d9faf --- /dev/null +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/ModelFilter.java @@ -0,0 +1,13 @@ +package org.ovirt.engine.ui.common.widget.uicommon.storage; + +import java.util.Collection; + +import org.ovirt.engine.ui.uicommonweb.models.EntityModel; + +/** + * Interface of filter. + */ +public interface ModelFilter> { + + Collection filter(Collection items); +} diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/PageFilter.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/PageFilter.java index 307c1147d81..b4df22acc60 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/PageFilter.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/PageFilter.java @@ -41,9 +41,9 @@ public Collection filter(Collection items) { } if (currentSize != items.size() || !isCurrentPageValid()) { - currentSize = items.size(); currentPage = 0; } + currentSize = items.size(); return new ArrayList(items).subList(getFirstItemOnPage(), getLastItemOnPage() + 1); } @@ -73,6 +73,12 @@ public void refresh() { } + @Override + public void reload(Collection items) { + currentSize = items.size(); + currentPage = 0; + } + public boolean canGoForward() { return currentPage < numberOfPages(currentSize, pageSize) - 1; } diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/PagingFilteredProxyModel.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/PagingFilteredProxyModel.java new file mode 100644 index 00000000000..c6a3e55af29 --- /dev/null +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/PagingFilteredProxyModel.java @@ -0,0 +1,34 @@ +package org.ovirt.engine.ui.common.widget.uicommon.storage; + +import java.util.Collection; + +import org.ovirt.engine.ui.uicommonweb.models.storage.SanStorageModelBase; +import org.ovirt.engine.ui.uicommonweb.models.storage.SanStoragePartialModel; + +/** + * Create a proxy model that will intercept {@link SanStorageModelBase#getItems()} and filter the items according filter + * and then filter the items that belong to the current page. From a logical point of view all data is still one model + * i.e. user changes are not lost when changing page or applying filter and submitting. + */ +public class PagingFilteredProxyModel extends PagingProxyModel { + + private final LunFilter lunFilter; + + public PagingFilteredProxyModel(SanStorageModelBase model, PageFilter pageFilter, LunFilter lunFilter) { + super(model, pageFilter); + this.lunFilter = lunFilter; + } + + public static SanStoragePartialModel create(PageFilter pageFilter, LunFilter lunFilter, SanStorageModelBase model) { + return new PagingFilteredProxyModel(model, pageFilter, lunFilter); + } + + @Override + public Collection getItems() { + Collection items = getModel().getItems(); + if (lunFilter != null) { + items = lunFilter.filter(items); + } + return getPageFilter().filter(items); + } +} diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/PagingProxyModel.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/PagingProxyModel.java index 257d33acc89..09a63f8b5e0 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/PagingProxyModel.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/PagingProxyModel.java @@ -1,29 +1,21 @@ package org.ovirt.engine.ui.common.widget.uicommon.storage; import java.util.Collection; -import java.util.List; -import java.util.Set; -import org.ovirt.engine.ui.uicommonweb.models.HasEntity; -import org.ovirt.engine.ui.uicommonweb.models.storage.LunModel; import org.ovirt.engine.ui.uicommonweb.models.storage.SanStorageModelBase; import org.ovirt.engine.ui.uicommonweb.models.storage.SanStoragePartialModel; -import org.ovirt.engine.ui.uicommonweb.models.storage.StorageModel; -import org.ovirt.engine.ui.uicompat.Event; -import org.ovirt.engine.ui.uicompat.EventArgs; /** * Create a proxy model that will intercept {@link SanStorageModelBase#getItems()} and filter the items that belong to * the current page. From a logical point of view all pages are still one model i.e. user changes are not lost when * changing page and submitting. */ -public class PagingProxyModel implements SanStoragePartialModel { +public class PagingProxyModel extends ProxyModelBase { - private final SanStorageModelBase model; private final PageFilter pageFilter; public PagingProxyModel(SanStorageModelBase model, PageFilter pageFilter) { - this.model = model; + super(model); this.pageFilter = pageFilter; } @@ -31,58 +23,12 @@ public static SanStoragePartialModel create(PageFilter pageFilter, SanStorageMod return new PagingProxyModel(model, pageFilter); } - @Override - public void setMultiSelection(boolean multiSelection) { - model.setMultiSelection(multiSelection); - } - - @Override - public Event getItemsChangedEvent() { - return model.getItemsChangedEvent(); - } - @Override public Collection getItems() { - return pageFilter.filter(model.getItems()); - } - - @Override - public void setSelectedLunWarning(String warning) { - model.setSelectedLunWarning(warning); - } - - @Override - public void updateLunWarningForDiscardAfterDelete() { - model.updateLunWarningForDiscardAfterDelete(); - } - - @Override - public StorageModel getContainer() { - return model.getContainer(); - } - - @Override - public boolean isReduceDeviceSupported() { - return model.isReduceDeviceSupported(); - } - - @Override - public HasEntity getRequireTableRefresh() { - return model.getRequireTableRefresh(); + return pageFilter.filter(getModel().getItems()); } - @Override - public Set getMetadataDevices() { - return model.getMetadataDevices(); - } - - @Override - public int getNumOfLUNsToRemove() { - return model.getNumOfLUNsToRemove(); - } - - @Override - public List getIncludedLuns() { - return model.getIncludedLuns(); + protected PageFilter getPageFilter() { + return pageFilter; } } diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/ProxyModelBase.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/ProxyModelBase.java new file mode 100644 index 00000000000..4f12fbaaec4 --- /dev/null +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/ProxyModelBase.java @@ -0,0 +1,79 @@ +package org.ovirt.engine.ui.common.widget.uicommon.storage; + +import java.util.List; +import java.util.Set; + +import org.ovirt.engine.ui.uicommonweb.models.HasEntity; +import org.ovirt.engine.ui.uicommonweb.models.storage.LunModel; +import org.ovirt.engine.ui.uicommonweb.models.storage.SanStorageModelBase; +import org.ovirt.engine.ui.uicommonweb.models.storage.SanStoragePartialModel; +import org.ovirt.engine.ui.uicommonweb.models.storage.StorageModel; +import org.ovirt.engine.ui.uicompat.Event; +import org.ovirt.engine.ui.uicompat.EventArgs; + +/** + * Base class of a proxy model that will intercept {@link SanStorageModelBase#getItems()} and provide the ability + * to filter items. + */ +public abstract class ProxyModelBase implements SanStoragePartialModel { + + private final SanStorageModelBase model; + + public ProxyModelBase(SanStorageModelBase model) { + this.model = model; + } + + @Override + public void setMultiSelection(boolean multiSelection) { + model.setMultiSelection(multiSelection); + } + + @Override + public Event getItemsChangedEvent() { + return model.getItemsChangedEvent(); + } + + @Override + public void setSelectedLunWarning(String warning) { + model.setSelectedLunWarning(warning); + } + + @Override + public void updateLunWarningForDiscardAfterDelete() { + model.updateLunWarningForDiscardAfterDelete(); + } + + @Override + public StorageModel getContainer() { + return model.getContainer(); + } + + @Override + public boolean isReduceDeviceSupported() { + return model.isReduceDeviceSupported(); + } + + @Override + public HasEntity getRequireTableRefresh() { + return model.getRequireTableRefresh(); + } + + @Override + public Set getMetadataDevices() { + return model.getMetadataDevices(); + } + + @Override + public int getNumOfLUNsToRemove() { + return model.getNumOfLUNsToRemove(); + } + + @Override + public List getIncludedLuns() { + return model.getIncludedLuns(); + } + + protected SanStorageModelBase getModel() { + return model; + } +} diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/SanStorageTargetToLunList.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/SanStorageTargetToLunList.java index 754fe9bd874..825518a0713 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/SanStorageTargetToLunList.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/SanStorageTargetToLunList.java @@ -1,6 +1,7 @@ package org.ovirt.engine.ui.common.widget.uicommon.storage; import java.util.ArrayList; +import java.util.Collection; import java.util.Comparator; import java.util.List; @@ -45,6 +46,8 @@ public class SanStorageTargetToLunList extends AbstractSanStorageList leafLunFilter; + public SanStorageTargetToLunList(SanStoragePartialModel model) { super(model); } @@ -57,6 +60,12 @@ public SanStorageTargetToLunList(SanStoragePartialModel model, boolean hideLeaf, super(model, hideLeaf, multiSelection); } + public SanStorageTargetToLunList(SanStoragePartialModel model, boolean hideLeaf, boolean multiSelection, + ModelFilter leafLunFilter) { + super(model, hideLeaf, multiSelection); + this.leafLunFilter = leafLunFilter; + } + @Override protected void createSanStorageListWidget() { super.createSanStorageListWidget(); @@ -179,7 +188,7 @@ protected TreeItem createRootNode(SanTargetModel rootModel) { protected TreeItem createLeafNode(ListModel leafModel) { final TreeItem item = new TreeItem(); - List items = (List) leafModel.getItems(); + List items = (List) applyLeafFilter((List) leafModel.getItems()); if (hideLeaf || items.isEmpty()) { item.setUserObject(Boolean.TRUE); @@ -346,4 +355,11 @@ public LunModel getValue(LunModel object) { actionsColumn.makeSortable(); table.addColumn(actionsColumn, headerString, "95px"); //$NON-NLS-1$ } + + protected Collection applyLeafFilter(Collection items) { + if (leafLunFilter == null) { + return items; + } + return leafLunFilter.filter(items); + } } diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/SanTargetFilter.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/SanTargetFilter.java new file mode 100644 index 00000000000..5616b99019f --- /dev/null +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/SanTargetFilter.java @@ -0,0 +1,31 @@ +package org.ovirt.engine.ui.common.widget.uicommon.storage; + +import java.util.Collection; +import java.util.stream.Collectors; + +import org.ovirt.engine.ui.uicommonweb.models.storage.SanTargetModel; + +/** + * SanTarget Model filter by applying LUN filter. + */ +public class SanTargetFilter extends LunFilterBase implements ModelFilter { + + public SanTargetFilter(boolean isHideUsedLuns) { + super(isHideUsedLuns); + } + + public Collection filter(Collection items) { + if (items == null || !needFilter()) { + return items; + } + + return items.stream().filter(sanTargetModel -> { + if (getIsHideUsedLuns()) { + // Show targets that are not logged in or that contain unused LUNs + return !sanTargetModel.getIsLoggedIn() || + sanTargetModel.getLuns().stream().anyMatch(lunModel -> !lunModel.getIsUsed()); + } + return true; + }).collect(Collectors.toList()); + } +} diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/StoragePagingDataProvider.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/StoragePagingDataProvider.java index bb794dc5ef9..839e2b699b2 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/StoragePagingDataProvider.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/StoragePagingDataProvider.java @@ -44,6 +44,12 @@ public void refresh() { sanStorageLunToTargetList.updateItems(); } + @Override + public void reload() { + pageFilter.reload(sanStorageLunToTargetList.model.getItems()); + sanStorageLunToTargetList.updateItems(); + } + @Override public int getFirstItemOnPage() { return pageFilter.getFirstItemOnPage(); diff --git a/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/ui/common/CommonApplicationConstants.properties b/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/ui/common/CommonApplicationConstants.properties index 4fa3182412d..4a712b9c17d 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/ui/common/CommonApplicationConstants.properties +++ b/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/ui/common/CommonApplicationConstants.properties @@ -984,4 +984,6 @@ typeToSearchPlaceHolder=Type to search configChangesPending=Configuration changes may be pending. Unplug and replug to apply. permissionFilter=Permission Filters preferredVncOption=Preferred default VNC option -defaultClient=Set to Default \ No newline at end of file +defaultClient=Set to Default +hideUsedLunsForISCSILabel=Hide used LUNs and targets +hideUsedLunsForFCPLabel=Hide used LUNs diff --git a/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/ui/common/CommonApplicationConstants_ru.properties b/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/ui/common/CommonApplicationConstants_ru.properties index da407dca580..6f507f4dd96 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/ui/common/CommonApplicationConstants_ru.properties +++ b/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/ui/common/CommonApplicationConstants_ru.properties @@ -793,3 +793,5 @@ webBasedClientsUnsupported=noVNC \u043D\u0435\u043B\u044C\u0437\u044F \u0438\u04 windowsHostNameInfo=\u0418\u043C\u044F \u0443\u0437\u043B\u0430 \u0434\u043B\u044F Sysprep \u0434\u043E\u043B\u0436\u043D\u043E \u0441\u043E\u0434\u0435\u0440\u0436\u0430\u0442\u044C \u043D\u0435 \u0431\u043E\u043B\u0435\u0435 15 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432. \u0415\u0441\u043B\u0438 \u0432\u044B \u043D\u0435 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442\u0435 \u044D\u0442\u043E \u043F\u043E\u043B\u0435,\u0442\u043E \u043F\u0435\u0440\u0432\u044B\u0435 15 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432 \u0438\u043C\u0435\u043D\u0438 \u0412\u041C \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u044B \u043A\u0430\u043A \u0438\u043C\u044F \u0443\u0437\u043B\u0430. wipeAfterDeleteVmDiskPopup=\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u044C \u043F\u043E\u0441\u043B\u0435 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044F yes=\u0414\u0430 +hideUsedLunsForISCSILabel=\u0421\u043a\u0440\u044b\u0442\u044c\u0020\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435\u0020\u004c\u0055\u004e\u0027\u044b\u0020\u0438\u0020\u0446\u0435\u043b\u0438 +hideUsedLunsForFCPLabel=\u0421\u043a\u0440\u044b\u0442\u044c\u0020\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435\u0020\u004c\u0055\u004e\u0027\u044b diff --git a/frontend/webadmin/modules/gwt-common/src/test/java/org/ovirt/engine/ui/common/widget/uicommon/storage/PageFilterTest.java b/frontend/webadmin/modules/gwt-common/src/test/java/org/ovirt/engine/ui/common/widget/uicommon/storage/PageFilterTest.java index 2934f8cc2ef..ac415cb02ad 100644 --- a/frontend/webadmin/modules/gwt-common/src/test/java/org/ovirt/engine/ui/common/widget/uicommon/storage/PageFilterTest.java +++ b/frontend/webadmin/modules/gwt-common/src/test/java/org/ovirt/engine/ui/common/widget/uicommon/storage/PageFilterTest.java @@ -122,4 +122,26 @@ void resetDueToItemsListChange() { assertThat(pager.getTotalItemsCount()).isEqualTo(5); } + + @Test + void reload() { + PageFilter pager = PageFilter.create(2); + assertThat(pager.filter(fiveElem)).containsExactly(1, 2); + assertThat(pager.getTotalItemsCount()).isEqualTo(5); + + pager.goForward(); + assertThat(pager.filter(fiveElem)).containsExactly(3, 4); + assertThat(pager.getTotalItemsCount()).isEqualTo(5); + assertTrue(pager.canGoBack()); + + pager.reload(fourElem); + assertThat(pager.getTotalItemsCount()).isEqualTo(4); + assertFalse(pager.canGoBack()); + assertTrue(pager.canGoForward()); + + assertThat(pager.filter(fourElem)).containsExactly(1, 2); + assertThat(pager.getTotalItemsCount()).isEqualTo(4); + assertThat(pager.getFirstItemOnPage()).isEqualTo(0); + assertThat(pager.getLastItemOnPage()).isEqualTo(1); + } } diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/storage/LunModel.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/storage/LunModel.java index 1c8e60af567..77a828b90a7 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/storage/LunModel.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/storage/LunModel.java @@ -232,6 +232,19 @@ public void setStatus(LunStatus status) { this.status = status; } + private boolean isUsed; + + public boolean getIsUsed() { + return isUsed; + } + + public void setIsUsed(boolean value) { + if (isUsed != value) { + isUsed = value; + onPropertyChanged(new PropertyChangedEventArgs("isUsed")); //$NON-NLS-1$ + } + } + @Override public void setIsSelected(boolean value) { if (getIsGrayedOut()) { diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/storage/SanStorageModelBase.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/storage/SanStorageModelBase.java index 15e4dc631bd..1ae40830d19 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/storage/SanStorageModelBase.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/storage/SanStorageModelBase.java @@ -735,6 +735,9 @@ private void updateGrayedOut(boolean isInMaintenance, Set metadataDevice boolean nonEmpty = lun.getStorageDomainId() != null || lun.getDiskId() != null || lun.getStatus() == LunStatus.Unusable; + // Setting isUsed for LUN + lunModel.setIsUsed(nonEmpty); + // Graying out LUNs lunModel.setIsGrayedOut(isIgnoreGrayedOut() ? lun.getDiskId() != null : nonEmpty);