aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsimonbrandhof <simon.brandhof@gmail.com>2010-12-03 00:09:06 +0000
committersimonbrandhof <simon.brandhof@gmail.com>2010-12-03 00:09:06 +0000
commit3ed6a62ad9e0fa21c108ab1e13724c90269ad2ca (patch)
tree930376e159c42017e51bb6f9376360424050c28b
parentfcd0d57b85fcc029d8fa2e05d6e03fd9225c8134 (diff)
downloadsonarqube-3ed6a62ad9e0fa21c108ab1e13724c90269ad2ca.tar.gz
sonarqube-3ed6a62ad9e0fa21c108ab1e13724c90269ad2ca.zip
SONAR-249 do not hide widgets which are changed in variation view + improve ruby api to display trend icons and measure variations + support variations in the widgets rules/size
-rw-r--r--plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/rules.html.erb124
-rw-r--r--plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/size.html.erb51
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java14
-rw-r--r--sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java4
-rw-r--r--sonar-server/src/main/java/org/sonar/server/ui/ViewProxy.java9
-rw-r--r--sonar-server/src/main/java/org/sonar/server/ui/Views.java4
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboard_controller.rb2
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb140
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/models/project_measure.rb58
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/db/migrate/150_add_plugins_child_first_classloader_column.rb4
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/db/migrate/151_create_dashboards.rb3
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/db/migrate/152_delete_duplicated_lib_snapshots.rb4
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/db/migrate/160_add_rule_failures_created_at_column.rb4
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/db/migrate/161_add_snapshots_var_columns.rb4
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/db/migrate/162_delete_iso_rule_categories.rb5
-rw-r--r--sonar-server/src/main/webapp/stylesheets/style.css17
-rw-r--r--sonar-server/src/test/java/org/sonar/server/ui/ViewsTest.java6
17 files changed, 299 insertions, 154 deletions
diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/rules.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/rules.html.erb
index c62d9c4c78e..8875bed9ffd 100644
--- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/rules.html.erb
+++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/rules.html.erb
@@ -1,88 +1,134 @@
-<% if measure(Metric::LINES) %>
+<%
+ violations=@snapshot.measure('violations')
+ density=@snapshot.measure('violations_density')
+ blocker_violations = @snapshot.measure('blocker_violations')
+ critical_violations = @snapshot.measure('critical_violations')
+ major_violations = @snapshot.measure('major_violations')
+ minor_violations = @snapshot.measure('minor_violations')
+ info_violations = @snapshot.measure('info_violations')
+%>
<table width="100%">
<tr>
- <td valign="top" width="50%">
+ <td valign="top">
<div class="dashbox">
<h3>Violations</h3>
- <div class="big marginbottom10">
- <%= format_measure(Metric::VIOLATIONS, :url => url_for(:controller => 'drilldown', :action => 'violations', :id => @project.key)) -%> <%= trend_icon(Metric::VIOLATIONS) -%>
+ <div class="marginbottom10">
+ <span class="big">
+ <%= format_measure(violations, :url => url_for(:controller => 'drilldown', :action => 'violations', :id => @project.key)) -%>
+ </span>
+ <%= dashboard_configuration.variation? ? format_variation(violations) : trend_icon(violations) -%>
</div>
<h3>Rules compliance</h3>
- <div class="big">
- <%= format_measure(Metric::VIOLATIONS_DENSITY, :url => url_for_drilldown(Metric::WEIGHTED_VIOLATIONS, {:highlight => Metric::WEIGHTED_VIOLATIONS})) -%> <%= trend_icon(Metric::VIOLATIONS_DENSITY) -%>
+ <div>
+ <span class="big">
+ <%= format_measure(density, :url => url_for_drilldown(Metric::WEIGHTED_VIOLATIONS, {:highlight => Metric::WEIGHTED_VIOLATIONS})) -%>
+ </span>
+ <%= dashboard_configuration.variation? ? format_variation(density) : trend_icon(density) -%>
</div>
</div>
</td>
- <td valign="top" width="50%" nowrap>
+ <td valign="top" nowrap>
<%
- blocker_violations = @snapshot.measure(Metric::BLOCKER_VIOLATIONS)
- critical_violations = @snapshot.measure(Metric::CRITICAL_VIOLATIONS)
- major_violations = @snapshot.measure(Metric::MAJOR_VIOLATIONS)
- minor_violations = @snapshot.measure(Metric::MINOR_VIOLATIONS)
- info_violations = @snapshot.measure(Metric::INFO_VIOLATIONS)
- max = 0
- [blocker_violations,critical_violations,major_violations,minor_violations,info_violations].each do |m|
- max = m.value if m and m.value and m.value>max
- end
+ values=[blocker_violations,critical_violations,major_violations,minor_violations,info_violations]
+ if dashboard_configuration.variation?
+ values=values.map{|m| m ? (m.variation(dashboard_configuration.variation_index)||0) : 0}
+ else
+ values=values.map{|m| m ? (m.value||0) : 0}
+ end
+ max=values.map{|val| val.abs}.max
%>
<table class="clear width100">
<tr>
<td><%= image_tag 'priority/BLOCKER.png'%></td>
<td> &nbsp;<%= link_to 'Blocker', {:controller => 'drilldown', :action => 'violations', :id => @project.key, :priority => 'BLOCKER'} %></td>
- <td style="padding-left: 10px;" align="right">
+ <td style="padding: 0 10px;" align="right">
<%= format_measure(blocker_violations) -%>
</td>
- <td width="1%"><%= trend_icon(blocker_violations) -%></td>
+ <td>
+ <%= dashboard_configuration.variation? ? format_variation(blocker_violations) : trend_icon(blocker_violations, :empty => true) -%>
+ </td>
<td align="left" style="padding-bottom:2px; padding-top:2px;">
- <%= barchart(:width => 60, :percent => (blocker_violations ? (100 * blocker_violations.value / max).to_i : 0), :color => '#777777') if max>0 %>
+ <% if dashboard_configuration.variation? %>
+ <%= barchart(:width => 35, :percent => (values[0]<0 ? (100 * values[0] / max).to_i : 0), :color => '#078C00') %>
+ <%= barchart(:width => 35, :percent => (values[0]>0 ? (100 * values[0] / max).to_i : 0), :color => '#cc0000') %>
+ <% else %>
+ <%= barchart(:width => 70, :percent => (100 * values[0] / max).to_i) %>
+ <% end %>
</td>
</tr>
<tr>
<td><%= image_tag 'priority/CRITICAL.png' %></td>
<td> &nbsp;<%= link_to 'Critical', {:controller => 'drilldown', :action => 'violations', :id => @project.key, :priority => 'CRITICAL'} %></td>
- <td style="padding-left: 10px;" align="right">
- <%= format_measure(critical_violations) -%>
+ <td style="padding: 0 10px;" align="right">
+ <%= format_measure(critical_violations) -%>
+ </td>
+ <td>
+ <%= dashboard_configuration.variation? ? format_variation(critical_violations) : trend_icon(critical_violations, :empty => true) -%>
</td>
- <td width="1%"><%= trend_icon(critical_violations) -%></td>
<td align="left" style="padding-bottom:2px; padding-top:2px;">
- <%= barchart(:width => 60, :percent => (critical_violations ? (100 * critical_violations.value / max).to_i : 0), :color => '#777777') if max>0 %>
+ <% if dashboard_configuration.variation? %>
+ <%= barchart(:width => 35, :percent => (values[1]<0 ? (100 * values[1] / max).to_i : 0), :color => '#078C00') %>
+ <%= barchart(:width => 35, :percent => (values[1]>0 ? (100 * values[1] / max).to_i : 0), :color => '#cc0000') %>
+ <% else %>
+ <%= barchart(:width => 70, :percent => (100 * values[1] / max).to_i) %>
+ <% end %>
</td>
</tr>
<tr>
<td><%= image_tag 'priority/MAJOR.png' %></td>
<td> &nbsp;<%= link_to 'Major', {:controller => 'drilldown', :action => 'violations', :id => @project.key, :priority => 'MAJOR'} %></td>
- <td style="padding-left: 10px;" align="right">
+ <td style="padding: 0 10px;" align="right">
<%= format_measure(major_violations) -%>
- </td>
- <td width="1%"><%= trend_icon(major_violations) -%></td>
+ </td>
+ <td>
+ <%= dashboard_configuration.variation? ? format_variation(major_violations) : trend_icon(major_violations, :empty => true) -%>
+ </td>
<td align="left" style="padding-bottom:2px; padding-top:2px;">
- <%= barchart(:width => 60, :percent => (major_violations ? (100 * major_violations.value / max).to_i : 0), :color => '#777777') if max>0 %>
+ <% if dashboard_configuration.variation? %>
+ <%= barchart(:width => 35, :percent => (values[2]<0 ? (100 * values[2] / max).to_i : 0), :color => '#078C00') %>
+ <%= barchart(:width => 35, :percent => (values[2]>0 ? (100 * values[2] / max).to_i : 0), :color => '#cc0000') %>
+ <% else %>
+ <%= barchart(:width => 70, :percent => (100 * values[2] / max).to_i) %>
+ <% end %>
</td>
</tr>
<tr>
<td><%= image_tag 'priority/MINOR.png' %></td>
<td> &nbsp;<%= link_to 'Minor', {:controller => 'drilldown', :action => 'violations', :id => @project.key, :priority => 'MINOR'} %></td>
- <td style="padding-left: 10px;" align="right">
- <%= format_measure(minor_violations) -%>
- </td>
- <td width="1%"><%= trend_icon(minor_violations) -%></td>
+ <td style="padding: 0 10px;" align="right">
+ <%= format_measure(minor_violations) -%>
+ </td>
+ <td>
+ <%= dashboard_configuration.variation? ? format_variation(minor_violations) : trend_icon(minor_violations, :empty => true) -%>
+ </td>
<td align="left" style="padding-bottom:2px; padding-top:2px;">
- <%= barchart(:width => 60, :percent => (minor_violations ? (100 * minor_violations.value / max).to_i : 0), :color => '#777777') if max>0 %>
+ <% if dashboard_configuration.variation? %>
+ <%= barchart(:width => 35, :percent => (values[3]<0 ? (100 * values[3] / max).to_i : 0), :color => '#078C00') %>
+ <%= barchart(:width => 35, :percent => (values[3]>0 ? (100 * values[3] / max).to_i : 0), :color => '#cc0000') %>
+ <% else %>
+ <%= barchart(:width => 70, :percent => (100 * values[3] / max).to_i) %>
+ <% end %>
</td>
</tr>
<tr>
<td><%= image_tag 'priority/INFO.png' %></td>
<td> &nbsp;<%= link_to 'Info', {:controller => 'drilldown', :action => 'violations', :id => @project.key, :priority => 'INFO'} %></td>
- <td style="padding-left: 10px;" align="right">
- <%= format_measure(info_violations) -%>
- </td>
- <td width="1%"><%= trend_icon(info_violations) -%></td>
+ <td style="padding: 0 10px;" align="right">
+ <%= format_measure(info_violations) -%>
+ </td>
+ <td>
+ <%= dashboard_configuration.variation? ? format_variation(info_violations) : trend_icon(info_violations, :empty => true) -%>
+ </td>
<td align="left" style="padding-bottom:2px; padding-top:2px;">
- <%= barchart(:width => 60, :percent => (info_violations ? (100 * info_violations.value / max).to_i : 0), :color => '#777777') if max>0 %>
+ <% if dashboard_configuration.variation? %>
+ <%= barchart(:width => 35, :percent => (values[4]<0 ? (100 * values[4] / max).to_i : 0), :color => '#078C00') %>
+ <%= barchart(:width => 35, :percent => (values[4]>0 ? (100 * values[4] / max).to_i : 0), :color => '#cc0000') %>
+ <% else %>
+ <%= barchart(:width => 70, :percent => (100 * values[4] / max).to_i) %>
+ <% end %>
</td>
</tr>
</table>
</td>
</tr>
- </table>
-<% end %> \ No newline at end of file
+ </table>
diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/size.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/size.html.erb
index bf89a8e1903..1e8e44cf792 100644
--- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/size.html.erb
+++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/size.html.erb
@@ -1,63 +1,76 @@
<%
-if measure('lines') || measure('ncloc')
+ lines=measure('lines')
+ ncloc=measure('ncloc')
+ classes=measure('classes')
files=measure('files')
- statements=measure('statements')
+ packages=measure('packages')
+ functions=measure('functions')
+ if measure('lines') || ncloc
+ files=measure('files')
+ statements=measure('statements')
%>
<table width="100%">
<tr>
<td valign="top" width="48%" nowrap>
<div class="dashbox">
<h3>Lines of code</h3>
- <% if measure('ncloc') %>
- <p><span class="big">
- <%= format_measure('ncloc', :suffix => '', :url => url_for_drilldown('ncloc')) -%> <%= trend_icon('ncloc', :big => true) -%></span></p>
+ <% if ncloc %>
+ <p>
+ <span class="big"><%= format_measure(ncloc, :suffix => '', :url => url_for_drilldown(ncloc)) -%></span>
+ <%= dashboard_configuration.variation? ? format_variation(ncloc) : trend_icon(ncloc, :big => true) -%>
+ </p>
<%
generated_ncloc=measure('generated_ncloc')
if generated_ncloc && generated_ncloc.value>0
%>
- <p>+<%= format_measure(generated_ncloc, :suffix => ' generated', :url => url_for_drilldown(generated_ncloc)) -%> <%= trend_icon(generated_ncloc) -%></p>
+ <p>+<%= format_measure(generated_ncloc, :suffix => ' generated', :url => url_for_drilldown(generated_ncloc)) -%> <%= dashboard_configuration.variation? ? format_variation(generated_ncloc) : trend_icon(generated_ncloc) -%></p>
<% end %>
- <p><%= format_measure('lines', :suffix => ' lines', :url => url_for_drilldown('lines')) -%> <%= trend_icon('lines') -%></p>
+ <p><%= format_measure(lines, :suffix => ' lines', :url => url_for_drilldown(lines)) -%> <%= dashboard_configuration.variation? ? format_variation(lines) : trend_icon(lines) -%></p>
<% else%>
- <p><span class="big"><%= format_measure('lines', :suffix => '', :url => url_for_drilldown('lines')) -%> <%= trend_icon('lines', :big => true) -%></span></p>
+ <p><span class="big"><%= format_measure(lines, :suffix => '', :url => url_for_drilldown(lines)) -%> <%= trend_icon(lines, :big => true) -%></span></p>
<% end %>
<%
generated_lines=measure('generated_lines')
if generated_lines && generated_lines.value>0
%>
- <p>incl. <%= format_measure(generated_lines, :suffix => ' generated', :url => url_for_drilldown(generated_lines)) -%> <%= trend_icon(generated_lines) -%></p>
+ <p>incl. <%= format_measure(generated_lines, :suffix => ' generated', :url => url_for_drilldown(generated_lines)) -%> <%= dashboard_configuration.variation? ? format_variation(generated_lines) : trend_icon(generated_lines) -%></p>
<% end %>
<% if statements %>
<p>
- <%= format_measure(statements, :suffix => ' statements', :url => url_for_drilldown(statements)) -%> <%= trend_icon(statements) -%>
+ <%= format_measure(statements, :suffix => ' statements', :url => url_for_drilldown(statements)) -%> <%= dashboard_configuration.variation? ? format_variation(statements) : trend_icon(statements) -%>
</p>
<% end %>
<% if files && measure('classes') %>
- <p><%= format_measure(files, :suffix => ' files', :url => url_for_drilldown(files)) -%> <%= trend_icon(files) -%></p>
+ <p><%= format_measure(files, :suffix => ' files', :url => url_for_drilldown(files)) -%> <%= dashboard_configuration.variation? ? format_variation(files) : trend_icon(files) -%></p>
<% end %>
</div>
</td>
<td width="10"> </td>
<td valign="top">
<div class="dashbox">
- <% if measure('classes') %>
+ <% if classes %>
<h3>Classes</h3>
- <p><span class="big"><%= format_measure('classes', :url => url_for_drilldown('classes')) -%> <%= trend_icon('classes') -%></span></p>
- <p><%= format_measure('packages', :suffix => ' packages', :url => url_for_drilldown('packages')) -%> <%= trend_icon('packages') -%></p>
+ <p>
+ <span class="big"><%= format_measure(classes, :url => url_for_drilldown(classes)) -%></span>
+ <%= dashboard_configuration.variation? ? format_variation(classes) : trend_icon(classes, :big => true) -%>
+ </p>
+ <p><%= format_measure(packages, :suffix => ' packages', :url => url_for_drilldown(packages)) -%> <%= dashboard_configuration.variation? ? format_variation(packages) : trend_icon(packages) -%></p>
<% else %>
<h3>Files</h3>
- <p><span class="big"><%= format_measure('files', :url => url_for_drilldown('files')) -%> <%= trend_icon('files') -%></span></p>
- <p><%= format_measure('directories', :suffix => ' directories', :url => url_for_drilldown('directories')) -%> <%= trend_icon('directories') -%></p>
+ <p><span class="big"><%= format_measure(files, :url => url_for_drilldown(files)) -%></span>
+ <%= dashboard_configuration.variation? ? format_variation(files) : trend_icon(files, :big => true) -%>
+ </p>
+ <p><%= format_measure('directories', :suffix => ' directories', :url => url_for_drilldown('directories')) -%> <%= dashboard_configuration.variation? ? format_variation('directories') : trend_icon('directories') -%></p>
<% end %>
- <p><%= format_measure('functions', :suffix => ' methods', :url => url_for_drilldown('functions')) -%> <%= trend_icon('functions') -%></p>
+ <p><%= format_measure(functions, :suffix => ' methods', :url => url_for_drilldown(functions)) -%> <%= dashboard_configuration.variation? ? format_variation(functions) : trend_icon(functions) -%></p>
<%
if (measure('accessors'))
prefix=(dashboard_configuration.variation? ? '' : '+')
%>
- <p><%= format_measure('accessors', :prefix => prefix, :suffix => ' accessors', :url => url_for_drilldown('accessors')) -%> <%= trend_icon('accessors') -%></p>
+ <p><%= format_measure('accessors', :prefix => prefix, :suffix => ' accessors', :url => url_for_drilldown('accessors')) -%> <%= dashboard_configuration.variation? ? format_variation('accessors') : trend_icon('accessors') -%></p>
<% end %>
<% if measure('paragraphs') %>
- <p><%= format_measure('paragraphs', :suffix => ' paragraphs', :url => url_for_drilldown('paragraphs')) -%> <%= trend_icon('paragraphs') -%></p>
+ <p><%= format_measure('paragraphs', :suffix => ' paragraphs', :url => url_for_drilldown('paragraphs')) -%> <%= dashboard_configuration.variation? ? format_variation('paragraphs') : trend_icon('paragraphs') -%></p>
<% end %>
</div>
</td>
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java
index 0954951f490..b51e25ac688 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java
@@ -351,31 +351,31 @@ public final class CoreMetrics {
public static final String VIOLATIONS_KEY = "violations";
public static final Metric VIOLATIONS = new Metric(VIOLATIONS_KEY, "Violations", "Violations", Metric.ValueType.INT,
- Metric.DIRECTION_WORST, false, DOMAIN_RULES).setBestValue(0.0).setOptimizedBestValue(true);
+ Metric.DIRECTION_WORST, true, DOMAIN_RULES).setBestValue(0.0).setOptimizedBestValue(true);
public static final String NEW_VIOLATIONS_KEY = "new_violations";
public static final Metric NEW_VIOLATIONS = new Metric(NEW_VIOLATIONS_KEY, "New Violations", "New Violations", Metric.ValueType.INT,
- Metric.DIRECTION_WORST, false, DOMAIN_RULES);
+ Metric.DIRECTION_WORST, true, DOMAIN_RULES);
public static final String BLOCKER_VIOLATIONS_KEY = "blocker_violations";
public static final Metric BLOCKER_VIOLATIONS = new Metric(BLOCKER_VIOLATIONS_KEY, "Blocker violations", "Blocker violations",
- Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_RULES).setBestValue(0.0).setOptimizedBestValue(true);
+ Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_RULES).setBestValue(0.0).setOptimizedBestValue(true);
public static final String CRITICAL_VIOLATIONS_KEY = "critical_violations";
public static final Metric CRITICAL_VIOLATIONS = new Metric(CRITICAL_VIOLATIONS_KEY, "Critical violations", "Critical violations",
- Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_RULES).setBestValue(0.0).setOptimizedBestValue(true);
+ Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_RULES).setBestValue(0.0).setOptimizedBestValue(true);
public static final String MAJOR_VIOLATIONS_KEY = "major_violations";
public static final Metric MAJOR_VIOLATIONS = new Metric(MAJOR_VIOLATIONS_KEY, "Major violations", "Major violations",
- Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_RULES).setBestValue(0.0).setOptimizedBestValue(true);
+ Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_RULES).setBestValue(0.0).setOptimizedBestValue(true);
public static final String MINOR_VIOLATIONS_KEY = "minor_violations";
public static final Metric MINOR_VIOLATIONS = new Metric(MINOR_VIOLATIONS_KEY, "Minor violations", "Minor violations",
- Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_RULES).setBestValue(0.0).setOptimizedBestValue(true);
+ Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_RULES).setBestValue(0.0).setOptimizedBestValue(true);
public static final String INFO_VIOLATIONS_KEY = "info_violations";
public static final Metric INFO_VIOLATIONS = new Metric(INFO_VIOLATIONS_KEY, "Info violations", "Info violations", Metric.ValueType.INT,
- Metric.DIRECTION_WORST, false, DOMAIN_RULES).setBestValue(0.0).setOptimizedBestValue(true);
+ Metric.DIRECTION_WORST, true, DOMAIN_RULES).setBestValue(0.0).setOptimizedBestValue(true);
/* Design */
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 259fcb9f06a..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
@@ -111,8 +111,8 @@ public final class JRubyFacade implements ServerComponent {
}
}
- public List<ViewProxy<Widget>> getWidgets(String resourceScope, String resourceQualifier, String resourceLanguage, boolean differentialDashboard) {
- return getContainer().getComponent(Views.class).getWidgets(resourceScope, resourceQualifier, resourceLanguage, differentialDashboard);
+ public List<ViewProxy<Widget>> getWidgets(String resourceScope, String resourceQualifier, String resourceLanguage) {
+ return getContainer().getComponent(Views.class).getWidgets(resourceScope, resourceQualifier, resourceLanguage);
}
public List<ViewProxy<Widget>> getWidgets() {
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 791d1c17ff8..59fae3ac6a5 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
@@ -42,7 +42,6 @@ public class ViewProxy<V extends View> implements Comparable<ViewProxy> {
private WidgetLayoutType widgetLayout = WidgetLayoutType.DEFAULT;
private boolean isDefaultTab = false;
private boolean isWidget = false;
- private boolean supportsVariationDashboard = false;
public ViewProxy(final V view) {
this.view = view;
@@ -104,10 +103,6 @@ public class ViewProxy<V extends View> implements Comparable<ViewProxy> {
widgetLayout = layoutAnnotation.value();
}
- if (AnnotationUtils.getClassAnnotation(view, SupportVariationDashboard.class)!=null) {
- supportsVariationDashboard = true;
- }
-
isWidget = (view instanceof Widget);
}
@@ -179,10 +174,6 @@ public class ViewProxy<V extends View> implements Comparable<ViewProxy> {
return !ArrayUtils.isEmpty(widgetProperties);
}
- public boolean supportsVariationDashboard() {
- return supportsVariationDashboard;
- }
-
public boolean hasRequiredProperties() {
boolean requires = false;
for (WidgetProperty property : widgetProperties) {
diff --git a/sonar-server/src/main/java/org/sonar/server/ui/Views.java b/sonar-server/src/main/java/org/sonar/server/ui/Views.java
index 2f0ccfba48a..69e4c8ee643 100644
--- a/sonar-server/src/main/java/org/sonar/server/ui/Views.java
+++ b/sonar-server/src/main/java/org/sonar/server/ui/Views.java
@@ -76,10 +76,10 @@ public class Views implements ServerComponent {
return widgetsPerId.get(id);
}
- public List<ViewProxy<Widget>> getWidgets(String resourceScope, String resourceQualifier, String resourceLanguage, boolean variationDashboard) {
+ public List<ViewProxy<Widget>> getWidgets(String resourceScope, String resourceQualifier, String resourceLanguage) {
List<ViewProxy<Widget>> result = Lists.newArrayList();
for (ViewProxy<Widget> proxy : widgets) {
- if (accept(proxy, null, resourceScope, resourceQualifier, resourceLanguage) && (!variationDashboard || proxy.supportsVariationDashboard())) {
+ if (accept(proxy, null, resourceScope, resourceQualifier, resourceLanguage)) {
result.add(proxy);
}
}
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 02baac0c617..2ac65f9e3ba 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
@@ -185,7 +185,7 @@ class DashboardController < ApplicationController
end
def load_authorized_widget_definitions()
- @widget_definitions = java_facade.getWidgets(@resource.scope, @resource.qualifier, @resource.language, @dashboard_configuration.variation?)
+ @widget_definitions = java_facade.getWidgets(@resource.scope, @resource.qualifier, @resource.language)
@widget_definitions=@widget_definitions.select do |widget|
authorized=widget.getUserRoles().size==0
unless authorized
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb b/sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb
index 12ae02f6c87..191370f66ac 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb
@@ -211,8 +211,6 @@ module ApplicationHelper
# * <tt>:prefix</tt> - add a prefix. Default is ''.
# * <tt>:suffix</tt> - add a suffix. Default is ''.
# * <tt>:default</tt> - text to return if metric or measure not found. Default is blank string.
- # * <tt>:mode</tt> - display the measure value (:value) or the variation (:variation). The default mode is :auto, according to the mode selected in the dashboard
- # * <tt>:variation</tt> - the configuration index between 1 and 3. Only when :mode => :variation
#
# === Examples
#
@@ -236,39 +234,23 @@ module ApplicationHelper
link_rel=''
show_link= !options[:url].blank?
- variation_mode = false
if m.metric.val_type==Metric::VALUE_TYPE_LEVEL
html=image_tag("levels/#{m.data.downcase}.png") unless m.data.blank?
else
- mode=options[:mode]||:auto
- if mode==:value
- html=m.formatted_value
- elsif mode==:variation
- html=m.formatted_var_value(options[:variation_index]||1)
- variation_mode = true
- else
- if @dashboard_configuration && @dashboard_configuration.variation?
- html=m.formatted_variation_value(@dashboard_configuration.variation_index)
- variation_mode = true
- else
- html=m.formatted_value
- end
- end
+ html=m.formatted_value
end
alert_class=''
alert_link = false
style = ''
- if !variation_mode
- if !(m.alert_status.blank?)
- alert_class="class='alert_#{m.alert_status}'" unless m.metric.val_type==Metric::VALUE_TYPE_LEVEL
- link_rel=h(m.alert_text)
- show_link=true
- alert_link = true
-
- elsif m.metric.val_type==Metric::VALUE_TYPE_RATING && m.color
- style = "style='background-color: #{m.color.html};padding: 2px 5px'"
- end
+ if !(m.alert_status.blank?)
+ alert_class="class='alert_#{m.alert_status}'" unless m.metric.val_type==Metric::VALUE_TYPE_LEVEL
+ link_rel=h(m.alert_text)
+ show_link=true
+ alert_link = true
+
+ elsif m.metric.val_type==Metric::VALUE_TYPE_RATING && m.color
+ style = "style='background-color: #{m.color.html};padding: 2px 5px'"
end
span_id=''
@@ -359,13 +341,28 @@ module ApplicationHelper
chart
end
+ #
+ #
+ # Draw a HTML/CSS bar
+ #
+ # === Optional parameters
+ # * width: container width in pixels. Default is 150.
+ # * percent: integer between -100 and 100. Size of the bar inside the container. Default is 100. Bar is aligned to right if the value is negative.
+ # * color: the bar HTML color. Default value is '#777'
+ #
def barchart(options)
percent = (options[:percent] || 100).to_i
- return '' if percent<=0
+ width=(options[:width] || 150).to_i
+ if options[:positive_color] && percent>0
+ color = options[:positive_color]
+ elsif options[:negative_color] && percent<0
+ color = options[:negative_color]
+ else
+ color = options[:color]||'#777'
+ end
- width = (options[:width] || 150).to_i
- color = (options[:color] ? "background-color: #{options[:color]};" : '')
- "<div class='barchart' style='width: #{width}px'><div style='width: #{percent}%;#{color}'></div></div>"
+ align=(percent<0 ? 'float: right;' : nil)
+ "<div class='barchart' style='width: #{width}px'><div style='width: #{percent.abs}%;background-color:#{color};#{align}'></div></div>"
end
def chart(parameters, options={})
@@ -394,12 +391,12 @@ module ApplicationHelper
#
# === Optional parameters
# * big: true|false. Default is false.
- # * force: true|false. By default trend icons are hidden when the dashboard variation mode is selected.
+ # * empty: true|false. Show an empty transparent image when no trend or no measure. Default is false.
#
# === Examples
# trend_icon('ncloc')
# trend_icon(measure('ncloc'))
- # trend_icon('ncloc', :big => true)
+ # trend_icon('ncloc', :big => true, :empty => true)
#
def trend_icon(metric_or_measure, options={})
if metric_or_measure.is_a? ProjectMeasure
@@ -408,13 +405,9 @@ module ApplicationHelper
m = @snapshot.measure(metric_or_measure)
end
- if defined?(@dashboard_configuration) && @dashboard_configuration.variation?
- return nil unless options[:force]
- end
-
big=options[:big]||false
if m.nil? || m.tendency.nil? || m.tendency==0
- return image_tag("transparent.gif", :width => big ? "18" : "16", :alt => "")
+ return options[:empty] ? image_tag("transparent.gif", :width => big ? "18" : "16", :alt => "") : nil
end
filename = m.tendency.to_s
@@ -429,4 +422,75 @@ module ApplicationHelper
suffix = (big ? '' : '-small')
image_tag("tendency/#{filename}#{suffix}.png")
end
+
+ #
+ #
+ # Numeric value of variation
+ #
+ # === Optional parameters
+ # * index: integer between 1 and 3. By default the index is defined by the dashboard variation select-box
+ #
+ # === Examples
+ # variation_value('ncloc')
+ # variation_value(measure('ncloc'))
+ # variation_value('ncloc', :index => 3)
+ #
+ def variation_value(metric_or_measure, options={})
+ if metric_or_measure.is_a?(ProjectMeasure)
+ m = metric_or_measure
+ elsif @snapshot
+ m = @snapshot.measure(metric_or_measure)
+ end
+
+ index=options[:index]
+ if index.nil? && defined?(@dashboard_configuration) && @dashboard_configuration.variation?
+ index = @dashboard_configuration.variation_index
+ end
+
+ m.variation(index)
+ end
+
+
+ #
+ #
+ # Format variation value
+ #
+ # === Optional parameters
+ # * color: true|false. Default is true.
+ # * index: integer between 1 and 3. By default the index is defined by the dashboard variation select-box
+ #
+ # === Examples
+ # format_variation('ncloc')
+ # format_variation(measure('ncloc'), :index => 3, :color => true)
+ #
+ def format_variation(metric_or_measure, options={})
+ if metric_or_measure.is_a?(ProjectMeasure)
+ m = metric_or_measure
+ elsif @snapshot
+ m = @snapshot.measure(metric_or_measure)
+ end
+ html=nil
+ if m
+ val=variation_value(m, options)
+ if val
+ formatted_val=(val>=0 ? "+#{m.format_numeric_value(val)}" : m.format_numeric_value(val))
+ css_class=''
+ if options[:color]||true
+ css_class='var'
+ if m.metric.qualitative?
+ factor=m.metric.direction * val
+ if factor>0
+ # better
+ css_class='varb'
+ elsif factor<0
+ # worst
+ css_class='varw'
+ end
+ end
+ end
+ html="<span class='#{css_class}'>(#{formatted_val})</span>"
+ end
+ end
+ html
+ end
end
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/project_measure.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/project_measure.rb
index 42f4cccc19f..e249ed87b6c 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/models/project_measure.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/models/project_measure.rb
@@ -88,22 +88,36 @@ class ProjectMeasure < ActiveRecord::Base
end
end
- def formatted_variation_value(variation_index)
- variation=nil
+ def format_numeric_value(val)
+ if metric.nil?
+ return val.to_s
+ end
+
+ case metric().val_type
+ when Metric::VALUE_TYPE_INT
+ number_with_precision(val, :precision => 0)
+ when Metric::VALUE_TYPE_FLOAT
+ number_with_precision(val, :precision => 1)
+ when Metric::VALUE_TYPE_PERCENT
+ number_to_percentage(val, {:precision => 1})
+ when Metric::VALUE_TYPE_MILLISEC
+ millisecs_formatted_value( val )
+ else
+ val.to_s
+ end
+ end
+
+ def variation(variation_index)
+ result = nil
case variation_index
when 1
- variation=diff_value_1
+ result=diff_value_1
when 2
- variation=diff_value_2
+ result=diff_value_2
when 3
- variation=diff_value_3
- end
- if variation
- label=format_numeric_value(variation)
- variation<0 ? label : "+#{label}"
- else
- nil
+ result=diff_value_3
end
+ result
end
def millisecs_formatted_value( value )
@@ -277,8 +291,6 @@ class ProjectMeasure < ActiveRecord::Base
end
end
-
-
def <=>(other)
return value<=>other.value
end
@@ -289,26 +301,6 @@ class ProjectMeasure < ActiveRecord::Base
[Metric::VALUE_TYPE_INT, Metric::VALUE_TYPE_FLOAT, Metric::VALUE_TYPE_PERCENT, Metric::VALUE_TYPE_MILLISEC].include?(metric.val_type)
end
-
- def format_numeric_value(val)
- if metric.nil?
- return val.to_s
- end
-
- case metric().val_type
- when Metric::VALUE_TYPE_INT
- number_with_precision(val, :precision => 0)
- when Metric::VALUE_TYPE_FLOAT
- number_with_precision(val, :precision => 1)
- when Metric::VALUE_TYPE_PERCENT
- number_to_percentage(val, {:precision => 1})
- when Metric::VALUE_TYPE_MILLISEC
- millisecs_formatted_value( val )
- else
- val.to_s
- end
- end
-
def validate_date
if not measure_date
errors.add_to_base('A valid date must be provided')
diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/150_add_plugins_child_first_classloader_column.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/150_add_plugins_child_first_classloader_column.rb
index 14842ab96a6..e16f0c6a6a9 100644
--- a/sonar-server/src/main/webapp/WEB-INF/db/migrate/150_add_plugins_child_first_classloader_column.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/db/migrate/150_add_plugins_child_first_classloader_column.rb
@@ -17,6 +17,10 @@
# License along with Sonar; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
#
+
+#
+# Sonar 2.4
+#
class AddPluginsChildFirstClassloaderColumn < ActiveRecord::Migration
def self.up
diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/151_create_dashboards.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/151_create_dashboards.rb
index f1c3fcbe8f6..4ee855ea473 100644
--- a/sonar-server/src/main/webapp/WEB-INF/db/migrate/151_create_dashboards.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/db/migrate/151_create_dashboards.rb
@@ -18,6 +18,9 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
#
+#
+# Sonar 2.4
+#
class CreateDashboards < ActiveRecord::Migration
def self.up
diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/152_delete_duplicated_lib_snapshots.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/152_delete_duplicated_lib_snapshots.rb
index d7b317bd3e1..f9906e36a8f 100644
--- a/sonar-server/src/main/webapp/WEB-INF/db/migrate/152_delete_duplicated_lib_snapshots.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/db/migrate/152_delete_duplicated_lib_snapshots.rb
@@ -17,6 +17,10 @@
# License along with Sonar; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
#
+
+#
+# Sonar 2.4
+#
class DeleteDuplicatedLibSnapshots < ActiveRecord::Migration
def self.up
metric=Metric.find(:first, :conditions => ['name=?','lines'])
diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/160_add_rule_failures_created_at_column.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/160_add_rule_failures_created_at_column.rb
index cf9d3189187..f5e0aea9860 100644
--- a/sonar-server/src/main/webapp/WEB-INF/db/migrate/160_add_rule_failures_created_at_column.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/db/migrate/160_add_rule_failures_created_at_column.rb
@@ -17,6 +17,10 @@
# License along with Sonar; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
#
+
+#
+# Sonar 2.5
+#
class AddRuleFailuresCreatedAtColumn < ActiveRecord::Migration
def self.up
diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/161_add_snapshots_var_columns.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/161_add_snapshots_var_columns.rb
index 8beb83d0cfb..7c18dd8ad0f 100644
--- a/sonar-server/src/main/webapp/WEB-INF/db/migrate/161_add_snapshots_var_columns.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/db/migrate/161_add_snapshots_var_columns.rb
@@ -17,6 +17,10 @@
# License along with Sonar; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
#
+
+#
+# Sonar 2.5
+#
class AddSnapshotsVarColumns < ActiveRecord::Migration
def self.up
diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/162_delete_iso_rule_categories.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/162_delete_iso_rule_categories.rb
index 8f1cf9c62a2..413b26a437d 100644
--- a/sonar-server/src/main/webapp/WEB-INF/db/migrate/162_delete_iso_rule_categories.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/db/migrate/162_delete_iso_rule_categories.rb
@@ -17,8 +17,13 @@
# License along with Sonar; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
#
+
+#
+# Sonar 2.5
+#
class DeleteIsoRuleCategories < ActiveRecord::Migration
+
def self.up
remove_rule_categories
delete_measures_on_iso_category
diff --git a/sonar-server/src/main/webapp/stylesheets/style.css b/sonar-server/src/main/webapp/stylesheets/style.css
index 53562ec76a9..2893e22bba3 100644
--- a/sonar-server/src/main/webapp/stylesheets/style.css
+++ b/sonar-server/src/main/webapp/stylesheets/style.css
@@ -881,6 +881,21 @@ ul.operations li a {
padding: 10px;
}
+
+/* ------------------- VARIATIONS ------------------- */
+.var {
+ font-weight: bold;
+ color: #005C9C !important;
+}
+.varb {/* better */
+ font-weight: bold;
+ color: #078C00 !important;
+}
+.varw {/* worst */
+ font-weight: bold;
+ color: #cc0000 !important;
+}
+
/* ------------------- HELP ------------------- */
.help {
border: 1px solid #ccc;
@@ -1303,7 +1318,7 @@ ul.bullet li {
div.barchart {
border: 0;
margin: 0;
- padding: 0 5px;
+ padding: 0;
float: left;
}
diff --git a/sonar-server/src/test/java/org/sonar/server/ui/ViewsTest.java b/sonar-server/src/test/java/org/sonar/server/ui/ViewsTest.java
index e1ae897c007..69584d249f0 100644
--- a/sonar-server/src/test/java/org/sonar/server/ui/ViewsTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/ui/ViewsTest.java
@@ -71,7 +71,7 @@ public class ViewsTest {
@Test
public void getWidgets() {
final Views views = new Views(VIEWS);
- List<ViewProxy<Widget>> widgets = views.getWidgets(null, null, null, false);
+ List<ViewProxy<Widget>> widgets = views.getWidgets(null, null, null);
assertThat(widgets.size(), is(1));
assertThat(widgets.get(0).getTarget(), is(FakeWidget.class));
}
@@ -79,7 +79,7 @@ public class ViewsTest {
@Test
public void sortViewsByTitle() {
final Views views = new Views(new View[]{new FakeWidget("ccc", "ccc"), new FakeWidget("aaa", "aaa"), new FakeWidget("bbb", "bbb")});
- List<ViewProxy<Widget>> widgets = views.getWidgets(null, null, null, false);
+ List<ViewProxy<Widget>> widgets = views.getWidgets(null, null, null);
assertThat(widgets.size(), is(3));
assertThat(widgets.get(0).getId(), is("aaa"));
assertThat(widgets.get(1).getId(), is("bbb"));
@@ -89,7 +89,7 @@ public class ViewsTest {
@Test
public void prefixTitleByNumberToDisplayFirst() {
final Views views = new Views(new View[]{new FakeWidget("other", "Other"), new FakeWidget("1id", "1widget"), new FakeWidget("2id", "2widget")});
- List<ViewProxy<Widget>> widgets = views.getWidgets(null, null, null, false);
+ List<ViewProxy<Widget>> widgets = views.getWidgets(null, null, null);
assertThat(widgets.size(), is(3));
assertThat(widgets.get(0).getId(), is("1id"));
assertThat(widgets.get(1).getId(), is("2id"));