aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main
diff options
context:
space:
mode:
authorStas Vilchik <vilchiks@gmail.com>2015-08-12 11:23:22 +0200
committerStas Vilchik <vilchiks@gmail.com>2015-08-13 10:49:41 +0200
commit91e29d47a06b3f5c7dd48bd19447a639b3b7de4c (patch)
treef548f32a3987b51986df32ef1dfb126cc8279574 /server/sonar-web/src/main
parentaaa5554c0a8e5478ad94739933784bdb59d60270 (diff)
downloadsonarqube-91e29d47a06b3f5c7dd48bd19447a639b3b7de4c.tar.gz
sonarqube-91e29d47a06b3f5c7dd48bd19447a639b3b7de4c.zip
SONAR-6765 SONAR-6766 show multiple issue locations and execution flows
Diffstat (limited to 'server/sonar-web/src/main')
-rw-r--r--server/sonar-web/src/main/js/apps/issues/component-viewer/main.js2
-rw-r--r--server/sonar-web/src/main/js/components/issue/issue-view.js7
-rw-r--r--server/sonar-web/src/main/js/components/issue/templates/issue.hbs13
-rw-r--r--server/sonar-web/src/main/js/components/source-viewer/helpers/code-with-issue-locations-helper.js32
-rw-r--r--server/sonar-web/src/main/js/components/source-viewer/main.js65
-rw-r--r--server/sonar-web/src/main/js/components/source-viewer/templates/source-viewer-flow-location.hbs1
-rw-r--r--server/sonar-web/src/main/less/components/source.less45
-rw-r--r--server/sonar-web/src/main/less/init/icons.less9
-rw-r--r--server/sonar-web/src/main/less/pages/issues.less5
-rw-r--r--server/sonar-web/src/main/less/variables.less2
10 files changed, 159 insertions, 22 deletions
diff --git a/server/sonar-web/src/main/js/apps/issues/component-viewer/main.js b/server/sonar-web/src/main/js/apps/issues/component-viewer/main.js
index 1e79d92e45d..8792113e213 100644
--- a/server/sonar-web/src/main/js/apps/issues/component-viewer/main.js
+++ b/server/sonar-web/src/main/js/apps/issues/component-viewer/main.js
@@ -24,6 +24,7 @@ define([
SourceViewer.prototype.onLoaded.apply(this, arguments);
this.bindShortcuts();
if (this.baseIssue != null) {
+ this.baseIssue.trigger('locations', this.baseIssue);
return this.scrollToLine(this.baseIssue.get('line'));
}
},
@@ -83,6 +84,7 @@ define([
var selected = this.options.app.state.get('selectedIndex'),
selectedIssue = this.options.app.list.at(selected);
if (selectedIssue.get('component') === this.model.get('key')) {
+ selectedIssue.trigger('locations', selectedIssue);
return this.scrollToIssue(selectedIssue.get('key'));
} else {
this.unbindShortcuts();
diff --git a/server/sonar-web/src/main/js/components/issue/issue-view.js b/server/sonar-web/src/main/js/components/issue/issue-view.js
index 14e83e689e4..aad34a2d04c 100644
--- a/server/sonar-web/src/main/js/components/issue/issue-view.js
+++ b/server/sonar-web/src/main/js/components/issue/issue-view.js
@@ -37,7 +37,8 @@ define([
'click .js-issue-plan': 'plan',
'click .js-issue-show-changelog': 'showChangeLog',
'click .js-issue-rule': 'showRule',
- 'click .js-issue-edit-tags': 'editTags'
+ 'click .js-issue-edit-tags': 'editTags',
+ 'click .js-issue-locations': 'showLocations'
};
},
@@ -217,6 +218,10 @@ define([
this.popup.render();
},
+ showLocations: function () {
+ this.model.trigger('locations', this.model);
+ },
+
serializeData: function () {
var issueKey = encodeURIComponent(this.model.get('key'));
return _.extend(Marionette.ItemView.prototype.serializeData.apply(this, arguments), {
diff --git a/server/sonar-web/src/main/js/components/issue/templates/issue.hbs b/server/sonar-web/src/main/js/components/issue/templates/issue.hbs
index 930e5ca5693..06e878f7b8f 100644
--- a/server/sonar-web/src/main/js/components/issue/templates/issue.hbs
+++ b/server/sonar-web/src/main/js/components/issue/templates/issue.hbs
@@ -4,7 +4,8 @@
<tr>
<td>
<div class="issue-message">
- {{message}}&nbsp;<button class="button-link js-issue-rule issue-rule icon-ellipsis-h"></button>
+ {{message}}&nbsp;
+ <button class="button-link js-issue-rule issue-rule icon-ellipsis-h"></button>
</div>
</td>
@@ -22,6 +23,14 @@
</li>
{{/if}}
+ {{#notEmpty secondaryLocations}}
+ <li class="issue-meta issue-meta-locations">
+ <button class="button-link issue-action js-issue-locations">
+ <i class="icon-issue-flow"></i>
+ </button>
+ </li>
+ {{/notEmpty}}
+
<li class="issue-meta">
<a class="js-issue-permalink icon-link" href="{{permalink}}" target="_blank"></a>
</li>
@@ -143,7 +152,7 @@
{{#if updatable}}
<button class="js-issue-comment-edit button-link icon-edit icon-half-transparent"></button>
<button class="js-issue-comment-delete button-link icon-delete icon-half-transparent"
- data-confirm-msg="{{t 'issue.comment.delete_confirm_message'}}"></button>
+ data-confirm-msg="{{t 'issue.comment.delete_confirm_message'}}"></button>
{{/if}}
</div>
</div>
diff --git a/server/sonar-web/src/main/js/components/source-viewer/helpers/code-with-issue-locations-helper.js b/server/sonar-web/src/main/js/components/source-viewer/helpers/code-with-issue-locations-helper.js
index b95c6efd18c..fd5d56a3bde 100644
--- a/server/sonar-web/src/main/js/components/source-viewer/helpers/code-with-issue-locations-helper.js
+++ b/server/sonar-web/src/main/js/components/source-viewer/helpers/code-with-issue-locations-helper.js
@@ -22,7 +22,8 @@ define(function () {
* @returns {string}
*/
function part (str, from, to, acc) {
- return str.substr(from - acc, to - from);
+ // we do not want negative number as the first argument of `substr`
+ return from >= acc ? str.substr(from - acc, to - from) : str.substr(0, to - from);
}
@@ -53,9 +54,10 @@ define(function () {
* Highlight issue locations in the list of tokens
* @param {Array} tokens
* @param {Array} issueLocations
+ * @param {string} className
* @returns {Array}
*/
- function highlightIssueLocations (tokens, issueLocations) {
+ function highlightIssueLocations (tokens, issueLocations, className) {
issueLocations.forEach(function (location) {
var nextTokens = [],
acc = 0;
@@ -68,8 +70,8 @@ define(function () {
nextTokens.push({ className: token.className, text: p1 });
}
if (p2.length) {
- var newClassName = token.className.indexOf('source-line-code-issue') === -1 ?
- [token.className, 'source-line-code-issue'].join(' ') : token.className;
+ var newClassName = token.className.indexOf(className) === -1 ?
+ [token.className, className].join(' ') : token.className;
nextTokens.push({ className: newClassName, text: p2 });
}
if (p3.length) {
@@ -100,20 +102,26 @@ define(function () {
* highlight issues and generate result html
* @param {string} code
* @param {Array} issueLocations
+ * @param {string} [optionalClassName]
* @returns {string}
*/
- function doTheStuff (code, issueLocations) {
+ function doTheStuff (code, issueLocations, optionalClassName) {
var _code = code || '&nbsp;';
var _issueLocations = issueLocations || [];
- return generateHTML(highlightIssueLocations(splitByTokens(_code), _issueLocations));
+ var _className = optionalClassName ? optionalClassName : 'source-line-code-issue';
+ return generateHTML(highlightIssueLocations(splitByTokens(_code), _issueLocations, _className));
}
- /**
- * Handlebars helper to highlight issue locations in the source code
- */
- Handlebars.registerHelper('codeWithIssueLocations', function (code, issueLocations) {
- return doTheStuff(code, issueLocations);
- });
+ if (typeof Handlebars !== 'undefined') {
+ /**
+ * Handlebars helper to highlight issue locations in the source code
+ */
+ Handlebars.registerHelper('codeWithIssueLocations', function (code, issueLocations) {
+ return doTheStuff(code, issueLocations);
+ });
+ }
+
+ return doTheStuff;
});
diff --git a/server/sonar-web/src/main/js/components/source-viewer/main.js b/server/sonar-web/src/main/js/components/source-viewer/main.js
index 828e9e53ffc..a73b56a315f 100644
--- a/server/sonar-web/src/main/js/components/source-viewer/main.js
+++ b/server/sonar-web/src/main/js/components/source-viewer/main.js
@@ -39,7 +39,8 @@ define([
SCMPopupView,
CoveragePopupView,
DuplicationPopupView,
- LineActionsPopupView) {
+ LineActionsPopupView,
+ highlightLocations) {
var $ = jQuery,
HIGHLIGHTED_ROW_CLASS = 'source-line-highlighted';
@@ -47,6 +48,7 @@ define([
return Marionette.LayoutView.extend({
className: 'source-viewer',
template: Templates['source-viewer'],
+ flowLocationTemplate: Templates['source-viewer-flow-location'],
ISSUES_LIMIT: 3000,
LINES_LIMIT: 1000,
@@ -84,6 +86,7 @@ define([
}
this.issues = new Issues();
this.listenTo(this.issues, 'change:severity', this.onIssuesSeverityChange);
+ this.listenTo(this.issues, 'locations', this.toggleFlowLocations);
this.issueViews = [];
this.loadSourceBeforeThrottled = _.throttle(this.loadSourceBefore, 1000);
this.loadSourceAfterThrottled = _.throttle(this.loadSourceAfter, 1000);
@@ -277,8 +280,8 @@ define([
data: {
componentUuids: this.model.id,
f: 'component,componentId,project,subProject,rule,status,resolution,author,reporter,assignee,debt,' +
- 'line,message,severity,actionPlan,creationDate,updateDate,closeDate,tags,comments,attr,actions,' +
- 'transitions,actionPlanName',
+ 'line,message,severity,actionPlan,creationDate,updateDate,closeDate,tags,comments,attr,actions,' +
+ 'transitions,actionPlanName',
additionalFields: '_all',
resolved: false,
s: 'FILE_LINE',
@@ -732,6 +735,62 @@ define([
hideFilteredTooltip: function (e) {
$(e.currentTarget).tooltip('destroy');
+ },
+
+ toggleFlowLocations: function (issue) {
+ if (this.locationsShowFor === issue) {
+ this.hideFlowLocations();
+ } else {
+ this.hideFlowLocations();
+ this.showFlowLocations(issue);
+ }
+ },
+
+ showFlowLocations: function (issue) {
+ this.locationsShowFor = issue;
+ var primaryLocation = {
+ msg: issue.get('message'),
+ textRange: issue.get('textRange')
+ },
+ _locations = [primaryLocation].concat(issue.get('secondaryLocations'));
+ _locations.forEach(this.showFlowLocation, this);
+ },
+
+ showFlowLocation: function (location) {
+ if (location && location.textRange) {
+ var line = location.textRange.startLine,
+ row = this.$('.source-line-code[data-line-number="' + line + '"]'),
+ renderedFlowLocation = this.renderFlowLocation(location);
+ row.append(renderedFlowLocation);
+ this.highlightFlowLocationInCode(location);
+ }
+ },
+
+ renderFlowLocation: function (location) {
+ location.msg = location.msg ? location.msg : ' ';
+ return this.flowLocationTemplate(location);
+ },
+
+ highlightFlowLocationInCode: function (location) {
+ for (var line = location.textRange.startLine; line <= location.textRange.endLine; line++) {
+ var row = this.$('.source-line-code[data-line-number="' + line + '"]');
+
+ // get location for the current line
+ var from = line === location.textRange.startLine ? location.textRange.startOffset : 0,
+ to = line === location.textRange.endLine ? location.textRange.endOffset : 999999,
+ _location = { from: from, to: to };
+
+ // mark issue location in the source code
+ var code = row.find('pre').html(),
+ newCode = highlightLocations(code, [_location], 'source-line-code-secondary-issue');
+ row.find('pre').html(newCode);
+ }
+ },
+
+ hideFlowLocations: function () {
+ this.locationsShowFor = null;
+ this.$('.source-viewer-flow-location').remove();
+ this.$('.source-line-code-secondary-issue').removeClass('source-line-code-secondary-issue');
}
});
diff --git a/server/sonar-web/src/main/js/components/source-viewer/templates/source-viewer-flow-location.hbs b/server/sonar-web/src/main/js/components/source-viewer/templates/source-viewer-flow-location.hbs
new file mode 100644
index 00000000000..e11d2200798
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/source-viewer/templates/source-viewer-flow-location.hbs
@@ -0,0 +1 @@
+<div class="source-viewer-flow-location" title="{{msg}}">{{limitString msg}} </div>
diff --git a/server/sonar-web/src/main/less/components/source.less b/server/sonar-web/src/main/less/components/source.less
index cbe29981233..24f587f1ea5 100644
--- a/server/sonar-web/src/main/less/components/source.less
+++ b/server/sonar-web/src/main/less/components/source.less
@@ -21,7 +21,7 @@
@import (reference) "../variables";
@import (reference) "ui";
-@lineHeight: 18px;
+@source-line-height: 18px;
@lineWithIssuesBackground: #ffeaea;
@duplicationColor: #f3ca8e;
@@ -95,18 +95,19 @@
}
.source-viewer pre {
- height: @lineHeight;
+ height: @source-line-height;
padding: 0;
}
.source-viewer pre,
.source-meta {
- line-height: @lineHeight;
+ line-height: @source-line-height;
font-family: @monoFontFamily;
font-size: 12px;
}
.source-line-code {
+ position: relative;
padding: 0 10px;
.issue-list {
@@ -123,6 +124,12 @@
background-position: bottom;
}
+.source-line-code-secondary-issue {
+ display: inline-block;
+ background-color: @red;
+ color: #fff !important;
+}
+
.source-meta {
vertical-align: top;
width: 1px;
@@ -204,7 +211,7 @@
.source-line-bar {
width: 5px;
- height: @lineHeight;
+ height: @source-line-height;
}
.source-line-with-issues {
@@ -444,3 +451,33 @@
.source-viewer-test-covered-lines {
text-align: right;
}
+
+.source-viewer-flow-location {
+ position: absolute;
+ top: 0;
+ right: 0;
+ line-height: @source-line-height - 2px;
+ margin: 1px 0;
+ padding: 0 10px;
+ background-color: @red;
+ color: #fff;
+ font-size: 12px;
+ z-index: @issue-flow-location-z-index;
+
+ &:before {
+ @arrow-size: (@source-line-height - 2px) / 2;
+ content: " ";
+ position: absolute;
+ top: 0;
+ right: 100%;
+ display: block;
+ .square(0);
+ border-top: @arrow-size solid transparent;
+ border-bottom: @arrow-size solid transparent;
+ border-right: @arrow-size solid @red;
+ }
+}
+
+.source-viewer-flow-location + .source-viewer-flow-location {
+ z-index: @issue-flow-location-z-index - 1;
+}
diff --git a/server/sonar-web/src/main/less/init/icons.less b/server/sonar-web/src/main/less/init/icons.less
index ca4a8b2b49f..f0d20455d5e 100644
--- a/server/sonar-web/src/main/less/init/icons.less
+++ b/server/sonar-web/src/main/less/init/icons.less
@@ -536,6 +536,15 @@ a[class^="icon-"], a[class*=" icon-"] {
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB2aWV3Qm94PSIwIDAgOSAxNiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3BhY2U9InByZXNlcnZlIiBzdHlsZT0iZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjEuNDE0MjE7Ij4gICAgPHBhdGggZD0iTTYuNTcxNDMsNS4xNDI4NkM2LjU3MTQzLDUuMjIwMjQgNi41NDMxNSw1LjI4NzIgNi40ODY2MSw1LjM0Mzc1QzYuNDMwMDYsNS40MDAzIDYuMzYzMSw1LjQyODU3IDYuMjg1NzEsNS40Mjg1N0M2LjIwODMzLDUuNDI4NTcgNi4xNDEzNyw1LjQwMDMgNi4wODQ4Miw1LjM0Mzc1QzYuMDI4MjcsNS4yODcyIDYsNS4yMjAyNCA2LDUuMTQyODZDNiw0Ljg2OTA1IDUuODM5MjksNC42NTc3NCA1LjUxNzg2LDQuNTA4OTNDNS4xOTY0Myw0LjM2MDEyIDQuODgwOTUsNC4yODU3MSA0LjU3MTQzLDQuMjg1NzFDNC40OTQwNSw0LjI4NTcxIDQuNDI3MDgsNC4yNTc0NCA0LjM3MDU0LDQuMjAwODlDNC4zMTM5OSw0LjE0NDM1IDQuMjg1NzEsNC4wNzczOCA0LjI4NTcxLDRDNC4yODU3MSwzLjkyMjYyIDQuMzEzOTksMy44NTU2NSA0LjM3MDU0LDMuNzk5MTFDNC40MjcwOCwzLjc0MjU2IDQuNDk0MDUsMy43MTQyOSA0LjU3MTQzLDMuNzE0MjlDNC44NjkwNSwzLjcxNDI5IDUuMTY1MTgsMy43NjE5IDUuNDU5ODIsMy44NTcxNEM1Ljc1NDQ2LDMuOTUyMzggNi4wMTMzOSw0LjExMzEgNi4yMzY2MSw0LjMzOTI5QzYuNDU5ODIsNC41NjU0OCA2LjU3MTQzLDQuODMzMzMgNi41NzE0Myw1LjE0Mjg2Wk04LDUuMTQyODZDOCw0LjcxNDI5IDcuODk3MzIsNC4zMTU0OCA3LjY5MTk2LDMuOTQ2NDNDNy40ODY2MSwzLjU3NzM4IDcuMjE4NzUsMy4yNzUzIDYuODg4MzksMy4wNDAxOEM2LjU1ODA0LDIuODA1MDYgNi4xOTE5NiwyLjYyMDU0IDUuNzkwMTgsMi40ODY2MUM1LjM4ODM5LDIuMzUyNjggNC45ODIxNCwyLjI4NTcxIDQuNTcxNDMsMi4yODU3MUM0LjE2MDcxLDIuMjg1NzEgMy43NTQ0NiwyLjM1MjY4IDMuMzUyNjgsMi40ODY2MUMyLjk1MDg5LDIuNjIwNTQgMi41ODQ4MiwyLjgwNTA2IDIuMjU0NDYsMy4wNDAxOEMxLjkyNDExLDMuMjc1MyAxLjY1NjI1LDMuNTc3MzggMS40NTA4OSwzLjk0NjQzQzEuMjQ1NTQsNC4zMTU0OCAxLjE0Mjg2LDQuNzE0MjkgMS4xNDI4Niw1LjE0Mjg2QzEuMTQyODYsNS43NDQwNSAxLjM0NTI0LDYuMjc5NzYgMS43NSw2Ljc1QzEuODA5NTIsNi44MTU0OCAxLjkwMDMsNi45MTM2OSAyLjAyMjMyLDcuMDQ0NjRDMi4xNDQzNSw3LjE3NTYgMi4yMzUxMiw3LjI3MzgxIDIuMjk0NjQsNy4zMzkyOUMzLjA1NjU1LDguMjUgMy40NzYxOSw5LjEzNjkgMy41NTM1NywxMEw1LjU4OTI5LDEwQzUuNjY2NjcsOS4xMzY5IDYuMDg2MzEsOC4yNSA2Ljg0ODIxLDcuMzM5MjlDNi45MDc3NCw3LjI3MzgxIDYuOTk4NTEsNy4xNzU2IDcuMTIwNTQsNy4wNDQ2NEM3LjI0MjU2LDYuOTEzNjkgNy4zMzMzMyw2LjgxNTQ4IDcuMzkyODYsNi43NUM3Ljc5NzYyLDYuMjc5NzYgOCw1Ljc0NDA1IDgsNS4xNDI4NlpNOS4xNDI4Niw1LjE0Mjg2QzkuMTQyODYsNi4wNjU0OCA4LjgzNjMxLDYuODYzMSA4LjIyMzIxLDcuNTM1NzFDNy45NTUzNiw3LjgyNzM4IDcuNzMzNjMsOC4wODYzMSA3LjU1ODA0LDguMzEyNUM3LjM4MjQ0LDguNTM4NjkgNy4yMDUzNiw4LjgyMjkyIDcuMDI2NzksOS4xNjUxOEM2Ljg0ODIxLDkuNTA3NDQgNi43NDcwMiw5LjgyNzM4IDYuNzIzMjEsMTAuMTI1QzcuMDAyOTgsMTAuMjkxNyA3LjE0Mjg2LDEwLjUzNTcgNy4xNDI4NiwxMC44NTcxQzcuMTQyODYsMTEuMDc3NCA3LjA2ODQ1LDExLjI2NzkgNi45MTk2NCwxMS40Mjg2QzcuMDY4NDUsMTEuNTg5MyA3LjE0Mjg2LDExLjc3OTggNy4xNDI4NiwxMkM3LjE0Mjg2LDEyLjMwOTUgNy4wMDg5MywxMi41NTA2IDYuNzQxMDcsMTIuNzIzMkM2LjgxODQ1LDEyLjg2MDEgNi44NTcxNCwxMyA2Ljg1NzE0LDEzLjE0MjlDNi44NTcxNCwxMy40MTY3IDYuNzYzMzksMTMuNjI4IDYuNTc1ODksMTMuNzc2OEM2LjM4ODM5LDEzLjkyNTYgNi4xNTc3NCwxNCA1Ljg4MzkzLDE0QzUuNzY0ODgsMTQuMjYxOSA1LjU4NjMxLDE0LjQ3MDIgNS4zNDgyMSwxNC42MjVDNS4xMTAxMiwxNC43Nzk4IDQuODUxMTksMTQuODU3MSA0LjU3MTQzLDE0Ljg1NzFDNC4yOTE2NywxNC44NTcxIDQuMDMyNzQsMTQuNzc5OCAzLjc5NDY0LDE0LjYyNUMzLjU1NjU1LDE0LjQ3MDIgMy4zNzc5OCwxNC4yNjE5IDMuMjU4OTMsMTRDMi45ODUxMiwxNCAyLjc1NDQ2LDEzLjkyNTYgMi41NjY5NiwxMy43NzY4QzIuMzc5NDYsMTMuNjI4IDIuMjg1NzEsMTMuNDE2NyAyLjI4NTcxLDEzLjE0MjlDMi4yODU3MSwxMyAyLjMyNDQsMTIuODYwMSAyLjQwMTc5LDEyLjcyMzJDMi4xMzM5MywxMi41NTA2IDIsMTIuMzA5NSAyLDEyQzIsMTEuNzc5OCAyLjA3NDQsMTEuNTg5MyAyLjIyMzIxLDExLjQyODZDMi4wNzQ0LDExLjI2NzkgMiwxMS4wNzc0IDIsMTAuODU3MUMyLDEwLjUzNTcgMi4xMzk4OCwxMC4yOTE3IDIuNDE5NjQsMTAuMTI1QzIuMzk1ODMsOS44MjczOCAyLjI5NDY0LDkuNTA3NDQgMi4xMTYwNyw5LjE2NTE4QzEuOTM3NSw4LjgyMjkyIDEuNzYwNDIsOC41Mzg2OSAxLjU4NDgyLDguMzEyNUMxLjQwOTIzLDguMDg2MzEgMS4xODc1LDcuODI3MzggMC45MTk2NDMsNy41MzU3MUMwLjMwNjU0OCw2Ljg2MzEgMCw2LjA2NTQ4IDAsNS4xNDI4NkMwLDQuNTUzNTcgMC4xMzI0NCw0LjAwNDQ2IDAuMzk3MzIxLDMuNDk1NTRDMC42NjIyMDIsMi45ODY2MSAxLjAxMDQyLDIuNTYzOTkgMS40NDE5NiwyLjIyNzY4QzEuODczNTEsMS44OTEzNyAyLjM2MTYxLDEuNjI2NDkgMi45MDYyNSwxLjQzMzA0QzMuNDUwODksMS4yMzk1OCA0LjAwNTk1LDEuMTQyODYgNC41NzE0MywxLjE0Mjg2QzUuMTM2OSwxLjE0Mjg2IDUuNjkxOTYsMS4yMzk1OCA2LjIzNjYxLDEuNDMzMDRDNi43ODEyNSwxLjYyNjQ5IDcuMjY5MzUsMS44OTEzNyA3LjcwMDg5LDIuMjI3NjhDOC4xMzI0NCwyLjU2Mzk5IDguNDgwNjUsMi45ODY2MSA4Ljc0NTU0LDMuNDk1NTRDOS4wMTA0Miw0LjAwNDQ2IDkuMTQyODYsNC41NTM1NyA5LjE0Mjg2LDUuMTQyODZaIiBzdHlsZT0iZmlsbDpyZ2IoNDUsMTM1LDE5Mik7ZmlsbC1ydWxlOm5vbnplcm87Ii8+PC9zdmc+);
background-repeat: no-repeat;
}
+.icon-issue-flow {
+ position: relative;
+ top: 1px;
+ display: inline-block;
+ vertical-align: top;
+ .size(14px, 14px);
+ background-image: url(data:image/svg+xml,%3Csvg%20width%3D%2214%22%20height%3D%2214%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20stroke-linejoin%3D%22round%22%20stroke-miterlimit%3D%221.414%22%3E%3Cpath%20d%3D%22M2.977%2012.656c0%20.417-.142.745-.426.985-.283.24-.636.36-1.058.36-.552%200-1-.172-1.344-.516l.446-.687c.255.234.53.35.828.35.15%200%20.282-.036.394-.112.112-.075.168-.186.168-.332%200-.333-.273-.48-.82-.437l-.203-.438c.043-.052.127-.165.255-.34.127-.174.238-.315.332-.422.094-.106.19-.207.29-.3v-.008c-.084%200-.21.002-.38.008-.17.005-.296.007-.38.007v.415H.25V10h2.602v.688l-.743.898c.265.062.476.19.632.383.156.19.235.42.235.686zm.015-4.898V9H.164c-.03-.188-.047-.328-.047-.422%200-.265.06-.508.184-.726.123-.22.27-.396.442-.532.172-.135.344-.26.516-.37.172-.113.32-.226.44-.34.124-.115.185-.232.185-.352%200-.13-.038-.23-.113-.3-.076-.07-.18-.106-.31-.106-.24%200-.45.15-.632.453l-.664-.46c.125-.267.31-.474.56-.622.246-.15.52-.223.823-.223.38%200%20.7.108.96.324.26.216.39.51.39.88%200%20.26-.087.498-.264.714-.177.216-.373.384-.586.504-.214.12-.41.25-.59.394-.18.144-.272.28-.277.41h.992V7.76h.82zM14%2010.25v1.5c0%20.068-.025.126-.074.176-.05.05-.108.074-.176.074h-9.5c-.068%200-.126-.025-.176-.074-.05-.05-.074-.108-.074-.176v-1.5c0-.073.023-.133.07-.18.047-.047.107-.07.18-.07h9.5c.068%200%20.126.025.176.074.05.05.074.108.074.176zM3%203.227V4H.383v-.773h.836c0-.214%200-.532.003-.954l.004-.945v-.094H1.21c-.04.09-.17.23-.39.422l-.554-.593L1.328.07h.828v3.157H3zM14%206.25v1.5c0%20.068-.025.126-.074.176-.05.05-.108.074-.176.074h-9.5c-.068%200-.126-.025-.176-.074C4.024%207.876%204%207.818%204%207.75v-1.5c0-.073.023-.133.07-.18.047-.047.107-.07.18-.07h9.5c.068%200%20.126.025.176.074.05.05.074.108.074.176zm0-4v1.5c0%20.068-.025.126-.074.176-.05.05-.108.074-.176.074h-9.5c-.068%200-.126-.025-.176-.074C4.024%203.876%204%203.818%204%203.75v-1.5c0-.068.025-.126.074-.176.05-.05.108-.074.176-.074h9.5c.068%200%20.126.025.176.074.05.05.074.108.074.176z%22%20fill%3D%22%23236A97%22%20fill-rule%3D%22nonzero%22%2F%3E%3C%2Fsvg%3E);
+ background-repeat: no-repeat;
+}
/*
diff --git a/server/sonar-web/src/main/less/pages/issues.less b/server/sonar-web/src/main/less/pages/issues.less
index 0f512c1ba6c..cfa2cc22bba 100644
--- a/server/sonar-web/src/main/less/pages/issues.less
+++ b/server/sonar-web/src/main/less/pages/issues.less
@@ -35,6 +35,11 @@
}
}
+
+ .issue-meta-locations {
+ position: absolute;
+ visibility: hidden;
+ }
}
.issues-workspace-list-component {
diff --git a/server/sonar-web/src/main/less/variables.less b/server/sonar-web/src/main/less/variables.less
index 44a86acb13f..82366ca71be 100644
--- a/server/sonar-web/src/main/less/variables.less
+++ b/server/sonar-web/src/main/less/variables.less
@@ -216,6 +216,8 @@
@workspace-nav-z-index: 451;
@workspace-viewer-z-index: 450;
+@issue-flow-location-z-index: 505;
+
// ui elements
@tooltip-z-index: 8000;
@tip-z-index: 8000;