aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web
diff options
context:
space:
mode:
authorStas Vilchik <stas.vilchik@sonarsource.com>2018-10-31 14:23:33 +0100
committerSonarTech <sonartech@sonarsource.com>2018-11-07 20:21:03 +0100
commitc7153cbc9057fa19651dba01c8d9c94ff5e1f4b2 (patch)
treec3e728ec71675c5c5a1913a489fe2c2abf383452 /server/sonar-web
parent87ba8f35bf6999bd2f5017f9ed26bdd0caca6935 (diff)
downloadsonarqube-c7153cbc9057fa19651dba01c8d9c94ff5e1f4b2.tar.gz
sonarqube-c7153cbc9057fa19651dba01c8d9c94ff5e1f4b2.zip
SONAR-11362 apply feedback (#905)
Diffstat (limited to 'server/sonar-web')
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMeta.tsx8
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavMeta-test.tsx.snap17
-rw-r--r--server/sonar-web/src/main/js/components/common/BranchMeasures.tsx89
-rw-r--r--server/sonar-web/src/main/js/components/common/__tests__/BranchMeasures-test.tsx23
-rw-r--r--server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/BranchMeasures-test.tsx.snap94
-rw-r--r--server/sonar-web/src/main/js/components/ui/DuplicationsRating.tsx14
6 files changed, 209 insertions, 36 deletions
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMeta.tsx b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMeta.tsx
index 217ee6d1976..d6f38f12a29 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMeta.tsx
+++ b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMeta.tsx
@@ -105,7 +105,7 @@ export function ComponentNavMeta({
<a
className="display-inline-flex-center big-spacer-right"
href={branchLike.url}
- rel="nofollow"
+ rel="noopener noreferrer"
target="_blank">
{translate('branches.see_the_pr')}
<DetachIcon className="little-spacer-left" size={12} />
@@ -116,7 +116,11 @@ export function ComponentNavMeta({
branchMeasures.length > 0 && (
<>
<span className="vertical-separator" />
- <BranchMeasures measures={branchMeasures} />
+ <BranchMeasures
+ branchLike={branchLike}
+ componentKey={component.key}
+ measures={branchMeasures}
+ />
</>
)}
</div>
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavMeta-test.tsx.snap b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavMeta-test.tsx.snap
index e9ad9057ec6..b0f425fc541 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavMeta-test.tsx.snap
+++ b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavMeta-test.tsx.snap
@@ -43,7 +43,7 @@ exports[`renders meta for pull request 1`] = `
<a
className="display-inline-flex-center big-spacer-right"
href="https://example.com/pull/1234"
- rel="nofollow"
+ rel="noopener noreferrer"
target="_blank"
>
branches.see_the_pr
@@ -107,6 +107,21 @@ exports[`renders status of short-living branch 1`] = `
className="vertical-separator"
/>
<BranchMeasures
+ branchLike={
+ Object {
+ "isMain": false,
+ "mergeBranch": "master",
+ "name": "feature",
+ "status": Object {
+ "bugs": 0,
+ "codeSmells": 2,
+ "qualityGateStatus": "ERROR",
+ "vulnerabilities": 3,
+ },
+ "type": "SHORT",
+ }
+ }
+ componentKey="foo"
measures={
Array [
Object {
diff --git a/server/sonar-web/src/main/js/components/common/BranchMeasures.tsx b/server/sonar-web/src/main/js/components/common/BranchMeasures.tsx
index cd9f2019fd1..680ef8e51cf 100644
--- a/server/sonar-web/src/main/js/components/common/BranchMeasures.tsx
+++ b/server/sonar-web/src/main/js/components/common/BranchMeasures.tsx
@@ -19,19 +19,24 @@
*/
import * as React from 'react';
import * as classNames from 'classnames';
-import { Measure } from '../../app/types';
+import { FormattedMessage } from 'react-intl';
+import { Link } from 'react-router';
+import { Measure, BranchLike } from '../../app/types';
import { getLeakValue } from '../measure/utils';
import CoverageRating from '../ui/CoverageRating';
import { formatMeasure } from '../../helpers/measures';
import HelpTooltip from '../controls/HelpTooltip';
import { translate } from '../../helpers/l10n';
import DuplicationsRating from '../ui/DuplicationsRating';
+import { getComponentDrilldownUrl } from '../../helpers/urls';
interface Props {
+ branchLike: BranchLike;
+ componentKey: string;
measures: Measure[];
}
-export default function BranchMeasures({ measures }: Props) {
+export default function BranchMeasures({ branchLike, componentKey, measures }: Props) {
const newCoverage = measures.find(measure => measure.metric === 'new_coverage');
const newDuplications = measures.find(
measure => measure.metric === 'new_duplicated_lines_density'
@@ -42,46 +47,94 @@ export default function BranchMeasures({ measures }: Props) {
return (
<div className="display-inline-flex-center">
- {newCoverage && <BranchCoverage measure={newCoverage} />}
- {newDuplications && (
- <BranchDuplications
- className={classNames({ 'big-spacer-left': Boolean(newCoverage) })}
- measure={newDuplications}
- />
- )}
+ <BranchCoverage branchLike={branchLike} componentKey={componentKey} measure={newCoverage} />
+ <BranchDuplications
+ branchLike={branchLike}
+ className="big-spacer-left"
+ componentKey={componentKey}
+ measure={newDuplications}
+ />
</div>
);
}
interface MeasureProps {
+ branchLike: BranchLike;
className?: string;
- measure: Measure;
+ componentKey: string;
+ measure: Measure | undefined;
}
-export function BranchCoverage({ className, measure }: MeasureProps) {
+export function BranchCoverage({ branchLike, className, componentKey, measure }: MeasureProps) {
const value = getLeakValue(measure);
return (
<div className={classNames('display-inline-flex-center', className)}>
<CoverageRating size="small" value={value} />
- <span className="little-spacer-left">{formatMeasure(value, 'PERCENT')}</span>
+ <span className="little-spacer-left">
+ {value !== undefined ? formatMeasure(value, 'PERCENT') : '–'}
+ </span>
<HelpTooltip
className="little-spacer-left"
- overlay={translate('branches.measures', measure.metric, 'help')}
+ overlay={
+ measure ? (
+ <FormattedMessage
+ defaultMessage={translate('branches.measures.new_coverage.help')}
+ id="branches.measures.new_coverage.help"
+ values={{
+ link: (
+ <Link
+ to={getComponentDrilldownUrl({
+ componentKey,
+ branchLike,
+ metric: 'new_coverage'
+ })}>
+ {translate('layout.measures')}
+ </Link>
+ )
+ }}
+ />
+ ) : (
+ translate('branches.measures.new_coverage.missing')
+ )
+ }
/>
</div>
);
}
-export function BranchDuplications({ className, measure }: MeasureProps) {
+export function BranchDuplications({ branchLike, className, componentKey, measure }: MeasureProps) {
const value = getLeakValue(measure);
- return value !== undefined ? (
+ return (
<div className={classNames('display-inline-flex-center', className)}>
<DuplicationsRating size="small" value={Number(value)} />
- <span className="little-spacer-left">{formatMeasure(value, 'PERCENT')}</span>
+ <span className="little-spacer-left">
+ {value !== undefined ? formatMeasure(value, 'PERCENT') : '–'}
+ </span>
<HelpTooltip
className="little-spacer-left"
- overlay={translate('branches.measures', measure.metric, 'help')}
+ overlay={
+ measure ? (
+ <FormattedMessage
+ defaultMessage={translate('branches.measures.new_duplicated_lines_density.help')}
+ id="branches.measures.new_duplicated_lines_density.help"
+ values={{
+ link: (
+ <Link
+ to={getComponentDrilldownUrl({
+ componentKey,
+ branchLike,
+ metric: 'new_duplicated_lines_density'
+ })}>
+ {translate('layout.measures')}
+ </Link>
+ )
+ }}
+ />
+ ) : (
+ translate('branches.measures.new_duplicated_lines_density.missing')
+ )
+ }
/>
</div>
- ) : null;
+ );
}
diff --git a/server/sonar-web/src/main/js/components/common/__tests__/BranchMeasures-test.tsx b/server/sonar-web/src/main/js/components/common/__tests__/BranchMeasures-test.tsx
index d0686833c12..c53ec9c6bd3 100644
--- a/server/sonar-web/src/main/js/components/common/__tests__/BranchMeasures-test.tsx
+++ b/server/sonar-web/src/main/js/components/common/__tests__/BranchMeasures-test.tsx
@@ -20,34 +20,47 @@
import * as React from 'react';
import { shallow } from 'enzyme';
import BranchMeasures, { BranchCoverage, BranchDuplications } from '../BranchMeasures';
+import { PullRequest } from '../../../app/types';
const MEASURES = [
{ metric: 'new_coverage', value: '0', periods: [{ index: 1, value: '95.9943' }] },
{ metric: 'new_duplicated_lines_density', periods: [{ index: 1, value: '3.5' }] }
];
+const pr: PullRequest = { base: 'master', branch: 'feature-x', key: '5', title: '' };
+
describe('BranchMeasures', () => {
it('should render coverage and duplications', () => {
- expect(shallow(<BranchMeasures measures={MEASURES} />)).toMatchSnapshot();
+ expect(
+ shallow(<BranchMeasures branchLike={pr} componentKey="foo" measures={MEASURES} />)
+ ).toMatchSnapshot();
});
it('should render correctly when coverage is missing', () => {
- expect(shallow(<BranchMeasures measures={[MEASURES[1]]} />)).toMatchSnapshot();
+ expect(
+ shallow(<BranchMeasures branchLike={pr} componentKey="foo" measures={[MEASURES[1]]} />)
+ ).toMatchSnapshot();
});
it('should not render anything', () => {
- expect(shallow(<BranchMeasures measures={[]} />).type()).toBeNull();
+ expect(
+ shallow(<BranchMeasures branchLike={pr} componentKey="foo" measures={[]} />).type()
+ ).toBeNull();
});
});
describe('BranchCoverage', () => {
it('should render correctly', () => {
- expect(shallow(<BranchCoverage measure={MEASURES[0]} />)).toMatchSnapshot();
+ expect(
+ shallow(<BranchCoverage branchLike={pr} componentKey="foo" measure={MEASURES[0]} />)
+ ).toMatchSnapshot();
});
});
describe('BranchDuplications', () => {
it('should render correctly', () => {
- expect(shallow(<BranchDuplications measure={MEASURES[1]} />)).toMatchSnapshot();
+ expect(
+ shallow(<BranchDuplications branchLike={pr} componentKey="foo" measure={MEASURES[1]} />)
+ ).toMatchSnapshot();
});
});
diff --git a/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/BranchMeasures-test.tsx.snap b/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/BranchMeasures-test.tsx.snap
index 225c5ad2089..6734123c4ca 100644
--- a/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/BranchMeasures-test.tsx.snap
+++ b/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/BranchMeasures-test.tsx.snap
@@ -15,7 +15,32 @@ exports[`BranchCoverage should render correctly 1`] = `
</span>
<HelpTooltip
className="little-spacer-left"
- overlay="branches.measures.new_coverage.help"
+ overlay={
+ <FormattedMessage
+ defaultMessage="branches.measures.new_coverage.help"
+ id="branches.measures.new_coverage.help"
+ values={
+ Object {
+ "link": <Link
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to={
+ Object {
+ "pathname": "/component_measures",
+ "query": Object {
+ "id": "foo",
+ "metric": "new_coverage",
+ "pullRequest": "5",
+ },
+ }
+ }
+ >
+ layout.measures
+ </Link>,
+ }
+ }
+ />
+ }
/>
</div>
`;
@@ -35,7 +60,32 @@ exports[`BranchDuplications should render correctly 1`] = `
</span>
<HelpTooltip
className="little-spacer-left"
- overlay="branches.measures.new_duplicated_lines_density.help"
+ overlay={
+ <FormattedMessage
+ defaultMessage="branches.measures.new_duplicated_lines_density.help"
+ id="branches.measures.new_duplicated_lines_density.help"
+ values={
+ Object {
+ "link": <Link
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to={
+ Object {
+ "pathname": "/component_measures",
+ "query": Object {
+ "id": "foo",
+ "metric": "new_duplicated_lines_density",
+ "pullRequest": "5",
+ },
+ }
+ }
+ >
+ layout.measures
+ </Link>,
+ }
+ }
+ />
+ }
/>
</div>
`;
@@ -44,8 +94,28 @@ exports[`BranchMeasures should render correctly when coverage is missing 1`] = `
<div
className="display-inline-flex-center"
>
+ <BranchCoverage
+ branchLike={
+ Object {
+ "base": "master",
+ "branch": "feature-x",
+ "key": "5",
+ "title": "",
+ }
+ }
+ componentKey="foo"
+ />
<BranchDuplications
- className=""
+ branchLike={
+ Object {
+ "base": "master",
+ "branch": "feature-x",
+ "key": "5",
+ "title": "",
+ }
+ }
+ className="big-spacer-left"
+ componentKey="foo"
measure={
Object {
"metric": "new_duplicated_lines_density",
@@ -66,6 +136,15 @@ exports[`BranchMeasures should render coverage and duplications 1`] = `
className="display-inline-flex-center"
>
<BranchCoverage
+ branchLike={
+ Object {
+ "base": "master",
+ "branch": "feature-x",
+ "key": "5",
+ "title": "",
+ }
+ }
+ componentKey="foo"
measure={
Object {
"metric": "new_coverage",
@@ -80,7 +159,16 @@ exports[`BranchMeasures should render coverage and duplications 1`] = `
}
/>
<BranchDuplications
+ branchLike={
+ Object {
+ "base": "master",
+ "branch": "feature-x",
+ "key": "5",
+ "title": "",
+ }
+ }
className="big-spacer-left"
+ componentKey="foo"
measure={
Object {
"metric": "new_duplicated_lines_density",
diff --git a/server/sonar-web/src/main/js/components/ui/DuplicationsRating.tsx b/server/sonar-web/src/main/js/components/ui/DuplicationsRating.tsx
index 29e51e0fca0..a46242de2b1 100644
--- a/server/sonar-web/src/main/js/components/ui/DuplicationsRating.tsx
+++ b/server/sonar-web/src/main/js/components/ui/DuplicationsRating.tsx
@@ -25,7 +25,7 @@ import './DuplicationsRating.css';
interface Props {
muted?: boolean;
size?: 'small' | 'normal' | 'big' | 'huge';
- value: number;
+ value: number | null | undefined;
}
export default function DuplicationsRating({ muted = false, size = 'normal', value }: Props) {
@@ -33,12 +33,12 @@ export default function DuplicationsRating({ muted = false, size = 'normal', val
'duplications-rating-small': size === 'small',
'duplications-rating-big': size === 'big',
'duplications-rating-huge': size === 'huge',
- 'duplications-rating-muted': muted,
- 'duplications-rating-A': inRange(value, 0, 3),
- 'duplications-rating-B': inRange(value, 3, 5),
- 'duplications-rating-C': inRange(value, 5, 10),
- 'duplications-rating-D': inRange(value, 10, 20),
- 'duplications-rating-E': value >= 20
+ 'duplications-rating-muted': muted || value == null || isNaN(value),
+ 'duplications-rating-A': inRange(value || 0, 0, 3),
+ 'duplications-rating-B': inRange(value || 0, 3, 5),
+ 'duplications-rating-C': inRange(value || 0, 5, 10),
+ 'duplications-rating-D': inRange(value || 0, 10, 20),
+ 'duplications-rating-E': (value || 0) >= 20
});
return <div className={className} />;