]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-4333 Provide a new "Unresolved issue statuses" widget
authorJulien Lancelot <julien.lancelot@gmail.com>
Thu, 23 May 2013 12:43:30 +0000 (14:43 +0200)
committerJulien Lancelot <julien.lancelot@gmail.com>
Thu, 23 May 2013 12:43:30 +0000 (14:43 +0200)
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/ProjectIssuesDashboard.java
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/issues/UnresolvedIssuesStatusesWidget.java [new file with mode: 0644]
plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties
plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/issues/unresolved_issues_statuses.html.erb [new file with mode: 0644]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/dashboards/ProjectIssuesDashboardTest.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java

index cc3b9e380d26d3fbaa68826e67a8800882d5cdf3..826b347868939d2daac3848fe978c97ca261bbbf 100644 (file)
@@ -46,9 +46,7 @@ import org.sonar.plugins.core.web.Lcom4Viewer;
 import org.sonar.plugins.core.web.TestsViewer;
 import org.sonar.plugins.core.widgets.*;
 import org.sonar.plugins.core.widgets.issues.ActionPlansWidget;
-import org.sonar.plugins.core.widgets.issues.FalsePositiveIssuesWidget;
-import org.sonar.plugins.core.widgets.issues.MyUnresolvedIssuesWidget;
-import org.sonar.plugins.core.widgets.issues.UnresolvedIssuesPerAssigneeWidget;
+import org.sonar.plugins.core.widgets.issues.*;
 import org.sonar.plugins.core.widgets.reviews.*;
 
 import java.util.List;
