diff options
8 files changed, 104 insertions, 22 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/WidgetCategory.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/WidgetCategory.java new file mode 100644 index 00000000000..b6a72ebccb9 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/WidgetCategory.java @@ -0,0 +1,34 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.api.web; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @since 2.4 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface WidgetCategory { + String[] value(); +} diff --git a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java index bba95c8fdc7..d6681e35148 100644 --- a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java +++ b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java @@ -122,6 +122,7 @@ public final class JRubyFacade implements ServerComponent { public ViewProxy<Widget> getWidget(String id) { return getContainer().getComponent(Views.class).getWidget(id); } + public List<ViewProxy<Page>> getPages(String section, String resourceScope, String resourceQualifier, String resourceLanguage) { return getContainer().getComponent(Views.class).getPages(section, resourceScope, resourceQualifier, resourceLanguage); diff --git a/sonar-server/src/main/java/org/sonar/server/ui/ViewProxy.java b/sonar-server/src/main/java/org/sonar/server/ui/ViewProxy.java index 0f15f3ad8ae..7cb7159bcf0 100644 --- a/sonar-server/src/main/java/org/sonar/server/ui/ViewProxy.java +++ b/sonar-server/src/main/java/org/sonar/server/ui/ViewProxy.java @@ -38,7 +38,8 @@ public class ViewProxy<V extends View> implements Comparable<ViewProxy> { private String[] defaultForMetrics = {}; private String description = ""; private WidgetProperty[] properties = {}; - private boolean isDefaultTab=false; + private String[] categories = {}; + private boolean isDefaultTab = false; private boolean isWidget = false; public ViewProxy(final V view) { @@ -71,7 +72,7 @@ public class ViewProxy<V extends View> implements Comparable<ViewProxy> { DefaultTab defaultTabAnnotation = AnnotationUtils.getClassAnnotation(view, DefaultTab.class); if (defaultTabAnnotation != null) { - if (defaultTabAnnotation==null || defaultTabAnnotation.metrics().length==0) { + if (defaultTabAnnotation == null || defaultTabAnnotation.metrics().length == 0) { isDefaultTab = true; defaultForMetrics = new String[0]; @@ -91,6 +92,11 @@ public class ViewProxy<V extends View> implements Comparable<ViewProxy> { properties = widgetProperties.value(); } + WidgetCategory widgetCategory = AnnotationUtils.getClassAnnotation(view, WidgetCategory.class); + if (widgetCategory != null) { + categories = widgetCategory.value(); + } + isWidget = (view instanceof Widget); } @@ -107,11 +113,15 @@ public class ViewProxy<V extends View> implements Comparable<ViewProxy> { } public String getDescription() { - return description; + return description; } public WidgetProperty[] getProperties() { - return properties; + return properties; + } + + public String[] getCategories() { + return categories; } public String[] getSections() { diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboard_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboard_controller.rb index bf7725dff03..50d872a104c 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboard_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboard_controller.rb @@ -75,7 +75,7 @@ class DashboardController < ApplicationController widget.save! all_ids<<widget.id end - end + end end @dashboard.widgets.reject{|w| all_ids.include?(w.id)}.each do |w| w.destroy @@ -140,6 +140,11 @@ class DashboardController < ApplicationController end end + def widget_definitions + load_widget_definitions(params[:category]) + render :partial => 'dashboard/widget_definitions', :locals => {:dashboard_id => params[:did], :resource_id => params[:rid], :filter_on_category => params[:category]} + end + private def load_dashboard @@ -193,8 +198,14 @@ class DashboardController < ApplicationController end end - def load_widget_definitions() - @widget_definitions = java_facade.getWidgets() + def load_widget_definitions(filter_on_category=nil) + @widget_definitions=java_facade.getWidgets() + @widget_categories=[] + @widget_definitions.each {|definition| @widget_categories<<definition.getCategories()} + @widget_categories=@widget_categories.flatten.uniq.sort + unless filter_on_category.blank? + @widget_definitions=@widget_definitions.select{|definition| definition.getCategories().to_a.include?(filter_on_category)} + end end end
\ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_widget_definition.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_widget_definition.html.erb index ef2dd5203db..eaaceb181c2 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_widget_definition.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_widget_definition.html.erb @@ -1,9 +1,9 @@ <td> - <div class="widget_def" id="def_<%= definition.getId().tr('_', '') -%>"> +<div class="widget_def" id="def_<%= definition.getId().tr('_', '') -%>"> <p><b><%= h definition.getTitle() -%></b></p> <p><%= h definition.getDescription() -%></p> -<%= form_tag :action => 'add_widget', :did => @dashboard.id, :id => params[:id], :widget => definition.getId() %> - <input type="submit" value="Add widget" > +<%= form_tag :action => 'add_widget', :did => dashboard_id, :id => resource_id, :widget => definition.getId() %> +<input type="submit" value="Add widget" > </form> - </div> -</td>
\ No newline at end of file +</div> +</td> diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_widget_definitions.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_widget_definitions.html.erb new file mode 100644 index 00000000000..6d330e40dba --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_widget_definitions.html.erb @@ -0,0 +1,18 @@ +<p> + <ul class="horizontal widget_categs"> + <li>Filter: </li> + <li class="<%= 'selected' if filter_on_category.blank? -%>"><a href="#" onClick="return filterWidgets('')">None</a></li> + <% @widget_categories.each do |category| %> + <li class="<%= 'selected' if filter_on_category==category -%>"><a href="#" onClick="return filterWidgets('<%= category -%>')"><%= h(category) -%></a></li> + <% end %> + </ul> + <%= image_tag 'loading.gif', :style=>'vertical-align: top;display: none', :id => 'filter-widgets-loading' -%> +</p> +<table width="100%"> + <% @widget_definitions.each_with_index do |definition, index| %> + <% if index%4==0 %><tr><% end %> + <%= render :partial => 'dashboard/widget_definition', :locals => {:definition => definition, :dashboard_id => dashboard_id, :resource_id => resource_id} %> + <% if index%4==3 %></tr><% end %> + <% end %> + <% if @widget_definitions.size%4<3 %></tr><% end %> +</table> diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/configure.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/configure.html.erb index 3917a3d4736..504e9f0a33d 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/configure.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/configure.html.erb @@ -24,22 +24,24 @@ <% end %> } Event.observe(window, 'load', init_dashboard, false); + + function filterWidgets(category){ + new Ajax.Updater( + 'widget_defs', + '<%= url_for :controller => "dashboard", :action => "widget_definitions", :did => @dashboard.id, :rid => @resource.id -%>&category=' + category, + {asynchronous:true, evalScripts:true}); + $('filter-widgets-loading').show(); + return false; + } + //--> </script> - <div id="dashboard"> <%= render :partial => 'dashboard/header', :locals => {:back => true} %> <div id="widget_defs"> - <table width="100%"> - <% @widget_definitions.each_with_index do |definition, index| %> - <% if index%4==0 %><tr><% end %> - <%= render :partial => 'dashboard/widget_definition', :locals => {:definition => definition} %> - <% if index%4==3 %></tr><% end %> - <% end %> - <% if @widget_definitions.size%4<3 %></tr><% end %> - </table> + <%= render :partial => 'dashboard/widget_definitions', :locals => {:dashboard_id => @dashboard.id, :resource_id => @resource.id, :filter_on_category => nil}-%> </div> diff --git a/sonar-server/src/main/webapp/stylesheets/dashboard.css b/sonar-server/src/main/webapp/stylesheets/dashboard.css index 5b935b7b576..321454fa79a 100644 --- a/sonar-server/src/main/webapp/stylesheets/dashboard.css +++ b/sonar-server/src/main/webapp/stylesheets/dashboard.css @@ -70,7 +70,13 @@ margin: 3px; white-space: normal; vertical-align: top; - +} +#dashboard ul.widget_categs li { + padding-right: 5px; +} +#dashboard ul.widget_categs li.selected a { + font-weight: bold; + text-decoration: none; } /*OPERATIONS*/ #dashboard #dashboard-operations { |