diff options
author | Stas Vilchik <stas.vilchik@sonarsource.com> | 2018-10-31 14:23:33 +0100 |
---|---|---|
committer | SonarTech <sonartech@sonarsource.com> | 2018-11-07 20:21:03 +0100 |
commit | c7153cbc9057fa19651dba01c8d9c94ff5e1f4b2 (patch) | |
tree | c3e728ec71675c5c5a1913a489fe2c2abf383452 /server/sonar-web | |
parent | 87ba8f35bf6999bd2f5017f9ed26bdd0caca6935 (diff) | |
download | sonarqube-c7153cbc9057fa19651dba01c8d9c94ff5e1f4b2.tar.gz sonarqube-c7153cbc9057fa19651dba01c8d9c94ff5e1f4b2.zip |
SONAR-11362 apply feedback (#905)
Diffstat (limited to 'server/sonar-web')
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} />; |