Kanagaraj M has uploaded a new change for review. Change subject: webadmin: importing newly added gluster hosts ......................................................................
webadmin: importing newly added gluster hosts An alert will be shown in the Cluster General tab when there new hosts which were added to the cluster through gluster cli(gluster peer probe) and they are not available in the ovirt engine. On clicking of the alert, a dialog will be shown with the new hosts along with their fingerprints. User will provide the passwords for them and save. Change-Id: I7afc2823d59c510d6e6aabd78e9be1d3c2ed082e Signed-off-by: Kanagaraj M <[email protected]> --- M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/clusters/ClusterGeneralModel.java M frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/Constants.java M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/ApplicationMessages.java M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/ClusterModule.java M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/tab/cluster/SubTabClusterGeneralPresenter.java M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/cluster/SubTabClusterGeneralView.java M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/cluster/SubTabClusterGeneralView.ui.xml 8 files changed, 469 insertions(+), 40 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/87/8187/1 diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java index be28ccb..a678de8 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java @@ -92,6 +92,7 @@ import org.ovirt.engine.core.common.queries.VdcQueryType; import org.ovirt.engine.core.common.queries.VdsGroupQueryParamenters; import org.ovirt.engine.core.common.queries.VdsIdParametersBase; +import org.ovirt.engine.core.common.queries.gluster.AddedGlusterServersParameters; import org.ovirt.engine.core.common.queries.gluster.GlusterParameters; import org.ovirt.engine.core.common.queries.gluster.GlusterServersQueryParameters; import org.ovirt.engine.core.compat.Guid; @@ -1079,6 +1080,19 @@ aQuery); } + public static void GetGlusterHostsNewlyAdded(AsyncQuery aQuery, Guid clusterId, boolean isFingerprintRequired) { + aQuery.converterCallback = new IAsyncConverter() { + @Override + public Object Convert(Object source, AsyncQuery _asyncQuery) + { + return source; + } + }; + Frontend.RunQuery(VdcQueryType.GetAddedGlusterServers, + new AddedGlusterServersParameters(clusterId, isFingerprintRequired), + aQuery); + } + public static void GetRpmVersionViaPublic(AsyncQuery aQuery) { aQuery.converterCallback = new IAsyncConverter() { @Override diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/clusters/ClusterGeneralModel.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/clusters/ClusterGeneralModel.java index c692664..146d722 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/clusters/ClusterGeneralModel.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/clusters/ClusterGeneralModel.java @@ -1,12 +1,18 @@ package org.ovirt.engine.ui.uicommonweb.models.clusters; import java.util.ArrayList; +import java.util.Map; +import org.ovirt.engine.core.common.action.AddVdsActionParameters; +import org.ovirt.engine.core.common.action.VdcActionParametersBase; import org.ovirt.engine.core.common.action.VdcActionType; +import org.ovirt.engine.core.common.action.VdcReturnValueBase; import org.ovirt.engine.core.common.action.VdsGroupOperationParameters; +import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.VDSGroup; import org.ovirt.engine.core.common.businessentities.gluster.GlusterStatus; import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeEntity; +import org.ovirt.engine.core.compat.PropertyChangedEventArgs; import org.ovirt.engine.core.compat.StringHelper; import org.ovirt.engine.ui.frontend.AsyncQuery; import org.ovirt.engine.ui.frontend.Frontend; @@ -15,7 +21,11 @@ import org.ovirt.engine.ui.uicommonweb.UICommand; import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider; import org.ovirt.engine.ui.uicommonweb.models.EntityModel; +import org.ovirt.engine.ui.uicommonweb.models.hosts.HostDetailModel; +import org.ovirt.engine.ui.uicommonweb.models.hosts.MultipleHostsModel; import org.ovirt.engine.ui.uicompat.ConstantsManager; +import org.ovirt.engine.ui.uicompat.FrontendMultipleActionAsyncResult; +import org.ovirt.engine.ui.uicompat.IFrontendMultipleActionAsyncCallback; public class ClusterGeneralModel extends EntityModel { @@ -63,6 +73,50 @@ privateEditPolicyCommand = value; } + private boolean hasAnyAlert; + + public boolean getHasAnyAlert() + { + return hasAnyAlert; + } + + public void setHasAnyAlert(boolean value) + { + if (hasAnyAlert != value) + { + hasAnyAlert = value; + OnPropertyChanged(new PropertyChangedEventArgs("HasAnyAlert")); //$NON-NLS-1$ + } + } + + private boolean hasGlusterHostsAlert; + + public boolean getHasNewGlusterHostsAlert() + { + return hasGlusterHostsAlert; + } + + public void setHasNewGlusterHostsAlert(boolean value) + { + if (hasGlusterHostsAlert != value) + { + hasGlusterHostsAlert = value; + OnPropertyChanged(new PropertyChangedEventArgs("HasNewGlusterHostsAlert")); //$NON-NLS-1$ + } + } + + private UICommand importNewGlusterHostsCommand; + + public UICommand getImportNewGlusterHostsCommand() + { + return importNewGlusterHostsCommand; + } + + private void setImportNewGlusterHostsCommand(UICommand value) + { + importNewGlusterHostsCommand = value; + } + @Override public VDSGroup getEntity() { @@ -84,6 +138,7 @@ setNoOfVolumesDown(0); setEditPolicyCommand(new UICommand("EditPolicy", this)); //$NON-NLS-1$ + setImportNewGlusterHostsCommand(new UICommand("ImportGlusterHosts", this)); //$NON-NLS-1$ AsyncQuery _asyncQuery = new AsyncQuery(); _asyncQuery.setModel(this); @@ -135,6 +190,7 @@ if (getEntity() != null) { UpdateVolumeDetails(); + updateAlerts(); } UpdateActionAvailability(); @@ -202,6 +258,121 @@ Cancel(); } + public void fetchAndImportNewGlusterHosts() { + if (getWindow() != null) + { + return; + } + + final MultipleHostsModel hostsModel = new MultipleHostsModel(); + setWindow(hostsModel); + hostsModel.setTitle(ConstantsManager.getInstance().getConstants().addMultipleHostsTitle()); + hostsModel.setHashName("add_hosts"); //$NON-NLS-1$ + + UICommand command = new UICommand("OnSaveHosts", this); //$NON-NLS-1$ + command.setTitle(ConstantsManager.getInstance().getConstants().ok()); + hostsModel.getCommands().add(command); + hostsModel.getHosts().setItems(new ArrayList<EntityModel>()); + + command = new UICommand("Cancel", this); //$NON-NLS-1$ + command.setTitle(ConstantsManager.getInstance().getConstants().cancel()); + command.setIsCancel(true); + hostsModel.getCommands().add(command); + + hostsModel.StartProgress(null); + + AsyncQuery _asyncQuery = new AsyncQuery(); + _asyncQuery.setModel(this); + _asyncQuery.asyncCallback = new INewAsyncCallback() { + @Override + public void OnSuccess(Object model, Object result) + { + Map<String, String> hostMap = (Map<String, String>) result; + + if (hostMap == null || hostMap.isEmpty()) + { + hostsModel.setMessage(ConstantsManager.getInstance().getConstants().emptyNewGlusterHosts()); + } + else + { + ArrayList<EntityModel> list = new ArrayList<EntityModel>(); + for (Map.Entry<String, String> host : hostMap.entrySet()) + { + HostDetailModel hostModel = new HostDetailModel(host.getKey(), host.getValue()); + hostModel.setName(host.getKey()); + hostModel.setPassword("");//$NON-NLS-1$ + EntityModel entityModel = new EntityModel(hostModel); + list.add(entityModel); + } + hostsModel.getHosts().setItems(list); + } + hostsModel.StopProgress(); + } + }; + AsyncDataProvider.GetGlusterHostsNewlyAdded(_asyncQuery, getEntity().getId(), true); + + } + + public void onSaveHosts() { + final MultipleHostsModel hostsModel = (MultipleHostsModel) getWindow(); + if (hostsModel == null) + { + return; + } + if (!hostsModel.validate()) + { + return; + } + + hostsModel.StartProgress(null); + ArrayList<VdcActionParametersBase> parametersList = new ArrayList<VdcActionParametersBase>(); + for (Object object : hostsModel.getHosts().getItems()) { + HostDetailModel hostDetailModel = (HostDetailModel) ((EntityModel) object).getEntity(); + + VDS host = new VDS(); + host.setvds_name(hostDetailModel.getName()); + host.sethost_name(hostDetailModel.getAddress()); + host.setSSHKeyFingerprint(hostDetailModel.getFingerprint()); + host.setport(54321); + + host.setvds_group_id(getEntity().getId()); + host.setpm_enabled(false); + + AddVdsActionParameters parameters = new AddVdsActionParameters(); + parameters.setVdsId(host.getId()); + parameters.setvds(host); + parameters.setRootPassword(hostDetailModel.getPassword()); + parameters.setOverrideFirewall(false); + + parametersList.add(parameters); + } + + Frontend.RunMultipleAction(VdcActionType.AddVds, + parametersList, + true, + new IFrontendMultipleActionAsyncCallback() { + + @Override + public void Executed(FrontendMultipleActionAsyncResult result) { + hostsModel.StopProgress(); + boolean isAllCanDoPassed = true; + for (VdcReturnValueBase returnValueBase : result.getReturnValue()) + { + isAllCanDoPassed = isAllCanDoPassed && returnValueBase.getCanDoAction(); + if (!isAllCanDoPassed) + { + break; + } + } + if (isAllCanDoPassed) + { + updateAlerts(); + Cancel(); + } + } + }, null); + } + public void Cancel() { setWindow(null); @@ -243,6 +414,39 @@ AsyncDataProvider.GetVolumeList(_asyncQuery, getEntity().getname()); } + private void updateAlerts() + { + if (getEntity().supportsGlusterService()) + { + AsyncQuery _asyncQuery = new AsyncQuery(); + _asyncQuery.setModel(this); + _asyncQuery.asyncCallback = new INewAsyncCallback() { + @Override + public void OnSuccess(Object model, Object result) + { + ClusterGeneralModel innerGeneralModel = (ClusterGeneralModel) model; + Map<String, String> serverMap = (Map<String, String>) result; + if (!serverMap.isEmpty()) + { + innerGeneralModel.setHasNewGlusterHostsAlert(true); + innerGeneralModel.setHasAnyAlert(true); + } + else + { + setHasNewGlusterHostsAlert(false); + setHasAnyAlert(false); + } + } + }; + AsyncDataProvider.GetGlusterHostsNewlyAdded(_asyncQuery, getEntity().getId(), false); + } + else + { + setHasNewGlusterHostsAlert(false); + setHasAnyAlert(false); + } + } + @Override public void ExecuteCommand(UICommand command) { @@ -256,6 +460,14 @@ { OnSavePolicy(); } + if (command == getImportNewGlusterHostsCommand()) + { + fetchAndImportNewGlusterHosts(); + } + else if (StringHelper.stringsEqual(command.getName(), "OnSaveHosts")) //$NON-NLS-1$ + { + onSaveHosts(); + } else if (StringHelper.stringsEqual(command.getName(), "Cancel")) //$NON-NLS-1$ { Cancel(); diff --git a/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/Constants.java b/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/Constants.java index b78d4c6..6896c64 100644 --- a/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/Constants.java +++ b/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/Constants.java @@ -1542,4 +1542,7 @@ @DefaultStringValue("Unable to fetch the gluster hosts. Please verify the host IP Address and password") String emptyGlusterHosts(); + + @DefaultStringValue("There are no new hosts in the cluster to import") + String emptyNewGlusterHosts(); } diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/ApplicationMessages.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/ApplicationMessages.java index 910dc2e..2e9675e 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/ApplicationMessages.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/ApplicationMessages.java @@ -59,4 +59,7 @@ @DefaultMessage("{0} (VLAN {1})") String vlanNetwork(String name, String vlanId); + + @DefaultMessage("Some new hosts are added to the cluster. <a>Click here</a> to import them.") + String clusterHasNewGlusterHosts(); } diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/ClusterModule.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/ClusterModule.java index 7af4d72..666a4c6 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/ClusterModule.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/ClusterModule.java @@ -92,8 +92,9 @@ @Provides @Singleton - public DetailModelProvider<ClusterListModel, ClusterGeneralModel> getClusterPolicyProvider(ClientGinjector ginjector, - final Provider<ClusterPolicyPopupPresenterWidget> popupProvider) { + public DetailModelProvider<ClusterListModel, ClusterGeneralModel> getClusterGeneralProvider(ClientGinjector ginjector, + final Provider<ClusterPolicyPopupPresenterWidget> policyPopupProvider, + final Provider<MultipleHostsPopupPresenterWidget> multipleHostsProvider) { return new DetailTabModelProvider<ClusterListModel, ClusterGeneralModel>(ginjector, ClusterListModel.class, ClusterGeneralModel.class) { @@ -101,8 +102,11 @@ public AbstractModelBoundPopupPresenterWidget<? extends Model, ?> getModelPopup(ClusterGeneralModel source, UICommand lastExecutedCommand, Model windowModel) { if (lastExecutedCommand == getModel().getEditPolicyCommand()) { - return popupProvider.get(); - } else { + return policyPopupProvider.get(); + } else if (lastExecutedCommand == getModel().getImportNewGlusterHostsCommand()) { + return multipleHostsProvider.get(); + } + else { return super.getModelPopup(source, lastExecutedCommand, windowModel); } } diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/tab/cluster/SubTabClusterGeneralPresenter.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/tab/cluster/SubTabClusterGeneralPresenter.java index 130db41..df93501 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/tab/cluster/SubTabClusterGeneralPresenter.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/tab/cluster/SubTabClusterGeneralPresenter.java @@ -1,16 +1,30 @@ package org.ovirt.engine.ui.webadmin.section.main.presenter.tab.cluster; import org.ovirt.engine.core.common.businessentities.VDSGroup; +import org.ovirt.engine.core.compat.Event; +import org.ovirt.engine.core.compat.EventArgs; +import org.ovirt.engine.core.compat.IEventListener; +import org.ovirt.engine.core.compat.PropertyChangedEventArgs; import org.ovirt.engine.ui.common.presenter.AbstractSubTabPresenter; import org.ovirt.engine.ui.common.uicommon.model.DetailModelProvider; +import org.ovirt.engine.ui.common.uicommon.model.UiCommonInitEvent; import org.ovirt.engine.ui.common.widget.tab.ModelBoundTabData; +import org.ovirt.engine.ui.uicommonweb.UICommand; import org.ovirt.engine.ui.uicommonweb.models.clusters.ClusterGeneralModel; import org.ovirt.engine.ui.uicommonweb.models.clusters.ClusterListModel; +import org.ovirt.engine.ui.webadmin.ApplicationMessages; import org.ovirt.engine.ui.webadmin.gin.ClientGinjector; +import org.ovirt.engine.ui.webadmin.gin.ClientGinjectorProvider; import org.ovirt.engine.ui.webadmin.place.ApplicationPlaces; import org.ovirt.engine.ui.webadmin.section.main.presenter.tab.ClusterSelectionChangeEvent; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.shared.EventBus; +import com.google.gwt.user.client.ui.Anchor; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.Widget; import com.google.inject.Inject; import com.gwtplatform.mvp.client.TabData; import com.gwtplatform.mvp.client.annotations.NameToken; @@ -30,7 +44,22 @@ } public interface ViewDef extends AbstractSubTabPresenter.ViewDef<VDSGroup> { + /** + * Clear all the alerts currently displayed in the alerts panel of the cluster. + */ + void clearAlerts(); + + /** + * Displays a new alert in the alerts panel of the host. + * + * @param widget + * the widget used to display the alert, usually just a text label, but can also be a text label with + * a link to an action embedded + */ + void addAlert(Widget widget); } + + private final ApplicationMessages messages; @TabInfo(container = ClusterSubTabPanelPresenter.class) static TabData getTabData(ClientGinjector ginjector) { @@ -42,6 +71,105 @@ public SubTabClusterGeneralPresenter(EventBus eventBus, ViewDef view, ProxyDef proxy, PlaceManager placeManager, DetailModelProvider<ClusterListModel, ClusterGeneralModel> modelProvider) { super(eventBus, view, proxy, placeManager, modelProvider); + // Inject a reference to the messages: + messages = ClientGinjectorProvider.instance().getApplicationMessages(); + } + + @Override + public void onUiCommonInit(UiCommonInitEvent event) { + super.onUiCommonInit(event); + + // Initialize the list of alerts: + final ClusterGeneralModel model = getModelProvider().getModel(); + updateAlerts(getView(), model); + + // Listen for changes in the properties of the model in order + // to update the alerts panel: + model.getPropertyChangedEvent().addListener(new IEventListener() { + @Override + public void eventRaised(Event ev, Object sender, EventArgs args) { + if (args instanceof PropertyChangedEventArgs) { + PropertyChangedEventArgs changedArgs = (PropertyChangedEventArgs) args; + if (changedArgs.PropertyName.contains("Alert")) { //$NON-NLS-1$ + updateAlerts(getView(), model); + } + } + } + }); + } + + /** + * Review the model and if there are alerts add them to the view. + * + * @param view + * the view where alerts should be added + * @param model + * the model to review + */ + private void updateAlerts(final ViewDef view, final ClusterGeneralModel model) { + // Clear all the alerts: + view.clearAlerts(); + + // Review the alerts and add those that are active: + if (model.getHasNewGlusterHostsAlert()) { + addTextAndLinkAlert(view, messages.clusterHasNewGlusterHosts(), model.getImportNewGlusterHostsCommand()); + } + } + + /** + * Create a widget containing text and a link that triggers the execution of a command. + * + * @param view + * the view where the alert should be added + * @param text + * the text content of the alert + * @param command + * the command that should be executed when the link is clicked + */ + private void addTextAndLinkAlert(final ViewDef view, final String text, final UICommand command) { + // Find the open and close positions of the link within the message: + final int openIndex = text.indexOf("<a>"); //$NON-NLS-1$ + final int closeIndex = text.indexOf("</a>"); //$NON-NLS-1$ + if (openIndex == -1 || closeIndex == -1 || closeIndex < openIndex) { + return; + } + + // Extract the text before, inside and after the tags: + final String beforeText = text.substring(0, openIndex); + final String betweenText = text.substring(openIndex + 3, closeIndex); + final String afterText = text.substring(closeIndex + 4); + + // Create a flow panel containing the text and the link: + final FlowPanel alertPanel = new FlowPanel(); + + // Create the label for the text before the tag: + final Label beforeLabel = new Label(beforeText); + beforeLabel.getElement().getStyle().setProperty("display", "inline"); //$NON-NLS-1$ //$NON-NLS-2$ + alertPanel.add(beforeLabel); + + // Create the anchor: + final Anchor betweenAnchor = new Anchor(betweenText); + betweenAnchor.getElement().getStyle().setProperty("display", "inline"); //$NON-NLS-1$ //$NON-NLS-2$ + alertPanel.add(betweenAnchor); + + // Add a listener to the anchor so that the command is executed when + // it is clicked: + betweenAnchor.addClickHandler( + new ClickHandler() { + @Override + public void onClick(ClickEvent event) { + command.Execute(); + } + } + ); + + // Create the label for the text after the tag: + final Label afterLabel = new Label(afterText); + afterLabel.getElement().getStyle().setProperty("display", "inline"); //$NON-NLS-1$ //$NON-NLS-2$ + alertPanel.add(afterLabel); + + // Add the alert to the view: + view.addAlert(alertPanel); } @Override diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/cluster/SubTabClusterGeneralView.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/cluster/SubTabClusterGeneralView.java index 42844a9..9de1acf 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/cluster/SubTabClusterGeneralView.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/cluster/SubTabClusterGeneralView.java @@ -18,6 +18,7 @@ import org.ovirt.engine.ui.uicommonweb.models.clusters.ClusterGeneralModel; import org.ovirt.engine.ui.uicommonweb.models.clusters.ClusterListModel; import org.ovirt.engine.ui.webadmin.ApplicationConstants; +import org.ovirt.engine.ui.webadmin.ApplicationResources; import org.ovirt.engine.ui.webadmin.section.main.presenter.tab.cluster.SubTabClusterGeneralPresenter; import com.google.gwt.core.client.GWT; @@ -28,7 +29,10 @@ import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.AbsolutePanel; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.VerticalPanel; @@ -47,6 +51,9 @@ interface ViewUiBinder extends UiBinder<Widget, SubTabClusterGeneralView> { ViewUiBinder uiBinder = GWT.create(ViewUiBinder.class); } + + // to find the icon for alert messages: + private final ApplicationResources resources; @UiField HorizontalPanel policyPanel; @@ -104,13 +111,24 @@ TextBoxLabel noOfVolumesUp = new TextBoxLabel(); TextBoxLabel noOfVolumesDown = new TextBoxLabel(); + @UiField + HTMLPanel alertsPanel; + + // This is the list of action items inside the panel, so that we + // can clear and add elements inside without affecting the panel: + @UiField + FlowPanel alertsList; + private final ApplicationConstants constants; @Inject public SubTabClusterGeneralView(final DetailModelProvider<ClusterListModel, ClusterGeneralModel> modelProvider, - ApplicationConstants constants) { + ApplicationResources resources, ApplicationConstants constants) { super(modelProvider); this.constants = constants; + + // Inject a reference to the resources: + this.resources = resources; initSliders(); initLabels(); @@ -218,4 +236,30 @@ volumeSummaryPanel.setVisible(selectedItem.supportsGlusterService()); } + @Override + public void clearAlerts() { + // Remove all the alert widgets and make the panel invisible: + alertsList.clear(); + alertsPanel.setVisible(false); + } + + @Override + public void addAlert(Widget alertWidget) { + // Create a composite panel that contains the alert icon and the widget provided + // by the caller, both rendered horizontally: + FlowPanel alertPanel = new FlowPanel(); + Image alertIcon = new Image(resources.alertImage()); + alertIcon.getElement().getStyle().setProperty("display", "inline"); //$NON-NLS-1$ //$NON-NLS-2$ + alertWidget.getElement().getStyle().setProperty("display", "inline"); //$NON-NLS-1$ //$NON-NLS-2$ + alertPanel.add(alertIcon); + alertPanel.add(alertWidget); + + // Add the composite panel to the alerts panel: + alertsList.add(alertPanel); + + // Make the panel visible if it wasn't: + if (!alertsPanel.isVisible()) { + alertsPanel.setVisible(true); + } + } } diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/cluster/SubTabClusterGeneralView.ui.xml b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/cluster/SubTabClusterGeneralView.ui.xml index 69fc179..6fb4439 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/cluster/SubTabClusterGeneralView.ui.xml +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/cluster/SubTabClusterGeneralView.ui.xml @@ -3,6 +3,9 @@ <ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:f="urn:import:org.ovirt.engine.ui.common.widget.form" xmlns:w="urn:import:org.ovirt.engine.ui.common.widget"> + + <ui:with field='constants' type='org.ovirt.engine.ui.webadmin.ApplicationConstants' /> + <ui:style> .button { width: 100px; @@ -53,43 +56,61 @@ font-weight: bold; padding-left: 5px; } + @external alertsPanel; + .alertsPanel { + padding-top: 5px; + padding-right: 16px; + padding-left: 16px; + } + .alertsPanel a { + color: black; + text-decoration: underline; + } </ui:style> - <g:HorizontalPanel spacing="5"> - <g:HorizontalPanel ui:field="policyPanel" addStyleNames="{style.marginLeft}"> - <g:FlowPanel width="400px"> - <w:UiCommandButton ui:field="editPolicyButton" addStyleNames="{style.button}" /> - <g:HorizontalPanel> - <g:Label ui:field="policyLabel" addStyleNames="{style.rightMarginStyle}"/> - <g:Label ui:field="policyFieldLabel"/> - </g:HorizontalPanel> - <g:AbsolutePanel ui:field="sliderPanel" addStyleNames="{style.topMarginPanel}"> - <g:HorizontalPanel addStyleNames="{style.absolutePanel}"> - <g:SimplePanel ui:field="leftDummySlider" addStyleNames="{style.geryPanel}"/> - <f:Slider ui:field="leftSlider"/> - <g:SimplePanel addStyleNames="{style.gerySplitPanel}"/> - <f:Slider ui:field="rightSlider"/> + <g:FlowPanel> + <g:HorizontalPanel spacing="5"> + <g:HorizontalPanel ui:field="policyPanel" addStyleNames="{style.marginLeft}"> + <g:FlowPanel width="400px"> + <w:UiCommandButton ui:field="editPolicyButton" addStyleNames="{style.button}" /> + <g:HorizontalPanel> + <g:Label ui:field="policyLabel" addStyleNames="{style.rightMarginStyle}"/> + <g:Label ui:field="policyFieldLabel"/> </g:HorizontalPanel> - <g:SimplePanel addStyleNames="{style.transparent}"/> - </g:AbsolutePanel> - <g:Label ui:field="policyTimeLabel"/> - </g:FlowPanel> - <g:FlowPanel addStyleNames="{style.minMaxPanel}"> - <g:HorizontalPanel > - <g:SimplePanel addStyleNames="{style.maxLabel}"/> - <g:Label ui:field="maxServiceLevelLabel"/> - </g:HorizontalPanel> - <g:HorizontalPanel> - <g:SimplePanel addStyleNames="{style.minLabel}"/> - <g:Label ui:field="minServiceLevelLabel"/> - </g:HorizontalPanel> - </g:FlowPanel> - </g:HorizontalPanel> + <g:AbsolutePanel ui:field="sliderPanel" addStyleNames="{style.topMarginPanel}"> + <g:HorizontalPanel addStyleNames="{style.absolutePanel}"> + <g:SimplePanel ui:field="leftDummySlider" addStyleNames="{style.geryPanel}"/> + <f:Slider ui:field="leftSlider"/> + <g:SimplePanel addStyleNames="{style.gerySplitPanel}"/> + <f:Slider ui:field="rightSlider"/> + </g:HorizontalPanel> + <g:SimplePanel addStyleNames="{style.transparent}"/> + </g:AbsolutePanel> + <g:Label ui:field="policyTimeLabel"/> + </g:FlowPanel> + <g:FlowPanel addStyleNames="{style.minMaxPanel}"> + <g:HorizontalPanel > + <g:SimplePanel addStyleNames="{style.maxLabel}"/> + <g:Label ui:field="maxServiceLevelLabel"/> + </g:HorizontalPanel> + <g:HorizontalPanel> + <g:SimplePanel addStyleNames="{style.minLabel}"/> + <g:Label ui:field="minServiceLevelLabel"/> + </g:HorizontalPanel> + </g:FlowPanel> + </g:HorizontalPanel> - <g:VerticalPanel ui:field="volumeSummaryPanel"> - <g:Label ui:field="volumeHeaderLabel" addStyleNames="{style.headerLabel}"/> - <f:GeneralFormPanel ui:field="volumeFormPanel"> - </f:GeneralFormPanel> - </g:VerticalPanel> - </g:HorizontalPanel> + <g:VerticalPanel ui:field="volumeSummaryPanel"> + <g:Label ui:field="volumeHeaderLabel" addStyleNames="{style.headerLabel}"/> + <f:GeneralFormPanel ui:field="volumeFormPanel"> + </f:GeneralFormPanel> + </g:VerticalPanel> + </g:HorizontalPanel> + <g:HTMLPanel ui:field="alertsPanel" addStyleNames="{style.alertsPanel}"> + <div> + <b><g:Label text="{constants.actionItemsHostGeneral}"></g:Label></b> + </div> + <g:FlowPanel ui:field="alertsList"/> + </g:HTMLPanel> + </g:FlowPanel> </ui:UiBinder> \ No newline at end of file -- To view, visit http://gerrit.ovirt.org/8187 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I7afc2823d59c510d6e6aabd78e9be1d3c2ed082e Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Kanagaraj M <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
