aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/pom.xml2
-rw-r--r--server/sonar-ce/pom.xml5
-rw-r--r--server/sonar-plugin-bridge/pom.xml2
-rw-r--r--server/sonar-process-monitor/pom.xml2
-rw-r--r--server/sonar-process/pom.xml5
-rw-r--r--server/sonar-search/pom.xml2
-rw-r--r--server/sonar-server-benchmarks/pom.xml2
-rw-r--r--server/sonar-server/pom.xml2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/activity/index/ActivityIndexDefinition.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/es/NewIndex.java16
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleDoc.java12
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndex.java10
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndexDefinition.java7
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndexer.java13
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleResultSetIterator.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/test/index/TestIndexDefinition.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/user/index/UserIndexDefinition.java5
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/view/index/ViewIndexDefinition.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/es/NewIndexTest.java8
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleDocTesting.java4
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java24
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleResultSetIteratorTest.java3
-rw-r--r--server/sonar-web/.gitignore1
-rw-r--r--server/sonar-web/package.json19
-rw-r--r--server/sonar-web/pom.xml2
-rw-r--r--server/sonar-web/src/main/js/api/components.js2
-rw-r--r--server/sonar-web/src/main/js/apps/code/actions/index.js54
-rw-r--r--server/sonar-web/src/main/js/apps/code/components/Code.js22
-rw-r--r--server/sonar-web/src/main/js/apps/code/reducers/index.js23
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js20
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/details/treemap/MeasureTreemap.js2
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/home/MeasureListValue.js2
-rw-r--r--server/sonar-web/src/main/js/apps/overview/main/code-smells.js13
-rw-r--r--server/sonar-web/src/main/js/apps/overview/main/coverage.js29
-rw-r--r--server/sonar-web/src/main/js/apps/overview/main/duplications.js13
-rw-r--r--server/sonar-web/src/main/js/apps/overview/main/risk.js19
-rw-r--r--server/sonar-web/src/main/js/apps/overview/main/structure.js13
-rw-r--r--server/sonar-web/src/main/less/pages/overview.less10
-rw-r--r--server/sonar-web/tests/apps/code/store-test.js11
40 files changed, 195 insertions, 194 deletions
diff --git a/server/pom.xml b/server/pom.xml
index 0802fb2eb61..f3870836960 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>sonarqube</artifactId>
- <version>5.5-SNAPSHOT</version>
+ <version>5.6-SNAPSHOT</version>
</parent>
<artifactId>server</artifactId>
<packaging>pom</packaging>
diff --git a/server/sonar-ce/pom.xml b/server/sonar-ce/pom.xml
index 3cc82fe4971..6c05fcfb0c5 100644
--- a/server/sonar-ce/pom.xml
+++ b/server/sonar-ce/pom.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>server</artifactId>
- <version>5.5-SNAPSHOT</version>
+ <version>5.6-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>sonar-ce</artifactId>
diff --git a/server/sonar-plugin-bridge/pom.xml b/server/sonar-plugin-bridge/pom.xml
index 5c23d7a334e..403e6e6f40c 100644
--- a/server/sonar-plugin-bridge/pom.xml
+++ b/server/sonar-plugin-bridge/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>server</artifactId>
- <version>5.5-SNAPSHOT</version>
+ <version>5.6-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>sonar-plugin-bridge</artifactId>
diff --git a/server/sonar-process-monitor/pom.xml b/server/sonar-process-monitor/pom.xml
index fcf9eb90795..700d81b27ff 100644
--- a/server/sonar-process-monitor/pom.xml
+++ b/server/sonar-process-monitor/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>server</artifactId>
- <version>5.5-SNAPSHOT</version>
+ <version>5.6-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
diff --git a/server/sonar-process/pom.xml b/server/sonar-process/pom.xml
index 55bcc49a5aa..5160d85ce29 100644
--- a/server/sonar-process/pom.xml
+++ b/server/sonar-process/pom.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>server</artifactId>
- <version>5.5-SNAPSHOT</version>
+ <version>5.6-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
diff --git a/server/sonar-search/pom.xml b/server/sonar-search/pom.xml
index cfd210e2c4f..265c778b4e2 100644
--- a/server/sonar-search/pom.xml
+++ b/server/sonar-search/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>server</artifactId>
- <version>5.5-SNAPSHOT</version>
+ <version>5.6-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
diff --git a/server/sonar-server-benchmarks/pom.xml b/server/sonar-server-benchmarks/pom.xml
index 087d3b832e6..8a719786008 100644
--- a/server/sonar-server-benchmarks/pom.xml
+++ b/server/sonar-server-benchmarks/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>server</artifactId>
- <version>5.5-SNAPSHOT</version>
+ <version>5.6-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>sonar-server-benchmarks</artifactId>
diff --git a/server/sonar-server/pom.xml b/server/sonar-server/pom.xml
index 12253497147..b6f8024dc19 100644
--- a/server/sonar-server/pom.xml
+++ b/server/sonar-server/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>server</artifactId>
- <version>5.5-SNAPSHOT</version>
+ <version>5.6-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>sonar-server</artifactId>
diff --git a/server/sonar-server/src/main/java/org/sonar/server/activity/index/ActivityIndexDefinition.java b/server/sonar-server/src/main/java/org/sonar/server/activity/index/ActivityIndexDefinition.java
index 4000f61afe0..be4f363d486 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/activity/index/ActivityIndexDefinition.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/activity/index/ActivityIndexDefinition.java
@@ -49,7 +49,7 @@ public class ActivityIndexDefinition implements IndexDefinition {
public void define(IndexDefinitionContext context) {
NewIndex index = context.create(INDEX);
index.getSettings().put("analysis.analyzer.default.type", "keyword");
- index.setShards(settings);
+ index.configureShards(settings);
index.refreshHandledByIndexer();
// type "activity"
diff --git a/server/sonar-server/src/main/java/org/sonar/server/es/NewIndex.java b/server/sonar-server/src/main/java/org/sonar/server/es/NewIndex.java
index ed516719329..668f838df7d 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/es/NewIndex.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/es/NewIndex.java
@@ -146,7 +146,6 @@ public class NewIndex {
private final NewIndexType indexType;
private final NewIndexType nestedType;
private final String fieldName;
- private boolean dynamic = false;
public NestedObjectBuilder(NewIndexType indexType, NewIndexType nestedType, String fieldName) {
this.indexType = indexType;
@@ -154,18 +153,9 @@ public class NewIndex {
this.fieldName = fieldName;
}
- public NestedObjectBuilder dynamic() {
- this.dynamic = true;
- return this;
- }
-
public void build() {
- if (dynamic) {
- indexType.setProperty(fieldName, ImmutableMap.of("type", "nested", "dynamic", "true"));
- } else {
- nestedType.setAttribute("type", "nested");
- indexType.setProperty(fieldName, nestedType.attributes);
- }
+ nestedType.setAttribute("type", "nested");
+ indexType.setProperty(fieldName, nestedType.attributes);
}
}
@@ -314,7 +304,7 @@ public class NewIndex {
return types;
}
- public void setShards(Settings settings) {
+ public void configureShards(Settings settings) {
boolean clusterMode = settings.getBoolean(ProcessProperties.CLUSTER_ACTIVATE);
int shards = settings.getInt(format("sonar.search.%s.shards", indexName));
if (shards == 0) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java
index 224556589c2..9194033d447 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java
@@ -91,7 +91,7 @@ public class IssueIndexDefinition implements IndexDefinition {
NewIndex index = context.create(INDEX);
index.refreshHandledByIndexer();
- index.setShards(settings);
+ index.configureShards(settings);
// type "authorization"
NewIndex.NewIndexType authorizationMapping = index.createType(TYPE_AUTHORIZATION);
diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleDoc.java b/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleDoc.java
index 93d33fc7ac8..a2908fb8e6f 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleDoc.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleDoc.java
@@ -19,9 +19,7 @@
*/
package org.sonar.server.rule.index;
-import com.google.common.annotations.VisibleForTesting;
import java.util.Collection;
-import java.util.List;
import java.util.Map;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
@@ -49,16 +47,6 @@ public class RuleDoc extends BaseDoc {
return this;
}
- @VisibleForTesting
- List<String> keyAsList() {
- return (List<String>) getField(RuleIndexDefinition.FIELD_RULE_KEY_AS_LIST);
- }
-
- public RuleDoc setKeyAsList(@Nullable List<String> s) {
- setField(RuleIndexDefinition.FIELD_RULE_KEY_AS_LIST, s);
- return this;
- }
-
@CheckForNull
public String ruleKey() {
return getNullableField(RuleIndexDefinition.FIELD_RULE_RULE_KEY);
diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndex.java b/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndex.java
index 47ab72986d0..7e7fccfc38b 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndex.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndex.java
@@ -66,6 +66,8 @@ import org.sonar.server.es.SearchIdResult;
import org.sonar.server.es.SearchOptions;
import org.sonar.server.search.StickyFacetBuilder;
+import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
+import static org.elasticsearch.index.query.QueryBuilders.simpleQueryStringQuery;
import static org.sonar.server.es.EsUtils.SCROLL_TIME_IN_MINUTES;
import static org.sonar.server.es.EsUtils.scrollIds;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_INHERITANCE;
@@ -77,7 +79,6 @@ import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_HTML_DE
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_INTERNAL_KEY;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_IS_TEMPLATE;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_KEY;
-import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_KEY_AS_LIST;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_LANGUAGE;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_NAME;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_REPOSITORY;
@@ -177,15 +178,16 @@ public class RuleIndex extends BaseIndex {
String queryString = query.getQueryText();
// Human readable type of querying
- qb.should(QueryBuilders.simpleQueryStringQuery(query.getQueryText())
+ qb.should(simpleQueryStringQuery(query.getQueryText())
.field(FIELD_RULE_NAME + "." + SEARCH_WORDS_SUFFIX, 20f)
.field(FIELD_RULE_HTML_DESCRIPTION + "." + SEARCH_WORDS_SUFFIX, 3f)
.defaultOperator(SimpleQueryStringBuilder.Operator.AND)
).boost(20f);
// Match and partial Match queries
- qb.should(termQuery(FIELD_RULE_KEY, queryString, 15f));
- qb.should(termQuery(FIELD_RULE_KEY_AS_LIST, queryString, 35f));
+ // Search by key uses the "sortable" sub-field as it requires to be case-insensitive (lower-case filtering)
+ qb.should(matchQuery(FIELD_RULE_KEY + "." + SORT_SUFFIX, queryString).operator(MatchQueryBuilder.Operator.AND).boost(30f));
+ qb.should(matchQuery(FIELD_RULE_RULE_KEY + "." + SORT_SUFFIX, queryString).operator(MatchQueryBuilder.Operator.AND).boost(15f));
qb.should(termQuery(FIELD_RULE_LANGUAGE, queryString, 3f));
qb.should(termQuery(FIELD_RULE_ALL_TAGS, queryString, 10f));
qb.should(termAnyQuery(FIELD_RULE_ALL_TAGS, queryString, 1f));
diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndexDefinition.java b/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndexDefinition.java
index 30a0437004e..87ea1ae7a28 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndexDefinition.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndexDefinition.java
@@ -35,8 +35,6 @@ public class RuleIndexDefinition implements IndexDefinition {
public static final String TYPE_RULE = "rule";
public static final String FIELD_RULE_KEY = "key";
- // TODO find at what this field is useful ?
- public static final String FIELD_RULE_KEY_AS_LIST = "_key";
public static final String FIELD_RULE_REPOSITORY = "repo";
public static final String FIELD_RULE_RULE_KEY = "ruleKey";
public static final String FIELD_RULE_INTERNAL_KEY = "internalKey";
@@ -83,7 +81,7 @@ public class RuleIndexDefinition implements IndexDefinition {
NewIndex index = context.create(INDEX);
index.refreshHandledByIndexer();
- index.setShards(settings);
+ index.configureShards(settings);
// Rule type
NewIndex.NewIndexType ruleMapping = index.createType(TYPE_RULE);
@@ -92,8 +90,7 @@ public class RuleIndexDefinition implements IndexDefinition {
ruleMapping.setEnableSource(false);
ruleMapping.stringFieldBuilder(FIELD_RULE_KEY).enableSorting().build();
- ruleMapping.stringFieldBuilder(FIELD_RULE_KEY_AS_LIST).build();
- ruleMapping.stringFieldBuilder(FIELD_RULE_RULE_KEY).disableSearch().docValues().build();
+ ruleMapping.stringFieldBuilder(FIELD_RULE_RULE_KEY).enableSorting().build();
ruleMapping.stringFieldBuilder(FIELD_RULE_REPOSITORY).docValues().build();
ruleMapping.stringFieldBuilder(FIELD_RULE_INTERNAL_KEY).disableSearch().docValues().build();
diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndexer.java b/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndexer.java
index 3cffbde5689..35da71cb5af 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndexer.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndexer.java
@@ -58,7 +58,7 @@ public class RuleIndexer extends BaseIndexer {
rowIt.close();
return maxDate;
} finally {
- dbSession.close();
+ dbClient.closeSession(dbSession);
}
}
@@ -67,11 +67,6 @@ public class RuleIndexer extends BaseIndexer {
long maxDate = 0L;
while (rules.hasNext()) {
RuleDoc rule = rules.next();
- // TODO when active rule is not more DAO v2, restore deleting of REMOVED rules and also remove active rules linked to this rule
- // if (rule.status() == RuleStatus.REMOVED) {
- // bulk.add(newDeleteRequest(rule));
- // } else {
- // }
bulk.add(newIndexRequest(rule));
// it's more efficient to sort programmatically than in SQL on some databases (MySQL for instance)
@@ -92,10 +87,4 @@ public class RuleIndexer extends BaseIndexer {
.routing(rule.repository())
.source(rule.getFields());
}
-
- // private DeleteRequest newDeleteRequest(RuleDoc rule) {
- // return new DeleteRequest(INDEX, TYPE_RULE, rule.key().toString())
- // .routing(rule.repository());
- // }
-
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleResultSetIterator.java b/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleResultSetIterator.java
index 09d2ad17a8e..1ac41b290a6 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleResultSetIterator.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleResultSetIterator.java
@@ -20,7 +20,6 @@
package org.sonar.server.rule.index;
import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
@@ -101,7 +100,6 @@ public class RuleResultSetIterator extends ResultSetIterator<RuleDoc> {
// all the fields must be present, even if value is null
doc.setKey(key.toString());
- doc.setKeyAsList(ImmutableList.of(repositoryKey, ruleKey));
doc.setRuleKey(ruleKey);
doc.setRepository(repositoryKey);
doc.setName(rs.getString(3));
diff --git a/server/sonar-server/src/main/java/org/sonar/server/test/index/TestIndexDefinition.java b/server/sonar-server/src/main/java/org/sonar/server/test/index/TestIndexDefinition.java
index fcf39c06197..eddab9581ed 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/test/index/TestIndexDefinition.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/test/index/TestIndexDefinition.java
@@ -51,7 +51,7 @@ public class TestIndexDefinition implements IndexDefinition {
NewIndex index = context.create(INDEX);
index.refreshHandledByIndexer();
- index.setShards(settings);
+ index.configureShards(settings);
NewIndex.NewIndexType nestedMapping = index.createType(TYPE);
nestedMapping.stringFieldBuilder(FIELD_COVERED_FILE_UUID).build();
diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/index/UserIndexDefinition.java b/server/sonar-server/src/main/java/org/sonar/server/user/index/UserIndexDefinition.java
index 62b01fa9dc2..0b5600b34b1 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/user/index/UserIndexDefinition.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/user/index/UserIndexDefinition.java
@@ -21,12 +21,11 @@ package org.sonar.server.user.index;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedMap;
+import java.util.SortedMap;
import org.sonar.api.config.Settings;
import org.sonar.server.es.IndexDefinition;
import org.sonar.server.es.NewIndex;
-import java.util.SortedMap;
-
/**
* Definition of ES index "users", including settings and fields.
*/
@@ -56,7 +55,7 @@ public class UserIndexDefinition implements IndexDefinition {
public void define(IndexDefinitionContext context) {
NewIndex index = context.create(INDEX);
- index.setShards(settings);
+ index.configureShards(settings);
index.getSettings()
// NGram filter (not edge) for logins and names
diff --git a/server/sonar-server/src/main/java/org/sonar/server/view/index/ViewIndexDefinition.java b/server/sonar-server/src/main/java/org/sonar/server/view/index/ViewIndexDefinition.java
index c229004d985..90dc408de33 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/view/index/ViewIndexDefinition.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/view/index/ViewIndexDefinition.java
@@ -46,7 +46,7 @@ public class ViewIndexDefinition implements IndexDefinition {
public void define(IndexDefinitionContext context) {
NewIndex index = context.create(INDEX);
- index.setShards(settings);
+ index.configureShards(settings);
// type "view"
NewIndex.NewIndexType mapping = index.createType(TYPE_VIEW);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/es/NewIndexTest.java b/server/sonar-server/src/test/java/org/sonar/server/es/NewIndexTest.java
index e8ee95c0c1b..b8c2a790bd3 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/es/NewIndexTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/es/NewIndexTest.java
@@ -149,7 +149,7 @@ public class NewIndexTest {
@Test
public void default_shards_and_replicas() {
NewIndex index = new NewIndex("issues");
- index.setShards(new org.sonar.api.config.Settings());
+ index.configureShards(new org.sonar.api.config.Settings());
assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_SHARDS)).isEqualTo(String.valueOf(NewIndex.DEFAULT_NUMBER_OF_SHARDS));
assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_REPLICAS)).isEqualTo("0");
}
@@ -159,7 +159,7 @@ public class NewIndexTest {
NewIndex index = new NewIndex("issues");
org.sonar.api.config.Settings settings = new org.sonar.api.config.Settings();
settings.setProperty("sonar.cluster.activate", "true");
- index.setShards(settings);
+ index.configureShards(settings);
assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_SHARDS)).isEqualTo(String.valueOf(NewIndex.DEFAULT_NUMBER_OF_SHARDS));
assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_REPLICAS)).isEqualTo("1");
}
@@ -169,7 +169,7 @@ public class NewIndexTest {
NewIndex index = new NewIndex("issues");
org.sonar.api.config.Settings settings = new org.sonar.api.config.Settings();
settings.setProperty("sonar.search.issues.shards", "3");
- index.setShards(settings);
+ index.configureShards(settings);
assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_SHARDS)).isEqualTo("3");
// keep default value
assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_REPLICAS)).isEqualTo("0");
@@ -181,7 +181,7 @@ public class NewIndexTest {
org.sonar.api.config.Settings settings = new org.sonar.api.config.Settings();
settings.setProperty("sonar.search.issues.shards", "3");
settings.setProperty("sonar.search.issues.replicas", "1");
- index.setShards(settings);
+ index.configureShards(settings);
assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_SHARDS)).isEqualTo("3");
assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_REPLICAS)).isEqualTo("1");
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleDocTesting.java b/server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleDocTesting.java
index 57d7ba5b965..773e7d31cdd 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleDocTesting.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleDocTesting.java
@@ -46,7 +46,7 @@ public class RuleDocTesting {
.setIsTemplate(false)
.setAllTags(Arrays.asList("spring", "performance"))
.setType(RuleType.CODE_SMELL)
- .setCreatedAt(150000000L)
- .setUpdatedAt(160000000L);
+ .setCreatedAt(1_500_000_000L)
+ .setUpdatedAt(1_600_000_000L);
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java
index 3241bb115a8..6ac245f2339 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java
@@ -103,15 +103,18 @@ public class RuleIndexTest {
}
@Test
- public void search_key_by_query() {
+ public void search_by_key() {
+ RuleKey js1 = RuleKey.of("javascript", "X001");
+ RuleKey cobol1 = RuleKey.of("cobol", "X001");
+ RuleKey php2 = RuleKey.of("php", "S002");
indexRules(
- newDoc(RuleKey.of("javascript", "X001")),
- newDoc(RuleKey.of("cobol", "X001")),
- newDoc(RuleKey.of("php", "S002")));
+ newDoc(js1).setName("First rule").setHtmlDescription("The first rule"),
+ newDoc(cobol1).setName("Second rule").setHtmlDescription("The second rule"),
+ newDoc(php2).setName("Third rule").setHtmlDescription("The third rule"));
// key
RuleQuery query = new RuleQuery().setQueryText("X001");
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
+ assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(js1, cobol1);
// partial key does not match
query = new RuleQuery().setQueryText("X00");
@@ -119,7 +122,16 @@ public class RuleIndexTest {
// repo:key -> nice-to-have !
query = new RuleQuery().setQueryText("javascript:X001");
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(1);
+ assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(js1);
+ }
+
+ @Test
+ public void search_by_case_insensitive_key() {
+ RuleKey ruleKey = RuleKey.of("javascript", "X001");
+ indexRules(newDoc(ruleKey).setName("Name without key").setHtmlDescription("Description without key"));
+
+ RuleQuery query = new RuleQuery().setQueryText("x001");
+ assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(ruleKey);
}
@Test
diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleResultSetIteratorTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleResultSetIteratorTest.java
index 48d6fe66c6f..7f8825a01f6 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleResultSetIteratorTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleResultSetIteratorTest.java
@@ -99,7 +99,6 @@ public class RuleResultSetIteratorTest {
RuleDoc rule = rulesByKey.get(templateRule.getRuleKey());
assertThat(rule).isNotNull();
assertThat(rule.key()).isEqualTo(RuleKey.of("xoo", "S001"));
- assertThat(rule.keyAsList()).containsOnly("xoo", "S001");
assertThat(rule.ruleKey()).isEqualTo("S001");
assertThat(rule.repository()).isEqualTo("xoo");
assertThat(rule.internalKey()).isEqualTo("S1");
@@ -144,7 +143,6 @@ public class RuleResultSetIteratorTest {
RuleDoc rule = rulesByKey.get(templateRule.getRuleKey());
assertThat(rule.key()).isEqualTo(RuleKey.of("xoo", "S001"));
- assertThat(rule.keyAsList()).containsOnly("xoo", "S001");
assertThat(rule.ruleKey()).isEqualTo("S001");
assertThat(rule.repository()).isEqualTo("xoo");
assertThat(rule.internalKey()).isEqualTo("S1");
@@ -160,7 +158,6 @@ public class RuleResultSetIteratorTest {
rule = rulesByKey.get(customRule.getRuleKey());
assertThat(rule.key()).isEqualTo(RuleKey.of("xoo", "S002"));
- assertThat(rule.keyAsList()).containsOnly("xoo", "S002");
assertThat(rule.ruleKey()).isEqualTo("S002");
assertThat(rule.repository()).isEqualTo("xoo");
assertThat(rule.internalKey()).isEqualTo("S2");
diff --git a/server/sonar-web/.gitignore b/server/sonar-web/.gitignore
index fe6eb9d4c35..44adb93a2a6 100644
--- a/server/sonar-web/.gitignore
+++ b/server/sonar-web/.gitignore
@@ -6,6 +6,7 @@ node_modules/
# npm logs
npm-debug.log.*
+npm.tar.gz
# build
build/
diff --git a/server/sonar-web/package.json b/server/sonar-web/package.json
index 7393b7bc96a..4f9f7f1d1b7 100644
--- a/server/sonar-web/package.json
+++ b/server/sonar-web/package.json
@@ -25,7 +25,7 @@
"css-loader": "0.23.1",
"d3": "3.5.6",
"del": "2.0.2",
- "enzyme": "1.2.0",
+ "enzyme": "2.2.0",
"eslint": "2.2.0",
"eslint-plugin-import": "^1.4.0",
"eslint-plugin-react": "4.0.0",
@@ -55,14 +55,15 @@
"moment": "2.10.6",
"numeral": "1.5.3",
"postcss-loader": "0.8.0",
- "react": "0.14.2",
- "react-addons-perf": "0.14.2",
- "react-addons-test-utils": "0.14.2",
- "react-dom": "0.14.2",
- "react-redux": "4.0.1",
- "react-router": "2.0.0",
- "react-router-redux": "4.0.0",
- "react-select": "1.0.0-beta6",
+ "react": "15.0.1",
+ "react-addons-perf": "15.0.1",
+ "react-addons-shallow-compare": "15.0.1",
+ "react-addons-test-utils": "15.0.1",
+ "react-dom": "15.0.1",
+ "react-redux": "4.4.1",
+ "react-router": "2.0.1",
+ "react-router-redux": "4.0.2",
+ "react-select": "1.0.0-beta12",
"react-transform-hmr": "1.0.4",
"redux": "3.3.1",
"redux-logger": "2.2.1",
diff --git a/server/sonar-web/pom.xml b/server/sonar-web/pom.xml
index 9f9dcad8a3f..8d46ea922fd 100644
--- a/server/sonar-web/pom.xml
+++ b/server/sonar-web/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>server</artifactId>
- <version>5.5-SNAPSHOT</version>
+ <version>5.6-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>sonar-web</artifactId>
diff --git a/server/sonar-web/src/main/js/api/components.js b/server/sonar-web/src/main/js/api/components.js
index ac53aaf2ab3..934d7a9c1bb 100644
--- a/server/sonar-web/src/main/js/api/components.js
+++ b/server/sonar-web/src/main/js/api/components.js
@@ -55,7 +55,7 @@ export function getComponentTree (strategy, componentKey, metrics = [], addition
}
export function getChildren (componentKey, metrics, additional) {
- return getComponentTree('children', componentKey, metrics, additional).then(r => r.components);
+ return getComponentTree('children', componentKey, metrics, additional);
}
export function getComponentLeaves (componentKey, metrics, additional) {
diff --git a/server/sonar-web/src/main/js/apps/code/actions/index.js b/server/sonar-web/src/main/js/apps/code/actions/index.js
index fc143fa1ec1..2422d993362 100644
--- a/server/sonar-web/src/main/js/apps/code/actions/index.js
+++ b/server/sonar-web/src/main/js/apps/code/actions/index.js
@@ -40,8 +40,11 @@ const METRICS_WITH_COVERAGE = [
'overall_coverage'
];
+const PAGE_SIZE = 100;
+
export const INIT = 'INIT';
export const BROWSE = 'BROWSE';
+export const LOAD_MORE = 'LOAD_MORE';
export const SEARCH = 'SEARCH';
export const SELECT_NEXT = 'SELECT_NEXT';
export const SELECT_PREV = 'SELECT_PREV';
@@ -58,12 +61,21 @@ export function initComponentAction (component, breadcrumbs = []) {
};
}
-export function browseAction (component, children = [], breadcrumbs = []) {
+export function browseAction (component, children = [], breadcrumbs = [], total = 0) {
return {
type: BROWSE,
component,
children,
- breadcrumbs
+ breadcrumbs,
+ total
+ };
+}
+
+export function loadMoreAction (children, page) {
+ return {
+ type: LOAD_MORE,
+ children,
+ page
};
}
@@ -108,17 +120,23 @@ function getPath (componentKey) {
return '/' + encodeURIComponent(componentKey);
}
-function expandRootDir (components) {
- const rootDir = components.find(component => component.qualifier === 'DIR' && component.name === '/');
+function expandRootDir ({ children, total, ...other }) {
+ const rootDir = children.find(component => component.qualifier === 'DIR' && component.name === '/');
if (rootDir) {
- return getChildren(rootDir.key, METRICS_WITH_COVERAGE).then(files => {
- return _.without([...components, ...files], rootDir);
+ return getChildren(rootDir.key, METRICS_WITH_COVERAGE).then(r => {
+ const nextChildren = _.without([...children, ...r.components], rootDir);
+ const nextTotal = total + r.components.length - /* root dir */ 1;
+ return { children: nextChildren, total: nextTotal, ...other };
});
} else {
- return components;
+ return { children, total, ...other };
}
}
+function prepareChildren (r) {
+ return { children: r.components, total: r.paging.total, page: r.paging.pageIndex };
+}
+
function skipRootDir (breadcrumbs) {
return breadcrumbs.filter(component => {
return !(component.qualifier === 'DIR' && component.name === '/');
@@ -133,8 +151,8 @@ function retrieveComponentBase (componentKey, candidate) {
function retrieveComponentChildren (componentKey, candidate) {
return candidate && candidate.children ?
- Promise.resolve(candidate.children) :
- getChildren(componentKey, METRICS_WITH_COVERAGE).then(expandRootDir);
+ Promise.resolve({ children: candidate.children, total: candidate.total }) :
+ getChildren(componentKey, METRICS_WITH_COVERAGE, { ps: PAGE_SIZE }).then(prepareChildren).then(expandRootDir);
}
function retrieveComponentBreadcrumbs (componentKey, candidate) {
@@ -195,7 +213,7 @@ export function browse (componentKey) {
window.location = getComponentUrl(component.refKey);
return new Promise();
} else {
- dispatch(browseAction(component, children, breadcrumbs));
+ dispatch(browseAction(component, children.children, breadcrumbs, children.total));
}
})
.then(() => dispatch(pushPath(getPath(componentKey))))
@@ -207,6 +225,22 @@ export function browse (componentKey) {
};
}
+export function loadMore () {
+ return (dispatch, getState) => {
+ const { baseComponent, page } = getState().current;
+ return getChildren(baseComponent.key, METRICS_WITH_COVERAGE, { p: page + 1, ps: PAGE_SIZE })
+ .then(prepareChildren)
+ .then(({ children }) => {
+ dispatch(loadMoreAction(children, page + 1));
+ dispatch(stopFetching());
+ })
+ .catch(e => {
+ getErrorMessage(e.response)
+ .then(message => dispatch(raiseError(message)));
+ });
+ };
+}
+
let debouncedSearch = function (query, baseComponent, dispatch) {
if (query) {
requestTree(query, baseComponent, dispatch);
diff --git a/server/sonar-web/src/main/js/apps/code/components/Code.js b/server/sonar-web/src/main/js/apps/code/components/Code.js
index 47e2e13cf2e..b8f63763f72 100644
--- a/server/sonar-web/src/main/js/apps/code/components/Code.js
+++ b/server/sonar-web/src/main/js/apps/code/components/Code.js
@@ -25,7 +25,8 @@ import Components from './Components';
import Breadcrumbs from './Breadcrumbs';
import SourceViewer from './SourceViewer';
import Search from './Search';
-import { initComponent, browse } from '../actions';
+import ListFooter from '../../../components/shared/list-footer';
+import { initComponent, browse, loadMore } from '../actions';
class Code extends Component {
componentDidMount () {
@@ -50,6 +51,11 @@ class Code extends Component {
dispatch(browse(component.key));
}
+ handleLoadMore () {
+ const { dispatch } = this.props;
+ dispatch(loadMore());
+ }
+
render () {
const {
fetching,
@@ -59,7 +65,9 @@ class Code extends Component {
sourceViewer,
coverageMetric,
searchResults,
- errorMessage } = this.props;
+ errorMessage,
+ total
+ } = this.props;
const shouldShowSearchResults = !!searchResults;
const shouldShowSourceViewer = !!sourceViewer;
const shouldShowComponents = !shouldShowSearchResults && !shouldShowSourceViewer && components;
@@ -109,6 +117,13 @@ class Code extends Component {
</div>
)}
+ {shouldShowComponents && (
+ <ListFooter
+ count={components.length}
+ total={total}
+ loadMore={this.handleLoadMore.bind(this)}/>
+ )}
+
{shouldShowSourceViewer && (
<div className="spacer-top">
<SourceViewer component={sourceViewer}/>
@@ -129,6 +144,7 @@ export default connect(state => {
sourceViewer: state.current.sourceViewer,
coverageMetric: state.current.coverageMetric,
searchResults: state.current.searchResults,
- errorMessage: state.current.errorMessage
+ errorMessage: state.current.errorMessage,
+ total: state.current.total
};
})(Code);
diff --git a/server/sonar-web/src/main/js/apps/code/reducers/index.js b/server/sonar-web/src/main/js/apps/code/reducers/index.js
index b76be02a510..f061926e0e4 100644
--- a/server/sonar-web/src/main/js/apps/code/reducers/index.js
+++ b/server/sonar-web/src/main/js/apps/code/reducers/index.js
@@ -19,8 +19,18 @@
*/
import _ from 'underscore';
-import { INIT, BROWSE, SEARCH, UPDATE_QUERY, SELECT_NEXT, SELECT_PREV, START_FETCHING, STOP_FETCHING,
- RAISE_ERROR } from '../actions';
+import {
+ INIT,
+ BROWSE,
+ LOAD_MORE,
+ SEARCH,
+ UPDATE_QUERY,
+ SELECT_NEXT,
+ SELECT_PREV,
+ START_FETCHING,
+ STOP_FETCHING,
+ RAISE_ERROR
+} from '../actions';
function hasSourceCode (component) {
return component.qualifier === 'FIL' || component.qualifier === 'UTS';
@@ -125,11 +135,19 @@ export function current (state = initialState, action) {
components,
breadcrumbs,
sourceViewer,
+ total: action.total,
+ page: 1,
searchResults: null,
searchQuery: '',
searchSelectedItem: null,
errorMessage: null
};
+ case LOAD_MORE:
+ return {
+ ...state,
+ components: sortChildren([...state.components, ...action.children]),
+ page: action.page
+ };
case SEARCH:
return {
...state,
@@ -172,6 +190,7 @@ export function bucket (state = [], action) {
case BROWSE:
const candidate = Object.assign({}, action.component, {
children: action.children,
+ total: action.total,
breadcrumbs: action.breadcrumbs
});
const nextState = merge(state, candidate);
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js b/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js
index 196b11e8d10..67bba2daf14 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js
+++ b/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js
@@ -69,23 +69,29 @@ export default ModalFormView.extend({
sendRequests (url, options, profiles) {
const that = this;
let looper = $.Deferred().resolve();
+ this.disableForm();
profiles.forEach(function (profile) {
const opts = _.extend({}, options, { profile_key: profile });
looper = looper.then(function () {
return $.post(url, opts).done(function (r) {
- if (r.failed) {
- that.showWarnMessage(profile, r.succeeded, r.failed);
- } else {
- that.showSuccessMessage(profile, r.succeeded);
+ if (!that.isDestroyed) {
+ if (r.failed) {
+ that.showWarnMessage(profile, r.succeeded, r.failed);
+ } else {
+ that.showSuccessMessage(profile, r.succeeded);
+ }
}
});
});
});
looper.done(function () {
that.options.app.controller.fetchList();
- that.$(that.ui.codingRulesSubmitBulkChange.selector).hide();
- that.$('.modal-field').hide();
- that.$('.js-modal-close').focus();
+ if (!that.isDestroyed) {
+ that.$(that.ui.codingRulesSubmitBulkChange.selector).hide();
+ that.enableForm();
+ that.$('.modal-field').hide();
+ that.$('.js-modal-close').focus();
+ }
});
},
diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/treemap/MeasureTreemap.js b/server/sonar-web/src/main/js/apps/component-measures/details/treemap/MeasureTreemap.js
index 92615167cc3..7b75d0b65f5 100644
--- a/server/sonar-web/src/main/js/apps/component-measures/details/treemap/MeasureTreemap.js
+++ b/server/sonar-web/src/main/js/apps/component-measures/details/treemap/MeasureTreemap.js
@@ -64,7 +64,7 @@ export default class MeasureTreemap extends React.Component {
};
return getChildren(componentKey, metrics, options).then(r => {
- const components = r.map(component => {
+ const components = r.components.map(component => {
const measures = {};
const key = component.refKey || component.key;
diff --git a/server/sonar-web/src/main/js/apps/component-measures/home/MeasureListValue.js b/server/sonar-web/src/main/js/apps/component-measures/home/MeasureListValue.js
index 3c61560f721..f53460afbd1 100644
--- a/server/sonar-web/src/main/js/apps/component-measures/home/MeasureListValue.js
+++ b/server/sonar-web/src/main/js/apps/component-measures/home/MeasureListValue.js
@@ -29,7 +29,7 @@ const MeasureListValue = ({ measure }) => {
if (isDiffMetric(metric)) {
return (
<div id={`measure-${measure.metric.key}-leak`} className="domain-measures-value domain-measures-leak">
- {formatMeasure(measure.leak, measure.metric.type)}
+ {formatMeasure(measure.leak, measure.metric.key)}
</div>
);
}
diff --git a/server/sonar-web/src/main/js/apps/overview/main/code-smells.js b/server/sonar-web/src/main/js/apps/overview/main/code-smells.js
index d731a4c84d8..95fae43f517 100644
--- a/server/sonar-web/src/main/js/apps/overview/main/code-smells.js
+++ b/server/sonar-web/src/main/js/apps/overview/main/code-smells.js
@@ -22,6 +22,7 @@ import React from 'react';
import {
Domain,
+ DomainHeader,
DomainPanel,
DomainNutshell,
DomainLeak,
@@ -90,17 +91,9 @@ export const CodeSmells = React.createClass({
const { snapshotDate } = this.props.component;
const formattedSnapshotDate = moment(snapshotDate).format('LLL');
- const domainUrl = window.baseUrl + '/component_measures/domain/Maintainability?id=' +
- encodeURIComponent(this.props.component.key);
-
return <Domain>
- <div className="overview-card-header">
- <div className="overview-title">
- <a href={domainUrl}>
- {translate('metric.code_smells.name')}
- </a>
- </div>
- </div>
+ <DomainHeader component={this.props.component}
+ title={translate('overview.domain.code_smells')}/>
<DomainPanel>
<DomainNutshell>
diff --git a/server/sonar-web/src/main/js/apps/overview/main/coverage.js b/server/sonar-web/src/main/js/apps/overview/main/coverage.js
index 4d619bbf379..8f7709438df 100644
--- a/server/sonar-web/src/main/js/apps/overview/main/coverage.js
+++ b/server/sonar-web/src/main/js/apps/overview/main/coverage.js
@@ -19,15 +19,14 @@
*/
import React from 'react';
-import {
- Domain,
- DomainPanel,
- DomainNutshell,
- DomainLeak,
- MeasuresList,
- Measure,
- DomainMixin
-} from './components';
+import { Domain,
+ DomainHeader,
+ DomainPanel,
+ DomainNutshell,
+ DomainLeak,
+ MeasuresList,
+ Measure,
+ DomainMixin } from './components';
import { DrilldownLink } from '../../../components/shared/drilldown-link';
import { TooltipsMixin } from '../../../components/mixins/tooltips-mixin';
import { DonutChart } from '../../../components/charts/donut-chart';
@@ -104,17 +103,9 @@ export const GeneralCoverage = React.createClass({
{ value: 100 - this.props.measures[coverageMetric], fill: '#d4333f' }
];
- const domainUrl = window.baseUrl + '/component_measures/domain/Tests?id=' +
- encodeURIComponent(this.props.component.key);
-
return <Domain>
- <div className="overview-card-header">
- <div className="overview-title">
- <a href={domainUrl}>
- {translate('metric.coverage.name')}
- </a>
- </div>
- </div>
+ <DomainHeader component={this.props.component}
+ title={translate('overview.domain.coverage')}/>
<DomainPanel>
<DomainNutshell>
diff --git a/server/sonar-web/src/main/js/apps/overview/main/duplications.js b/server/sonar-web/src/main/js/apps/overview/main/duplications.js
index 22162b18718..8077c4d97c4 100644
--- a/server/sonar-web/src/main/js/apps/overview/main/duplications.js
+++ b/server/sonar-web/src/main/js/apps/overview/main/duplications.js
@@ -20,6 +20,7 @@
import React from 'react';
import { Domain,
+ DomainHeader,
DomainPanel,
DomainNutshell,
DomainLeak,
@@ -74,17 +75,9 @@ export const GeneralDuplications = React.createClass({
{ value: Math.max(0, 20 - this.props.measures['duplicated_lines_density']), fill: '#e6e6e6' }
];
- const domainUrl = window.baseUrl + '/component_measures/domain/Duplication?id=' +
- encodeURIComponent(this.props.component.key);
-
return <Domain>
- <div className="overview-card-header">
- <div className="overview-title">
- <a href={domainUrl}>
- {translate('overview.domain.duplications')}
- </a>
- </div>
- </div>
+ <DomainHeader component={this.props.component}
+ title={translate('overview.domain.duplications')}/>
<DomainPanel>
<DomainNutshell>
diff --git a/server/sonar-web/src/main/js/apps/overview/main/risk.js b/server/sonar-web/src/main/js/apps/overview/main/risk.js
index d6942d02056..d6cf8f95e02 100644
--- a/server/sonar-web/src/main/js/apps/overview/main/risk.js
+++ b/server/sonar-web/src/main/js/apps/overview/main/risk.js
@@ -21,6 +21,7 @@ import moment from 'moment';
import React from 'react';
import {
+ DomainHeader,
DomainPanel,
DomainNutshell,
DomainLeak,
@@ -91,23 +92,9 @@ export const Risk = React.createClass({
const bugs = this.props.measures['bugs'] || 0;
const vulnerabilities = this.props.measures['vulnerabilities'] || 0;
- const bugsDomainUrl = window.baseUrl + '/component_measures/domain/Reliability?id=' +
- encodeURIComponent(this.props.component.key);
- const vulnerabilitiesDomainUrl = window.baseUrl + '/component_measures/domain/Security?id=' +
- encodeURIComponent(this.props.component.key);
-
return <div className="overview-card overview-card-special">
- <div className="overview-card-header">
- <div className="overview-title">
- <a href={bugsDomainUrl}>
- {translate('metric.bugs.name')}
- </a>
- {' & '}
- <a href={vulnerabilitiesDomainUrl}>
- {translate('metric.vulnerabilities.name')}
- </a>
- </div>
- </div>
+ <DomainHeader component={this.props.component}
+ title={translate('overview.domain.risk')}/>
<DomainPanel>
<DomainNutshell>
diff --git a/server/sonar-web/src/main/js/apps/overview/main/structure.js b/server/sonar-web/src/main/js/apps/overview/main/structure.js
index fe0e43bd5e1..2f431e63227 100644
--- a/server/sonar-web/src/main/js/apps/overview/main/structure.js
+++ b/server/sonar-web/src/main/js/apps/overview/main/structure.js
@@ -20,6 +20,7 @@
import React from 'react';
import { Domain,
+ DomainHeader,
DomainPanel,
DomainNutshell,
DomainLeak,
@@ -68,17 +69,9 @@ export const GeneralStructure = React.createClass({
},
render () {
- const domainUrl = window.baseUrl + '/component_measures/domain/Size?id=' +
- encodeURIComponent(this.props.component.key);
-
return <Domain>
- <div className="overview-card-header">
- <div className="overview-title">
- <a href={domainUrl}>
- {translate('overview.domain.structure')}
- </a>
- </div>
- </div>
+ <DomainHeader component={this.props.component}
+ title={translate('overview.domain.structure')}/>
<DomainPanel>
<DomainNutshell>
diff --git a/server/sonar-web/src/main/less/pages/overview.less b/server/sonar-web/src/main/less/pages/overview.less
index 4970d78111b..de53c77286e 100644
--- a/server/sonar-web/src/main/less/pages/overview.less
+++ b/server/sonar-web/src/main/less/pages/overview.less
@@ -88,16 +88,6 @@
font-size: 14px;
letter-spacing: 0.05em;
}
-
- & > a {
- border-bottom-color: #d0d0d0;
- color: @baseFontColor;
-
- &:hover, &:focus {
- border-bottom-color: @lightBlue;
- color: @blue;
- }
- }
}
/*
diff --git a/server/sonar-web/tests/apps/code/store-test.js b/server/sonar-web/tests/apps/code/store-test.js
index de5ddbfadf1..155c84a8720 100644
--- a/server/sonar-web/tests/apps/code/store-test.js
+++ b/server/sonar-web/tests/apps/code/store-test.js
@@ -313,7 +313,7 @@ describe('Code :: Store', () => {
const breadcrumbsBefore = [{ key: 'A' }];
const bucketAfter = [
- { key: 'A', breadcrumbs: [{ key: 'A' }], children: [{ key: 'B' }] },
+ { key: 'A', breadcrumbs: [{ key: 'A' }], children: [{ key: 'B' }], total: 0 },
{ key: 'B', breadcrumbs: [{ key: 'A' }, { key: 'B' }] }
];
@@ -335,7 +335,8 @@ describe('Code :: Store', () => {
{
key: 'A',
breadcrumbs: [{ key: 'A' }],
- children: [{ key: 'B' }]
+ children: [{ key: 'B' }],
+ total: 0
},
{
key: 'B',
@@ -360,12 +361,14 @@ describe('Code :: Store', () => {
{
key: 'A',
breadcrumbs: [{ key: 'A' }],
- children: [{ key: 'B' }]
+ children: [{ key: 'B' }],
+ total: 0
},
{
key: 'B',
breadcrumbs: [{ key: 'A' }, { key: 'B' }],
- children: [{ key: 'C' }]
+ children: [{ key: 'C' }],
+ total: 0
},
{
key: 'C',