import moment from 'moment';
import React from 'react';
-import {getProjectUrl} from '../../helpers/Url';
+import { getComponentUrl } from '../../helpers/urls';
import QualifierIcon from '../../components/shared/qualifier-icon';
import PendingIcon from '../../components/shared/pending-icon';
import {STATUSES} from './constants';
<span className="little-spacer-right">
<QualifierIcon qualifier={task.componentQualifier}/>
</span>
- <a href={getProjectUrl(task.componentKey)}>{task.componentName}</a>
+ <a href={getComponentUrl(task.componentKey)}>{task.componentName}</a>
</td>
);
},
import _ from 'underscore';
import React from 'react';
import { BubbleChart } from '../../../components/charts/bubble-chart';
-import { getProjectUrl } from '../../../helpers/Url';
+import { getComponentUrl } from '../../../helpers/urls';
import { getFiles } from '../../../api/components';
import { formatMeasure } from '../../../helpers/measures';
x: getMeasure(component, this.props.xMetric),
y: getMeasure(component, this.props.yMetric),
size: this.getSizeMetricsValue(component),
- link: getProjectUrl(component.key),
+ link: getComponentUrl(component.key),
tooltip: this.getTooltip(component)
};
});
import moment from 'moment';
import React from 'react';
import IssuesLink from './issues-link';
+import { getComponentDrilldownUrl } from '../../../helpers/urls';
+
export default React.createClass({
isIssueMeasure() {
return this.renderIssuesLink();
}
- let params = { id: this.props.component, metric: this.props.metric };
- if (this.props.period) {
- params.period = this.props.period;
- }
-
- let query = Object.keys(params).map(key => {
- return `${key}=${encodeURIComponent(params[key])}`;
- }).join('&'),
- url = `${baseUrl}/drilldown/measures?${query}`;
-
+ let url = getComponentDrilldownUrl(this.props.component, this.props.metric, this.props.period);
return <a href={url}>{this.props.children}</a>;
}
});
import React from 'react';
+import { getComponentIssuesUrl } from '../../../helpers/urls';
+
export default React.createClass({
render() {
- let params = Object.keys(this.props.params).map((key) => {
- return `${key}=${encodeURIComponent(this.props.params[key])}`;
- }).join('|'),
- url = `${window.baseUrl}/component_issues/index?id=${encodeURIComponent(this.props.component)}#${params}`;
+ let url = getComponentIssuesUrl(this.props.component, this.props.params);
return <a href={url}>{this.props.children}</a>;
}
});
import React from 'react';
import Assignee from '../../../components/shared/assignee-helper';
import { DomainHeader } from '../domain/header';
-import { componentIssuesUrl } from '../../../helpers/Url';
+import { getComponentIssuesUrl } from '../../../helpers/urls';
import { formatMeasure } from '../../../helpers/measures';
export default class extends React.Component {
render () {
let rows = this.props.assignees.map(s => {
- let href = componentIssuesUrl(this.props.component.key, { statuses: 'OPEN,REOPENED', assignees: s.val });
+ let href = getComponentIssuesUrl(this.props.component.key, { statuses: 'OPEN,REOPENED', assignees: s.val });
return <tr key={s.val}>
<td>
<Assignee user={s.user}/>
import React from 'react';
import SeverityHelper from '../../../components/shared/severity-helper';
import { DomainHeader } from '../domain/header';
-import { componentIssuesUrl } from '../../../helpers/Url';
+import { getComponentIssuesUrl } from '../../../helpers/urls';
import { formatMeasure } from '../../../helpers/measures';
render () {
let rows = this.sortedSeverities().map(s => {
- let href = componentIssuesUrl(this.props.component.key, { resolved: 'false', severities: s.val });
+ let href = getComponentIssuesUrl(this.props.component.key, { resolved: 'false', severities: s.val });
return <tr key={s.val}>
<td>
<SeverityHelper severity={s.val}/>
import React from 'react';
import { DomainHeader } from '../domain/header';
import { WordCloud } from '../../../components/charts/word-cloud';
-import { componentIssuesUrl } from '../../../helpers/Url';
+import { getComponentIssuesUrl } from '../../../helpers/urls';
import { formatMeasure } from '../../../helpers/measures';
export default class extends React.Component {
renderWordCloud () {
let tags = this.props.tags.map(tag => {
- let link = componentIssuesUrl(this.props.component.key, { resolved: 'false', tags: tag.val });
+ let link = getComponentIssuesUrl(this.props.component.key, { resolved: 'false', tags: tag.val });
let tooltip = `Issues: ${formatMeasure(tag.count, 'SHORT_INT')}`;
return { text: tag.val, size: tag.count, link, tooltip };
});
import UsersView from './users-view';
import GroupsView from './groups-view';
import ApplyTemplateView from './apply-template-view';
-import {getProjectUrl} from '../../helpers/Url';
+import { getComponentUrl } from '../../helpers/urls';
import QualifierIcon from '../../components/shared/qualifier-icon';
export default React.createClass({
<span className="little-spacer-right">
<QualifierIcon qualifier={this.props.project.qualifier}/>
</span>
- <a href={getProjectUrl(this.props.project.key)}>{this.props.project.name}</a>
+ <a href={getComponentUrl(this.props.project.key)}>{this.props.project.name}</a>
</td>
{permissions}
<td className="thin nowrap text-right">
import React from 'react';
-import {getProjectUrl} from '../../helpers/Url';
+import { getComponentUrl } from '../../helpers/urls';
import Checkbox from '../../components/shared/checkbox';
import QualifierIcon from '../../components/shared/qualifier-icon';
<QualifierIcon qualifier={project.qualifier}/>
</td>
<td className="nowrap">
- <a href={getProjectUrl(project.key)}>{project.name}</a>
+ <a href={getComponentUrl(project.key)}>{project.name}</a>
</td>
<td className="nowrap">
<span className="note">{project.key}</span>
+++ /dev/null
-export function getProjectUrl (project) {
- if (typeof project !== 'string') {
- throw new TypeError('Project ID or KEY should be passed');
- }
- return `${window.baseUrl}/dashboard?id=${encodeURIComponent(project)}`;
-}
-
-export function componentIssuesUrl (componentKey, query) {
- let serializedQuery = Object.keys(query).map(criterion => {
- return `${encodeURIComponent(criterion)}=${encodeURIComponent(query[criterion])}`;
- }).join('|');
- return window.baseUrl + '/component_issues?id=' + encodeURIComponent(componentKey) + '#' + serializedQuery;
-}
--- /dev/null
+/**
+ * Generate URL for a component's home page
+ * @param {string} componentKey
+ * @returns {string}
+ */
+export function getComponentUrl (componentKey) {
+ return window.baseUrl + '/dashboard?id=' + encodeURIComponent(componentKey);
+}
+
+
+/**
+ * Generate URL for a component's issues page
+ * @param {string} componentKey
+ * @param {object} query
+ * @returns {string}
+ */
+export function getComponentIssuesUrl (componentKey, query) {
+ let serializedQuery = Object.keys(query).map(criterion => {
+ return `${encodeURIComponent(criterion)}=${encodeURIComponent(query[criterion])}`;
+ }).join('|');
+ return window.baseUrl + '/component_issues?id=' + encodeURIComponent(componentKey) + '#' + serializedQuery;
+}
+
+
+/**
+ * Generate URL for a component's drilldown page
+ * @param {string} componentKey
+ * @param {string} metric
+ * @param {string|number} [period]
+ * @returns {string}
+ */
+export function getComponentDrilldownUrl (componentKey, metric, period) {
+ let url = window.baseUrl + '/drilldown/measures?id=' + encodeURIComponent(componentKey) +
+ '&metric=' + encodeURIComponent(metric);
+ if (period) {
+ url += '&period=' + period;
+ }
+ return url;
+}
--- /dev/null
+import { expect } from 'chai';
+
+import { getComponentUrl, getComponentIssuesUrl, getComponentDrilldownUrl } from '../../src/main/js/helpers/urls';
+
+
+const SIMPLE_COMPONENT_KEY = 'sonarqube';
+const COMPLEX_COMPONENT_KEY = 'org.sonarsource.sonarqube:sonarqube';
+const COMPLEX_COMPONENT_KEY_ENCODED = encodeURIComponent(COMPLEX_COMPONENT_KEY);
+const METRIC = 'coverage';
+const PERIOD = '3';
+
+
+describe('URLs', function () {
+ var oldBaseUrl;
+
+ beforeEach(function () {
+ oldBaseUrl = window.baseUrl;
+ });
+
+ afterEach(function () {
+ window.baseUrl = oldBaseUrl;
+ });
+
+ describe('#getComponentUrl', function () {
+ it('should return component url', function () {
+ expect(getComponentUrl(SIMPLE_COMPONENT_KEY)).to.equal('/dashboard?id=' + SIMPLE_COMPONENT_KEY);
+ });
+
+ it('should encode component key', function () {
+ expect(getComponentUrl(COMPLEX_COMPONENT_KEY)).to.equal('/dashboard?id=' + COMPLEX_COMPONENT_KEY_ENCODED);
+ });
+
+ it('should take baseUrl into account', function () {
+ window.baseUrl = '/context';
+ expect(getComponentUrl(COMPLEX_COMPONENT_KEY)).to.equal('/context/dashboard?id=' + COMPLEX_COMPONENT_KEY_ENCODED);
+ });
+ });
+
+ describe('#getComponentIssuesUrl', function () {
+ it('should work without parameters', function () {
+ expect(getComponentIssuesUrl(SIMPLE_COMPONENT_KEY, {})).to.equal(
+ '/component_issues?id=' + SIMPLE_COMPONENT_KEY + '#');
+ });
+
+ it('should encode component key', function () {
+ expect(getComponentIssuesUrl(COMPLEX_COMPONENT_KEY, {})).to.equal(
+ '/component_issues?id=' + COMPLEX_COMPONENT_KEY_ENCODED + '#');
+ });
+
+ it('should work with parameters', function () {
+ expect(getComponentIssuesUrl(SIMPLE_COMPONENT_KEY, { resolved: 'false' })).to.equal(
+ '/component_issues?id=' + SIMPLE_COMPONENT_KEY + '#resolved=false');
+ });
+
+ it('should encode parameters', function () {
+ expect(getComponentIssuesUrl(SIMPLE_COMPONENT_KEY, { componentUuids: COMPLEX_COMPONENT_KEY })).to.equal(
+ '/component_issues?id=' + SIMPLE_COMPONENT_KEY + '#componentUuids=' + COMPLEX_COMPONENT_KEY_ENCODED);
+ });
+
+ it('should take baseUrl into account', function () {
+ window.baseUrl = '/context';
+ expect(getComponentIssuesUrl(SIMPLE_COMPONENT_KEY, {})).to.equal(
+ '/context/component_issues?id=' + SIMPLE_COMPONENT_KEY + '#');
+ });
+ });
+
+ describe('#getComponentDrilldownUrl', function () {
+ it('should return component drilldown url', function () {
+ expect(getComponentDrilldownUrl(SIMPLE_COMPONENT_KEY, METRIC)).to.equal(
+ '/drilldown/measures?id=' + SIMPLE_COMPONENT_KEY + '&metric=' + METRIC);
+ });
+
+ it('should encode component key', function () {
+ expect(getComponentDrilldownUrl(COMPLEX_COMPONENT_KEY, METRIC)).to.equal(
+ '/drilldown/measures?id=' + COMPLEX_COMPONENT_KEY_ENCODED + '&metric=' + METRIC);
+ });
+
+ it('should work with period', function () {
+ expect(getComponentDrilldownUrl(SIMPLE_COMPONENT_KEY, METRIC, PERIOD)).to.equal(
+ '/drilldown/measures?id=' + SIMPLE_COMPONENT_KEY + '&metric=' + METRIC + '&period=' + PERIOD);
+ });
+
+ it('should take baseUrl into account', function () {
+ window.baseUrl = '/context';
+ expect(getComponentDrilldownUrl(SIMPLE_COMPONENT_KEY, METRIC)).to.equal(
+ '/context/drilldown/measures?id=' + SIMPLE_COMPONENT_KEY + '&metric=' + METRIC);
+ });
+ });
+});