modules/core/domain/src/main/java/org/rhq/core/domain/tagging/compsite/TagReportComposite.java | 7 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/LinkManager.java | 6 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/report/tag/TagCloudView.java | 125 ++++++++-- modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/report/tag/TaggedView.java | 58 +++- modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties | 5 5 files changed, 169 insertions(+), 32 deletions(-)
New commits: commit 8337b34c8a757821de0c22f4c30f9f32b55265f2 Author: John Mazzitelli mazz@redhat.com Date: Wed Mar 30 00:57:02 2011 -0400
BZ 691978 - fix tag cloud view - you can now delete tags. prettied up the UI as well
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/tagging/compsite/TagReportComposite.java b/modules/core/domain/src/main/java/org/rhq/core/domain/tagging/compsite/TagReportComposite.java index 57084e2..d5bcceb 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/tagging/compsite/TagReportComposite.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/tagging/compsite/TagReportComposite.java @@ -31,7 +31,6 @@ public class TagReportComposite extends Tag {
private static final long serialVersionUID = 1L;
- private Tag tag; private long total; private long resourceCount; private long resourceGroupCount; @@ -46,8 +45,8 @@ public class TagReportComposite extends Tag { public TagReportComposite(int id, String namespace, String semantic, String name, long total, long resourceCount, long resourceGroupCount, long bundleCount, long bundleVersionCount, long bundleDeploymentCount, long bundleDestinationCount) { - this.tag = new Tag(namespace, semantic, name); - this.tag.setId(id); + super(namespace, semantic, name); + setId(id); this.total = total; this.resourceCount = resourceCount; this.resourceGroupCount = resourceGroupCount; @@ -58,7 +57,7 @@ public class TagReportComposite extends Tag { }
public Tag getTag() { - return tag; + return this; }
public long getTotal() { diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/LinkManager.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/LinkManager.java index 61bfede..2a6beeb 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/LinkManager.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/LinkManager.java @@ -383,7 +383,11 @@ public class LinkManager { }
public static String getTagLink(String tag) { - return "#Reports/Subsystems/Tags/" + tag; + if (tag == null) { + return "#Reports/Subsystems/Tags"; + } else { + return "#Reports/Subsystems/Tags/" + tag; + } }
public static String getBundleLink(int bundleId) { diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/report/tag/TagCloudView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/report/tag/TagCloudView.java index 61164f3..b2ce6bc 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/report/tag/TagCloudView.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/report/tag/TagCloudView.java @@ -24,26 +24,42 @@ package org.rhq.enterprise.gui.coregui.client.report.tag;
import java.util.Collections; import java.util.Comparator; +import java.util.HashSet;
import com.google.gwt.user.client.rpc.AsyncCallback; import com.smartgwt.client.widgets.HTMLFlow; +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.criteria.TagCriteria; +import org.rhq.core.domain.tagging.Tag; import org.rhq.core.domain.tagging.compsite.TagReportComposite; +import org.rhq.core.domain.util.PageControl; import org.rhq.core.domain.util.PageList; import org.rhq.enterprise.gui.coregui.client.CoreGUI; import org.rhq.enterprise.gui.coregui.client.LinkManager; import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup; +import org.rhq.enterprise.gui.coregui.client.util.message.Message; +import org.rhq.enterprise.gui.coregui.client.util.message.Message.Severity; +import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableIButton; import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
/** + * Shows the tags in a large HTML block, where the most used tags are shown in bigger fonts. + * * @author Greg Hinkle + * @author John Mazzitelli */ public class TagCloudView extends LocatableVLayout {
- private PageList<TagReportComposite> tags; + private static final String REMOVE_ICON = "[skin]/images/actions/remove.png"; + private static final int MIN_FONTSIZE = 8; + private static final int MAX_FONTSIZE = 22;
+ private PageList<TagReportComposite> tags; private String selectedTag; + private IButton deleteButton;
public TagCloudView(String locatorId) { super(locatorId); @@ -52,10 +68,16 @@ public class TagCloudView extends LocatableVLayout { @Override protected void onDraw() { super.onDraw(); + refresh(); + }
+ private void refresh() { removeMembers(getMembers());
- GWTServiceLookup.getTagService().findTagReportCompositesByCriteria(new TagCriteria(), + TagCriteria tagCriteria = new TagCriteria(); + tagCriteria.setPageControl(PageControl.getUnlimitedInstance()); + + GWTServiceLookup.getTagService().findTagReportCompositesByCriteria(tagCriteria, new AsyncCallback<PageList<TagReportComposite>>() { public void onFailure(Throwable caught) { CoreGUI.getErrorHandler().handleError(MSG.view_tagCloud_error_fetchFailure(), caught); @@ -68,36 +90,34 @@ public class TagCloudView extends LocatableVLayout { }
private void drawTags(PageList<TagReportComposite> tags) { - if (tags == null) { - return; // Tags still loading + return; // tags are still loading }
this.tags = tags;
+ // determine the maximum number of times any single tag is used long max = 0; - long total = 0; for (TagReportComposite tag : tags) { if (tag.getTotal() > max) { max = tag.getTotal(); } - total += tag.getTotal(); }
+ // sort the tags so they appear alphabetically Collections.sort(tags, new Comparator<TagReportComposite>() { public int compare(TagReportComposite o1, TagReportComposite o2) { return o1.getTag().toString().compareTo(o2.getTag().toString()); } });
+ // build the HTML block that contains all the tags with variable font sizes + // where the font size represents the relative number of times the tag is used StringBuilder buf = new StringBuilder(); - - int minFont = 8; - int maxFont = 22; - for (TagReportComposite tag : tags) {
- int font = (int) ((((double) tag.getTotal()) / (double) max) * (maxFont - minFont)) + minFont; + int font = (int) ((((double) tag.getTotal()) / (double) max) * (MAX_FONTSIZE - MIN_FONTSIZE)) + + MIN_FONTSIZE;
buf.append("<a href="").append(LinkManager.getTagLink(tag.getTag().toString())).append( "" style="font-size: ").append(font).append("pt; margin: 8px;""); @@ -111,16 +131,93 @@ public class TagCloudView extends LocatableVLayout {
buf.append(">").append(tag.getTag()).append("</a> "); } - HTMLFlow flow = new HTMLFlow(buf.toString()); - addMember(flow); }
+ public String getSelectedTag() { + return this.selectedTag; + } + + /** + * Determines which, if any, tag is currently selected. + * + * @param selectedTag the full tag name, or <code>null</code> if nothing is selected + */ public void setSelectedTag(String selectedTag) { this.selectedTag = selectedTag; + TagReportComposite selected = getSelectedTagReportComposite(); + getDeleteButton().setDisabled(selected == null || selected.getTotal() > 0); // don't be able to delete non-existent tag or tag that is used removeMembers(getMembers()); - drawTags(tags); + drawTags(this.tags); }
+ /** + * This view can provide a delete button that, when clicked, will delete the currently + * selected tag. This view doesn't put this delete button anywhere, the caller can place + * this button where ever it deems appropriate. + * + * @return a delete button component that can be placed as a member of a canvas + */ + public IButton getDeleteButton() { + if (this.deleteButton == null) { + final IButton button = new DeleteButton(extendLocatorId("deleteButton")); + button.setIcon(REMOVE_ICON); + button.setIconWidth(16); + button.setIconHeight(16); + button.setTitle(MSG.view_tagCloud_deleteTag()); + button.setAutoFit(true); + button.addClickHandler(new ClickHandler() { + @Override + public void onClick(ClickEvent event) { + final TagReportComposite selected = getSelectedTagReportComposite(); + if (selected != null) { + HashSet<Tag> doomedTag = new HashSet<Tag>(1); + doomedTag.add(selected.getTag()); + GWTServiceLookup.getTagService().removeTags(doomedTag, new AsyncCallback<Void>() { + @Override + public void onSuccess(Void result) { + tags.remove(selected); + CoreGUI.goToView(LinkManager.getTagLink(null)); + CoreGUI.getMessageCenter().notify( + new Message(MSG.view_tagCloud_deleteTagSuccess(selected.getTag().toString()), + Severity.Info)); + } + + @Override + public void onFailure(Throwable caught) { + CoreGUI.getErrorHandler().handleError( + MSG.view_tagCloud_deleteTagFailure(selected.getTag().toString()), caught); + } + }); + } + } + }); + this.deleteButton = button; + } + return this.deleteButton; + } + + private TagReportComposite getSelectedTagReportComposite() { + if (selectedTag != null && tags != null) { + for (TagReportComposite tag : tags) { + if (tag.getTag().toString().equals(selectedTag)) { + return tag; + } + } + } + return null; + } + + class DeleteButton extends LocatableIButton { + public DeleteButton(String locatorId) { + super(locatorId); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + deleteButton = null; + } + } } diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/report/tag/TaggedView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/report/tag/TaggedView.java index 465b37c..36e2ff8 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/report/tag/TaggedView.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/report/tag/TaggedView.java @@ -26,9 +26,13 @@ import java.util.ArrayList;
import com.smartgwt.client.data.Criteria; import com.smartgwt.client.widgets.tab.Tab; +import com.smartgwt.client.widgets.tab.events.TabSelectedEvent; +import com.smartgwt.client.widgets.tab.events.TabSelectedHandler;
+import org.rhq.core.domain.resource.ResourceCategory; import org.rhq.core.domain.tagging.Tag; import org.rhq.enterprise.gui.coregui.client.BookmarkableView; +import org.rhq.enterprise.gui.coregui.client.ImageManager; import org.rhq.enterprise.gui.coregui.client.ViewPath; import org.rhq.enterprise.gui.coregui.client.bundle.deployment.BundleDeploymentListView; import org.rhq.enterprise.gui.coregui.client.bundle.destination.BundleDestinationListView; @@ -43,7 +47,11 @@ import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableTabSet; import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
/** + * The main tag cloud view which will show the actual tag cloud with a tabbed view + * underneath containing all the tables of data for the selected tag. + * * @author Greg Hinkle + * @author John Mazzitelli */ public class TaggedView extends LocatableVLayout implements BookmarkableView {
@@ -52,6 +60,7 @@ public class TaggedView extends LocatableVLayout implements BookmarkableView { private TagCloudView tagCloudView; private LocatableTabSet container; private ArrayList<Table> viewsWithTags = new ArrayList<Table>(); + private int selectedTabNum = 0;
public TaggedView(String locatorId) { super(locatorId); @@ -73,40 +82,48 @@ public class TaggedView extends LocatableVLayout implements BookmarkableView { addMember(tagCloudView); }
- @Override - protected void onDraw() { - super.onDraw(); - } - private void viewTag(String tagString) {
+ // if we are switching tags, remove all our tables - we need to recreate them with new criteria + if (tagString != null && !tagString.equals(tagCloudView.getSelectedTag())) { + destroyTagTables(); + } + tagCloudView.setSelectedTag(tagString);
- Tag tag = new Tag(tagString); + if (container == null) {
- Criteria criteria = new Criteria(); - criteria.addCriteria("tagNamespace", tag.getNamespace()); - criteria.addCriteria("tagSemantic", tag.getSemantic()); - criteria.addCriteria("tagName", tag.getName()); + Tag tag = new Tag(tagString);
- if (container == null) { + Criteria criteria = new Criteria(); + criteria.addCriteria("tagNamespace", tag.getNamespace()); + criteria.addCriteria("tagSemantic", tag.getSemantic()); + criteria.addCriteria("tagName", tag.getName());
container = new LocatableTabSet(extendLocatorId("tags")); container.setWidth100(); container.setHeight100(); - addMember(container); + container.setTabBarControls(tagCloudView.getDeleteButton()); + container.addTabSelectedHandler(new TabSelectedHandler() { + public void onTabSelected(TabSelectedEvent event) { + selectedTabNum = event.getTabNum(); + } + }); + container.setSelectedTab(selectedTabNum); // this is so we keep the same tab the user selected between tag selections
Tab tab;
BundlesListView bundlesView = new BundlesListView(getLocatorId(), criteria, null); viewsWithTags.add(bundlesView); tab = new LocatableTab(extendLocatorId("bundleList"), MSG.view_bundle_bundles()); + tab.setIcon(ImageManager.getBundleIcon()); tab.setPane(bundlesView); container.addTab(tab);
BundleVersionListView bundleVersionListView = new BundleVersionListView(getLocatorId(), criteria); viewsWithTags.add(bundleVersionListView); tab = new LocatableTab(extendLocatorId("bundleVersionList"), MSG.view_bundle_bundleVersions()); + tab.setIcon("subsystems/bundle/BundleVersion_16.png"); tab.setPane(bundleVersionListView); container.addTab(tab);
@@ -115,6 +132,7 @@ public class TaggedView extends LocatableVLayout implements BookmarkableView { false); viewsWithTags.add(bundleDeploymentListView); tab = new LocatableTab(extendLocatorId("bundleDeploymentsList"), MSG.view_bundle_bundleDeployments()); + tab.setIcon("subsystems/bundle/BundleDeployment_16.png"); tab.setPane(bundleDeploymentListView); container.addTab(tab);
@@ -122,6 +140,7 @@ public class TaggedView extends LocatableVLayout implements BookmarkableView { criteria); viewsWithTags.add(bundleDestinationListView); tab = new LocatableTab(extendLocatorId("bundleDestinationsList"), MSG.view_bundle_bundleDestinations()); + tab.setIcon("subsystems/bundle/BundleDestination_16.png"); tab.setPane(bundleDestinationListView); container.addTab(tab);
@@ -129,12 +148,15 @@ public class TaggedView extends LocatableVLayout implements BookmarkableView { .view_taggedResources_title()); viewsWithTags.add(resourceView); tab = new LocatableTab(extendLocatorId("resourceList"), MSG.view_taggedResources_title()); + tab.setIcon(ImageManager.getResourceIcon(ResourceCategory.SERVICE)); tab.setPane(resourceView); container.addTab(tab);
for (Table t : viewsWithTags) { t.setShowFooter(false); } + + addMember(container); }
for (Table t : viewsWithTags) { @@ -142,10 +164,22 @@ public class TaggedView extends LocatableVLayout implements BookmarkableView { } }
+ private void destroyTagTables() { + if (this.container != null) { + this.viewsWithTags.clear(); + removeMember(this.container); + this.container.destroy(); + this.container = null; + } + } + public void renderView(ViewPath viewPath) { if (!viewPath.isEnd()) { String tagString = viewPath.getCurrent().getPath(); viewTag(tagString); + } else { + destroyTagTables(); + tagCloudView.setSelectedTag(null); } } } diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties index fd6ac7e..a965934 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties @@ -2021,10 +2021,13 @@ view_measurementOob_title = Suspect Metrics view_tagCloud_title = Tag Cloud view_tagCloud_error_fetchFailure = Failed to load tags. view_tagCloud_error_tagUsedCount = Tag used {0} times. +view_tagCloud_deleteTag = Delete Tag +view_tagCloud_deleteTagFailure = Failed to delete the tag [{0}] +view_tagCloud_deleteTagSuccess = You successfully deleted the tag [{0}]
view_reports_inventorySummary_failFetch = Failed to get inventory summary
-view_taggedResources_title = Tagged Resources +view_taggedResources_title = Resources
view_reports_alertDefinitions_parentHover = Click to go to the parent alert definition view_reports_alertDefinitions_resTypeLoadError = Cannot get the template resource type - unable to view the alert template.
rhq-commits@lists.fedorahosted.org