@@ -20,6 +20,7 @@ | |||
package org.sonar.server.issue.notification; | |||
import com.google.common.base.Strings; | |||
import java.io.UnsupportedEncodingException; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import org.apache.commons.lang.StringUtils; | |||
@@ -31,6 +32,8 @@ import org.sonar.db.user.UserDto; | |||
import org.sonar.plugins.emailnotifications.api.EmailMessage; | |||
import org.sonar.plugins.emailnotifications.api.EmailTemplate; | |||
import static java.net.URLEncoder.encode; | |||
/** | |||
* Creates email message for notification "issue-changes". | |||
*/ | |||
@@ -100,9 +103,17 @@ public class IssueChangesEmailTemplate extends EmailTemplate { | |||
appendField(sb, "Message", null, notif.getFieldValue("message")); | |||
} | |||
private void appendFooter(StringBuilder sb, Notification notification) { | |||
private void appendFooter(StringBuilder sb, Notification notification){ | |||
String issueKey = notification.getFieldValue("key"); | |||
sb.append("See it in SonarQube: ").append(settings.getServerBaseURL()).append("/issues?issues=").append(issueKey).append(NEW_LINE); | |||
try { | |||
sb.append("See it in SonarQube: ").append(settings.getServerBaseURL()) | |||
.append("/project/issues?id=").append(encode(notification.getFieldValue("projectKey"), "UTF-8")) | |||
.append("&issues=").append(issueKey) | |||
.append("&open=").append(issueKey) | |||
.append(NEW_LINE); | |||
} catch (UnsupportedEncodingException e) { | |||
throw new IllegalStateException("Encoding not supported", e); | |||
} | |||
} | |||
private static void appendLine(StringBuilder sb, @Nullable String line) { |
@@ -3,4 +3,4 @@ Rule: Avoid Cycles | |||
Message: Has 3 cycles | |||
See it in SonarQube: http://nemo.sonarsource.org/issues?issues=ABCDE | |||
See it in SonarQube: http://nemo.sonarsource.org/project/issues?id=org.apache%3Astruts&issues=ABCDE&open=ABCDE |
@@ -4,4 +4,4 @@ Message: Has 3 cycles | |||
Resolution: FIXED (was FALSE-POSITIVE) | |||
See it in SonarQube: http://nemo.sonarsource.org/issues?issues=ABCDE | |||
See it in SonarQube: http://nemo.sonarsource.org/project/issues?id=org.apache%3Astruts&issues=ABCDE&open=ABCDE |
@@ -4,4 +4,4 @@ Message: Has 3 cycles | |||
Action Plan changed to ABC 1.0 | |||
See it in SonarQube: http://nemo.sonarsource.org/issues?issues=ABCDE | |||
See it in SonarQube: http://nemo.sonarsource.org/project/issues?id=org.apache%3Astruts&issues=ABCDE&open=ABCDE |
@@ -4,4 +4,4 @@ Message: Has 3 cycles | |||
Assignee changed to louis | |||
See it in SonarQube: http://nemo.sonarsource.org/issues?issues=ABCDE | |||
See it in SonarQube: http://nemo.sonarsource.org/project/issues?id=org.apache%3Astruts&issues=ABCDE&open=ABCDE |
@@ -9,4 +9,4 @@ Resolution: FALSE-POSITIVE | |||
Status: RESOLVED | |||
Tags: [bug performance] | |||
See it in SonarQube: http://nemo.sonarsource.org/issues?issues=ABCDE | |||
See it in SonarQube: http://nemo.sonarsource.org/project/issues?id=org.apache%3Astruts&issues=ABCDE&open=ABCDE |
@@ -25,7 +25,7 @@ import IssueMessage from './IssueMessage'; | |||
import SimilarIssuesFilter from './SimilarIssuesFilter'; | |||
import LocationIndex from '../../common/LocationIndex'; | |||
import Tooltip from '../../controls/Tooltip'; | |||
import { getSingleIssueUrl } from '../../../helpers/urls'; | |||
import { getComponentIssuesUrl } from '../../../helpers/urls'; | |||
import { formatMeasure } from '../../../helpers/measures'; | |||
import { translate, translateWithParameters } from '../../../helpers/l10n'; | |||
import type { Issue } from '../types'; | |||
@@ -62,6 +62,8 @@ export default function IssueTitleBar(props: Props) { | |||
// dirty trick :( | |||
const onIssuesPage = document.getElementById('issues-page') != null; | |||
const issueUrl = getComponentIssuesUrl(issue.project, { issues: issue.key, open: issue.key }); | |||
return ( | |||
<table className="issue-table"> | |||
<tbody> | |||
@@ -94,10 +96,7 @@ export default function IssueTitleBar(props: Props) { | |||
<li className="issue-meta"> | |||
{onIssuesPage | |||
? locationsBadge | |||
: <Link | |||
onClick={stopPropagation} | |||
target="_blank" | |||
to={getSingleIssueUrl(issue.key)}> | |||
: <Link onClick={stopPropagation} target="_blank" to={issueUrl}> | |||
{locationsBadge} | |||
</Link>} | |||
</li>} | |||
@@ -106,7 +105,7 @@ export default function IssueTitleBar(props: Props) { | |||
className="js-issue-permalink icon-link" | |||
onClick={stopPropagation} | |||
target="_blank" | |||
to={getSingleIssueUrl(issue.key)} | |||
to={issueUrl} | |||
/> | |||
</li> | |||
{hasSimilarIssuesFilter && |
@@ -25,6 +25,7 @@ const issue = { | |||
line: 26, | |||
creationDate: '2017-03-01T09:36:01+0100', | |||
organization: 'myorg', | |||
project: 'myproject', | |||
key: 'AVsae-CQS-9G3txfbFN2', | |||
rule: 'javascript:S1067', | |||
message: 'Reduce the number of conditional operators (4) used in the expression', |
@@ -33,6 +33,7 @@ exports[`should render the titlebar correctly 1`] = ` | |||
"line": 26, | |||
"message": "Reduce the number of conditional operators (4) used in the expression", | |||
"organization": "myorg", | |||
"project": "myproject", | |||
"rule": "javascript:S1067", | |||
"secondaryLocations": Array [], | |||
} | |||
@@ -63,8 +64,9 @@ exports[`should render the titlebar correctly 1`] = ` | |||
target="_blank" | |||
to={ | |||
Object { | |||
"pathname": "/issues", | |||
"pathname": "/project/issues", | |||
"query": Object { | |||
"id": "myproject", | |||
"issues": "AVsae-CQS-9G3txfbFN2", | |||
"open": "AVsae-CQS-9G3txfbFN2", | |||
}, | |||
@@ -112,6 +114,7 @@ exports[`should render the titlebar with the filter 1`] = ` | |||
"line": 26, | |||
"message": "Reduce the number of conditional operators (4) used in the expression", | |||
"organization": "myorg", | |||
"project": "myproject", | |||
"rule": "javascript:S1067", | |||
"secondaryLocations": Array [], | |||
} | |||
@@ -142,8 +145,9 @@ exports[`should render the titlebar with the filter 1`] = ` | |||
target="_blank" | |||
to={ | |||
Object { | |||
"pathname": "/issues", | |||
"pathname": "/project/issues", | |||
"query": Object { | |||
"id": "myproject", | |||
"issues": "AVsae-CQS-9G3txfbFN2", | |||
"open": "AVsae-CQS-9G3txfbFN2", | |||
}, | |||
@@ -164,6 +168,7 @@ exports[`should render the titlebar with the filter 1`] = ` | |||
"line": 26, | |||
"message": "Reduce the number of conditional operators (4) used in the expression", | |||
"organization": "myorg", | |||
"project": "myproject", | |||
"rule": "javascript:S1067", | |||
"secondaryLocations": Array [], | |||
} |
@@ -55,13 +55,6 @@ export function getComponentIssuesUrlAsString(componentKey, query) { | |||
return `${window.baseUrl}${path.pathname}?${stringify(path.query)}`; | |||
} | |||
/** | |||
* Generate URL for a single issue | |||
*/ | |||
export function getSingleIssueUrl(issues) { | |||
return { pathname: '/issues', query: { issues, open: issues } }; | |||
} | |||
/** | |||
* Generate URL for a component's drilldown page | |||
* @param {string} componentKey |