@@ -418,6 +416,7 @@ public final class CorePlugin extends SonarPlugin {
       ActionPlansWidget.class,
       org.sonar.plugins.core.widgets.ActionPlansWidget.class,
       UnresolvedIssuesPerAssigneeWidget.class,
+      UnresolvedIssuesStatusesWidget.class,
 
       // batch
       ProfileSensor.class,
index 17daeadeec312e50d4b8c872b9a4df952a901c7c..0df89cb314f8415f8b6ad4b2e6810ef6697206e5 100644 (file)
@@ -45,7 +45,8 @@ public final class ProjectIssuesDashboard extends DashboardTemplate {
   }
 
   private void addFirstColumn(Dashboard dashboard) {
-    dashboard.addWidget("issues_action_plans", 1);
+    dashboard.addWidget("unresolved_issues_statuses", 1);
+    dashboard.addWidget("issues_action_plans", 2);
   }
 
   private void addSecondColumn(Dashboard dashboard) {
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/issues/UnresolvedIssuesStatusesWidget.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/issues/UnresolvedIssuesStatusesWidget.java
new file mode 100644 (file)
index 0000000..566c1d2
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.plugins.core.widgets.issues;
+
+import org.sonar.api.web.WidgetCategory;
+import org.sonar.plugins.core.widgets.CoreWidget;
+
+@WidgetCategory({"Issues"})
+public class UnresolvedIssuesStatusesWidget extends CoreWidget {
+  public UnresolvedIssuesStatusesWidget() {
+    super("unresolved_issues_statuses", "Unresolved issue statuses", "/org/sonar/plugins/core/widgets/issues/unresolved_issues_statuses.html.erb");
+  }
+}
index 5cf4f639a85452b8ed62138a1648c2a4a81add08..43e989126b63e03bdcf4429342998062e1b4f213 100644 (file)
@@ -1073,6 +1073,11 @@ widget.unresolved_issues_per_assignee.name=Unresolved issues per assignee
 widget.unresolved_issues_per_assignee.description=Shows the number of unresolved issues per assignee.
 widget.unresolved_issues_per_assignee.not_assigned=Not assigned
 
+widget.unresolved_issues_statuses.name=Unresolved issue statuses
+widget.unresolved_issues_statuses.description=Display the number of unresolved issues according to their status : Open, Reopen and Accepted.
+widget.unresolved_issues_statuses.added=Added:
+widget.unresolved_issues_statuses.removed=Removed:
+
 widget.action_plans.name=Action plans
 widget.action_plans.description=Shows all the open action plans of the project
 widget.action_plans.property.showClosedReviews.name=Show Closed Reviews
diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/issues/unresolved_issues_statuses.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/issues/unresolved_issues_statuses.html.erb
new file mode 100644 (file)
index 0000000..255ea17
--- /dev/null
@@ -0,0 +1,58 @@
+<%
+   issues = @snapshot.measure('violations')
+   open_issues = @snapshot.measure('open_issues')
+   reopened_issues = @snapshot.measure('reopened_issues')
+   confirmed_issues = @snapshot.measure('confirmed_issues')
+
+   issues_search_options = {}
+   issues_search_options['resolved'] = 'false'
+   issues_search_options['componentRoots'] = @project.key
+%>
+<table width="100%">
+  <tr>
+    <td valign="top" width="25%">
+      <div class="dashbox">
+        <h3><%= message('issues') -%></h3>
+        <div class="marginbottom10">
+          <span class="big">
+            <%= format_measure(issues, :url => url_for({:controller => 'issues', :action => 'search' }.merge(issues_search_options))) -%>
+          </span>
+          <%= dashboard_configuration.selected_period? ? format_variation(issues) : trend_icon(issues) -%>
+        </div>
+      </div>
+    </td>
+    <td valign="top" width="25%">
+      <div class="dashbox">
+        <h3><%= message('issue.status.OPEN') -%></h3>
+        <div class="marginbottom10">
+          <span class="big">
+            <%= format_measure(open_issues, :url => url_for({:controller => 'issues', :action => 'search', :statuses => 'OPEN'}.merge(issues_search_options))) -%>
+          </span>
+          <%= dashboard_configuration.selected_period? ? format_variation(open_issues) : trend_icon(open_issues) -%>
+        </div>
+      </div>
+    </td>
+    <td valign="top" width="25%">
+      <div class="dashbox">
+        <h3><%= message('issue.status.REOPENED') -%></h3>
+        <div class="marginbottom10">
+          <span class="big">
+            <%= format_measure(reopened_issues, :url => url_for({:controller => 'issues', :action => 'search', :statuses => 'REOPENED'}.merge(issues_search_options))) -%>
+          </span>
+          <%= dashboard_configuration.selected_period? ? format_variation(reopened_issues) : trend_icon(reopened_issues) -%>
+        </div>
+      </div>
+    </td>
+    <td valign="top" width="25%">
+      <div class="dashbox">
+        <h3><%= message('issue.status.CONFIRMED') -%></h3>
+        <div class="marginbottom10">
+          <span class="big">
+            <%= format_measure(confirmed_issues, :url => url_for({:controller => 'issues', :action => 'search', :statuses => 'CONFIRMED'}.merge(issues_search_options))) -%>
+          </span>
+          <%= dashboard_configuration.selected_period? ? format_variation(confirmed_issues) : trend_icon(confirmed_issues) -%>
+        </div>
+      </div>
+    </td>
+ </tr>
+</table>
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/dashboards/ProjectIssuesDashboardTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/dashboards/ProjectIssuesDashboardTest.java
new file mode 100644 (file)
index 0000000..65e9e31
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.plugins.core.dashboards;
+
+import org.junit.Test;
+import org.sonar.api.web.Dashboard;
+import org.sonar.api.web.DashboardLayout;
+import org.sonar.plugins.core.CorePlugin;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class ProjectIssuesDashboardTest {
+
+  ProjectIssuesDashboard template = new ProjectIssuesDashboard();
+
+  @Test
+  public void should_have_a_name() {
+    assertThat(template.getName()).isEqualTo("Issues");
+  }
+
+  @Test
+  public void should_be_registered_as_an_extension() {
+    assertThat(new CorePlugin().getExtensions()).contains(template.getClass());
+  }
+
+  @Test
+  public void should_create_dashboard() {
+    Dashboard dashboard = template.createDashboard();
+
+    assertThat(dashboard.getLayout()).isEqualTo(DashboardLayout.TWO_COLUMNS);
+    assertThat(dashboard.getWidgets()).hasSize(5);
+  }
+
+}
index 17fc013a30ede1d93b264fe74072bbee99e4c2de..f72770aa2bd8f440a70fd3d2e49295c7fab1da35 100644 (file)
@@ -1848,7 +1848,6 @@ public final class CoreMetrics {
     .setDomain(DOMAIN_ISSUES)
     .setBestValue(0.0)
     .setOptimizedBestValue(true)
-    .setDeleteHistoricalData(true)
     .create();
 
   /**
@@ -1866,7 +1865,6 @@ public final class CoreMetrics {
     .setDomain(DOMAIN_ISSUES)
     .setBestValue(0.0)
     .setOptimizedBestValue(true)
-    .setDeleteHistoricalData(true)
     .create();