/* * RHQ Management Platform * Copyright (C) 2010 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.coregui.client.inventory.groups.detail.summary; import java.util.Map; import java.util.Set; import com.google.gwt.user.client.rpc.AsyncCallback; import com.smartgwt.client.util.BooleanCallback; import com.smartgwt.client.util.SC; import com.smartgwt.client.widgets.Canvas; import com.smartgwt.client.widgets.IButton; import com.smartgwt.client.widgets.events.ClickEvent; import com.smartgwt.client.widgets.events.ClickHandler; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.authz.Permission; import org.rhq.core.domain.common.EntityContext; import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.criteria.DashboardCriteria; import org.rhq.core.domain.dashboard.Dashboard; import org.rhq.core.domain.dashboard.DashboardCategory; import org.rhq.core.domain.dashboard.DashboardPortlet; import org.rhq.core.domain.resource.group.ResourceGroup; import org.rhq.core.domain.resource.group.composite.ResourceGroupComposite; import org.rhq.core.domain.util.PageList; import org.rhq.coregui.client.CoreGUI; import org.rhq.coregui.client.InitializableView; import org.rhq.coregui.client.PermissionsLoadedListener; import org.rhq.coregui.client.PermissionsLoader; import org.rhq.coregui.client.UserSessionManager; import org.rhq.coregui.client.dashboard.DashboardContainer; import org.rhq.coregui.client.dashboard.DashboardView; import org.rhq.coregui.client.dashboard.portlets.groups.GroupAlertsPortlet; import org.rhq.coregui.client.dashboard.portlets.groups.GroupConfigurationUpdatesPortlet; import org.rhq.coregui.client.dashboard.portlets.groups.GroupEventsPortlet; import org.rhq.coregui.client.dashboard.portlets.groups.GroupMetricsPortlet; import org.rhq.coregui.client.dashboard.portlets.groups.GroupOperationsPortlet; import org.rhq.coregui.client.gwt.DashboardGWTServiceAsync; import org.rhq.coregui.client.gwt.GWTServiceLookup; import org.rhq.coregui.client.util.enhanced.EnhancedIButton; import org.rhq.coregui.client.util.enhanced.EnhancedToolStrip; import org.rhq.coregui.client.util.enhanced.EnhancedVLayout; /** * The content pane for the group Summary>Activity subtab. * * @author Simeon Pinder * @author Jay Shaughnessy */ public class ActivityView extends EnhancedVLayout implements DashboardContainer, InitializableView { private static final String DASHBOARD_NAME_PREFIX = "GroupDashboard_"; private ResourceGroupComposite groupComposite; private boolean isAutoGroup; private boolean isAutoCluster; private DashboardGWTServiceAsync dashboardService = GWTServiceLookup.getDashboardService(); private DashboardView dashboardView; private EnhancedToolStrip footer; private IButton editButton; private IButton resetButton; // Capture the user's global permissions for use by any dashboard or portlet that may need it for rendering. private Set<Permission> globalPermissions; private boolean editMode = false; private boolean isInitialized = false; //default portlet positioning parameters private int colLeft = 0; private int colRight = 1; private int rowLeft = 0; private int rowRight = 0; private boolean displayLeft = false; public ActivityView(ResourceGroupComposite groupComposite, boolean isAutoCluster, boolean isAutoGroup) { super(); this.groupComposite = groupComposite; this.isAutoCluster = isAutoCluster; this.isAutoGroup = isAutoGroup; } @Override protected void onInit() { if (!isInitialized()) { super.onInit(); // first async call to get global permissions new PermissionsLoader().loadExplicitGlobalPermissions(new PermissionsLoadedListener() { public void onPermissionsLoaded(Set<Permission> permissions) { globalPermissions = permissions; // now make async call to look for customized dash for this user and entity DashboardCriteria criteria = new DashboardCriteria(); criteria.addFilterCategory(DashboardCategory.GROUP); criteria.addFilterGroupId(groupComposite.getResourceGroup().getId()); dashboardService.findDashboardsByCriteria(criteria, new AsyncCallback<PageList<Dashboard>>() { public void onFailure(Throwable caught) { CoreGUI.getErrorHandler().handleError(MSG.view_dashboardsManager_error1(), caught); } public void onSuccess(final PageList<Dashboard> result) { Dashboard dashboard = result.isEmpty() ? getDefaultDashboard() : result.get(0); setDashboard(dashboard); isInitialized = true; // draw() may be done since onInit finishes asynchronously, if so redraw if (isDrawn()) { markForRedraw(); } } }); } }); } } private void setDashboard(Dashboard dashboard) { Canvas[] members = getMembers(); removeMembers(members); //pass in the group information EntityContext context = EntityContext.forGroup(groupComposite.getResourceGroup().getId(), isAutoCluster, isAutoGroup); dashboardView = new DashboardView(this, dashboard, context, groupComposite); addMember(dashboardView); footer = new EnhancedToolStrip(); footer.setPadding(5); footer.setWidth100(); footer.setMembersMargin(15); editButton = new EnhancedIButton(editMode ? MSG.common_title_view_mode() : MSG.common_title_edit_mode()); editButton.addClickHandler(new ClickHandler() { public void onClick(ClickEvent clickEvent) { editMode = !editMode; editButton.setTitle(editMode ? MSG.common_title_view_mode() : MSG.common_title_edit_mode()); dashboardView.setEditMode(editMode); } }); resetButton = new EnhancedIButton(MSG.common_button_reset()); resetButton.addClickHandler(new ClickHandler() { public void onClick(ClickEvent clickEvent) { String message = MSG.view_summaryDashboard_resetConfirm(); SC.ask(message, new BooleanCallback() { public void execute(Boolean confirmed) { if (confirmed) { dashboardView.delete(); setDashboard(getDefaultDashboard()); markForRedraw(); } } }); } }); footer.addMember(editButton); footer.addMember(resetButton); addMember(footer); } protected Dashboard getDefaultDashboard() { Subject sessionSubject = UserSessionManager.getSessionSubject(); final ResourceGroup group = groupComposite.getResourceGroup(); final Dashboard dashboard = new Dashboard(); dashboard.setName(DASHBOARD_NAME_PREFIX + sessionSubject.getId() + "_" + group.getId()); dashboard.setCategory(DashboardCategory.GROUP); dashboard.setGroup(group); dashboard.setColumns(2); // set leftmost column and let the rest be equally divided dashboard.setColumnWidths("40%"); dashboard.getConfiguration().put(new PropertySimple(Dashboard.CFG_BACKGROUND, "transparent")); //figure out which portlets to display and how Map<String, String> groupKeyNameMap = DashboardView.processPortletNameMapForGroup(groupComposite); //reset positioning parameters colLeft = 0; colRight = 1; rowLeft = 0; rowRight = 0; //Left Column if (groupKeyNameMap.containsKey(GroupMetricsPortlet.KEY)) {//measurments top left if available DashboardPortlet measurements = new DashboardPortlet(GroupMetricsPortlet.NAME, GroupMetricsPortlet.KEY, 220); dashboard.addPortlet(measurements, colLeft, rowLeft++); groupKeyNameMap.remove(GroupMetricsPortlet.KEY); } // right Column(approx 60%. As larger more room to display table and N rows.) if (groupKeyNameMap.containsKey(GroupAlertsPortlet.KEY)) {//alerts top right if available DashboardPortlet alerts = new DashboardPortlet(GroupAlertsPortlet.NAME, GroupAlertsPortlet.KEY, 210); dashboard.addPortlet(alerts, colRight, rowRight++); groupKeyNameMap.remove(GroupAlertsPortlet.KEY); } if (groupKeyNameMap.containsKey(GroupEventsPortlet.KEY)) {//events if available DashboardPortlet events = new DashboardPortlet(GroupEventsPortlet.NAME, GroupEventsPortlet.KEY, 210); dashboard.addPortlet(events, colRight, rowRight++); groupKeyNameMap.remove(GroupEventsPortlet.KEY); } if (groupKeyNameMap.containsKey(GroupOperationsPortlet.KEY)) {//operations if available DashboardPortlet ops = new DashboardPortlet(GroupOperationsPortlet.NAME, GroupOperationsPortlet.KEY, 210); dashboard.addPortlet(ops, colRight, rowRight++); groupKeyNameMap.remove(GroupOperationsPortlet.KEY); } if (groupKeyNameMap.containsKey(GroupConfigurationUpdatesPortlet.KEY)) {//operations if available DashboardPortlet ops = new DashboardPortlet(GroupConfigurationUpdatesPortlet.NAME, GroupConfigurationUpdatesPortlet.KEY, 210); dashboard.addPortlet(ops, colRight, rowRight++); groupKeyNameMap.remove(GroupConfigurationUpdatesPortlet.KEY); } //Fill out left column(typically smaller portlets) then alternate cols with remaining displayLeft = false; updateDashboardWithPortlets(groupKeyNameMap, dashboard, 105); return dashboard; } /**Iterates list of new portlets and updates the dashboard reference with these new portlets. * Attempts to fill the spaces around the remaining larger portlets if already installed, then alternates * adding to left and right columns. Assumes dashboard has only two columns. * * @param keyNameMap portlet key|name map * @param dashboard dasboard instance to update */ private void updateDashboardWithPortlets(Map<String, String> keyNameMap, Dashboard dashboard, int initialHeight) { if ((keyNameMap != null) && (dashboard != null)) { for (String key : keyNameMap.keySet()) { //locate portlet and add to dashboard DashboardPortlet portlet = new DashboardPortlet(keyNameMap.get(key), key, initialHeight); if (rowLeft < 4) { dashboard.addPortlet(portlet, colLeft, rowLeft++); } else {//alternate if (!displayLeft) { dashboard.addPortlet(portlet, colRight, rowRight++); } else { dashboard.addPortlet(portlet, colLeft, rowLeft++); } //toggle displayLeft = !displayLeft; } } } } @Override public boolean isInitialized() { return isInitialized; } public Set<Permission> getGlobalPermissions() { return globalPermissions; } /** * name update not supported because the name is derived from the entity id. * @return */ public boolean supportsDashboardNameEdit() { return false; } public void updateDashboardNames() { return; } @Override public boolean isValidDashboardName(String name) { return ((name != null) && (dashboardView != null) && name.equals(dashboardView.getDashboard().getName())); } @Override public void refresh() { if (isInitialized()) { dashboardView.rebuild(); } } }