diff options
author | Grégoire Aubert <gregoire.aubert@sonarsource.com> | 2017-05-23 13:53:41 +0200 |
---|---|---|
committer | Grégoire Aubert <gregoire.aubert@sonarsource.com> | 2017-06-09 08:26:48 +0200 |
commit | ea37577db04eba371145873d41ac8ad9cae9bb64 (patch) | |
tree | 523cfd63c8585b4ac5f21eea7c36a846ed09ad44 /server/sonar-web | |
parent | 1689d1f1ca71dfac66682fd87b4ce56ad58dfce0 (diff) | |
download | sonarqube-ea37577db04eba371145873d41ac8ad9cae9bb64.tar.gz sonarqube-ea37577db04eba371145873d41ac8ad9cae9bb64.zip |
SONAR-9256 Update project cards design on the projects page
Diffstat (limited to 'server/sonar-web')
14 files changed, 779 insertions, 618 deletions
diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectCard.js b/server/sonar-web/src/main/js/apps/projects/components/ProjectCard.js index f08708da24d..18b485bdcc8 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectCard.js +++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectCard.js @@ -72,10 +72,20 @@ export default function ProjectCard({ measures, organization, project, type }: P return ( <div data-key={project.key} className={className}> - {displayQualityGate && - <div className="boxed-group-actions"> - <ProjectCardQualityGate status={measures['alert_status']} /> - </div>} + + <div className="boxed-group-actions text-right"> + {project.visibility === 'private' && + <PrivateBadge className="spacer-left" tooltipPlacement="left" />} + {project.tags.length > 0 && <TagsList tags={project.tags} customClass="spacer-left" />} + {isLeakView && + isProjectAnalyzed && + <div className="little-spacer-top spacer-left note"> + {translateWithParameters( + 'overview.last_analysis_on_x', + moment(project.analysisDate).format('LLL') + )} + </div>} + </div> <div className="boxed-group-header"> {project.isFavorite != null && @@ -88,8 +98,7 @@ export default function ProjectCard({ measures, organization, project, type }: P </span>} <Link to={{ pathname: '/dashboard', query: { id: project.key } }}>{project.name}</Link> </h2> - {project.visibility === 'private' && <PrivateBadge className="spacer-left" />} - {project.tags.length > 0 && <TagsList tags={project.tags} customClass="spacer-left" />} + {displayQualityGate && <ProjectCardQualityGate status={measures['alert_status']} />} </div> {isProjectAnalyzed @@ -103,14 +112,6 @@ export default function ProjectCard({ measures, organization, project, type }: P {translate('projects.not_analyzed')} </div> </div>} - - {isProjectAnalyzed && - <div className="project-card-analysis-date note"> - {translateWithParameters( - 'overview.last_analysis_on_x', - moment(project.analysisDate).format('LLL') - )} - </div>} </div> ); } diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectCardLeakMeasures.js b/server/sonar-web/src/main/js/apps/projects/components/ProjectCardLeakMeasures.js index b1490444391..b42ea3bdd13 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectCardLeakMeasures.js +++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectCardLeakMeasures.js @@ -117,7 +117,7 @@ export default function ProjectCardLeakMeasures({ measures }: Props) { </div> {measures['new_lines'] != null && - <div className="project-card-measure smaller-card" data-key="new_lines"> + <div className="project-card-measure smaller-card pull-right" data-key="new_lines"> <div className="project-card-measure-inner"> <div className="project-card-measure-number"> <Measure diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectCardOverallMeasures.js b/server/sonar-web/src/main/js/apps/projects/components/ProjectCardOverallMeasures.js index 883b8039953..87ad40ee285 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectCardOverallMeasures.js +++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectCardOverallMeasures.js @@ -26,7 +26,6 @@ import CoverageRating from '../../../components/ui/CoverageRating'; import DuplicationsRating from '../../../components/ui/DuplicationsRating'; import SizeRating from '../../../components/ui/SizeRating'; import { translate } from '../../../helpers/l10n'; -import { formatMeasure } from '../../../helpers/measures'; type Props = { measures?: { [string]: string } @@ -95,9 +94,7 @@ export default function ProjectCardMeasures({ measures }: Props) { <div className="project-card-measure-number"> {measures['duplicated_lines_density'] != null && <span className="spacer-right"> - <DuplicationsRating - value={formatMeasure(measures['duplicated_lines_density'], 'FLOAT')} - /> + <DuplicationsRating value={Number(measures['duplicated_lines_density'])} /> </span>} <Measure measure={{ value: measures['duplicated_lines_density'] }} @@ -111,11 +108,11 @@ export default function ProjectCardMeasures({ measures }: Props) { </div> {measures['ncloc'] != null && - <div className="project-card-measure" data-key="ncloc"> + <div className="project-card-measure pull-right" data-key="ncloc"> <div className="project-card-measure-inner"> <div className="project-card-measure-number"> <span className="spacer-right"> - <SizeRating value={formatMeasure(measures['ncloc'], 'INT')} /> + <SizeRating value={Number(measures['ncloc'])} /> </span> <Measure measure={{ value: measures['ncloc'] }} diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectCardQualityGate.js b/server/sonar-web/src/main/js/apps/projects/components/ProjectCardQualityGate.js index 1c4995a8bb8..585c2648e1c 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectCardQualityGate.js +++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectCardQualityGate.js @@ -17,32 +17,30 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +//@flow import React from 'react'; import Level from '../../../components/ui/Level'; -import { translate } from '../../../helpers/l10n'; +import Tooltip from '../../../components/controls/Tooltip'; +import { formatMeasure } from '../../../helpers/measures'; +import { translateWithParameters } from '../../../helpers/l10n'; -export default class ProjectCardQualityGate extends React.PureComponent { - static propTypes = { - status: React.PropTypes.string - }; - - render() { - const { status } = this.props; +export default function ProjectCardQualityGate({ status }: { status?: string }) { + if (!status) { + return null; + } - if (!status) { - return null; - } + const tooltip = translateWithParameters( + 'overview.quality_gate_x', + formatMeasure(status, 'LEVEL') + ); - return ( - <div className="project-card-measure project-card-quality-gate"> + return ( + <div className="project-card-measure project-card-quality-gate spacer-left"> + <Tooltip overlay={tooltip}> <div className="project-card-measure-inner"> - <span className="small spacer-right"> - {translate('overview.quality_gate')} - {':'} - </span> <Level level={status} small={true} /> </div> - </div> - ); - } + </Tooltip> + </div> + ); } diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCard-test.js b/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCard-test.js index 3961e537d86..bb5b0ecef82 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCard-test.js +++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCard-test.js @@ -24,7 +24,7 @@ import ProjectCard from '../ProjectCard'; const PROJECT = { analysisDate: '2017-01-01', key: 'foo', name: 'Foo', tags: [] }; const MEASURES = {}; -it('should display analysis date', () => { +it('should not display analysis date', () => { expect( shallow(<ProjectCard measures={MEASURES} project={PROJECT} />).find( '.project-card-analysis-date' diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCardLeakMeasures-test.js b/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCardLeakMeasures-test.js new file mode 100644 index 00000000000..8ef407e3181 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCardLeakMeasures-test.js @@ -0,0 +1,61 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import React from 'react'; +import { shallow } from 'enzyme'; +import ProjectCardLeakMeasures from '../ProjectCardLeakMeasures'; + +const measures = { + alert_status: 'ERROR', + new_reliability_rating: '1.0', + new_bugs: '8', + new_security_rating: '2.0', + new_vulnerabilities: '2', + new_maintainability_rating: '1.0', + new_code_smells: '0', + new_coverage: '26.55', + new_duplicated_lines_density: '0.55', + new_lines: '87' +}; + +it('should render correctly with all data', () => { + const wrapper = shallow(<ProjectCardLeakMeasures measures={measures} />); + expect(wrapper).toMatchSnapshot(); +}); + +it('should not render new coverage', () => { + const wrapper = shallow( + <ProjectCardLeakMeasures measures={{ ...measures, new_coverage: undefined }} /> + ); + expect(wrapper.find('[data-key="new_coverage"]')).toMatchSnapshot(); +}); + +it('should not render new duplications', () => { + const wrapper = shallow( + <ProjectCardLeakMeasures measures={{ ...measures, new_duplicated_lines_density: undefined }} /> + ); + expect(wrapper.find('[data-key="new_duplicated_lines_density"]')).toMatchSnapshot(); +}); + +it('should not render new lines', () => { + const wrapper = shallow( + <ProjectCardLeakMeasures measures={{ ...measures, new_lines: undefined }} /> + ); + expect(wrapper.find('[data-key="new_lines"]')).toMatchSnapshot(); +}); diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCardMeasures-test.js b/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCardOverallMeasures-test.js index b0d6e3280b3..7ee12ea5dfa 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCardMeasures-test.js +++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCardOverallMeasures-test.js @@ -19,21 +19,35 @@ */ import React from 'react'; import { shallow } from 'enzyme'; -import ProjectCardMeasures from '../ProjectCardMeasures'; +import ProjectCardOverallMeasures from '../ProjectCardOverallMeasures'; -it('should not render coverage', () => { +it('should render correctly with all data', () => { const measures = { alert_status: 'ERROR', + coverage: '88.3', duplicated_lines_density: '9.8', ncloc: '2053', reliability_rating: '1.0', security_rating: '1.0', sqale_rating: '1.0' }; - const wrapper = shallow(<ProjectCardMeasures measures={measures} />); + const wrapper = shallow(<ProjectCardOverallMeasures measures={measures} />); expect(wrapper).toMatchSnapshot(); }); +it('should not render coverage', () => { + const measures = { + alert_status: 'ERROR', + duplicated_lines_density: '9.8', + ncloc: '2053', + reliability_rating: '1.0', + security_rating: '1.0', + sqale_rating: '1.0' + }; + const wrapper = shallow(<ProjectCardOverallMeasures measures={measures} />); + expect(wrapper.find('[data-key="coverage"]')).toMatchSnapshot(); +}); + it('should not render duplications', () => { const measures = { alert_status: 'ERROR', @@ -43,8 +57,8 @@ it('should not render duplications', () => { security_rating: '1.0', sqale_rating: '1.0' }; - const wrapper = shallow(<ProjectCardMeasures measures={measures} />); - expect(wrapper).toMatchSnapshot(); + const wrapper = shallow(<ProjectCardOverallMeasures measures={measures} />); + expect(wrapper.find('[data-key="duplicated_lines_density"]')).toMatchSnapshot(); }); it('should not render ncloc', () => { @@ -56,6 +70,20 @@ it('should not render ncloc', () => { security_rating: '1.0', sqale_rating: '1.0' }; - const wrapper = shallow(<ProjectCardMeasures measures={measures} />); - expect(wrapper).toMatchSnapshot(); + const wrapper = shallow(<ProjectCardOverallMeasures measures={measures} />); + expect(wrapper.find('[data-key="ncloc"]').length).toBe(0); +}); + +it('should render ncloc correctly', () => { + const measures = { + alert_status: 'ERROR', + coverage: '88.3', + ncloc: '16549887', + duplicated_lines_density: '9.8', + reliability_rating: '1.0', + security_rating: '1.0', + sqale_rating: '1.0' + }; + const wrapper = shallow(<ProjectCardOverallMeasures measures={measures} />); + expect(wrapper.find('[data-key="ncloc"]')).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PerspectiveSelect-test.js.snap b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PerspectiveSelect-test.js.snap index 8939575929b..b4ab927ee51 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PerspectiveSelect-test.js.snap +++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/PerspectiveSelect-test.js.snap @@ -66,6 +66,11 @@ exports[`should render correctly 1`] = ` "value": "overall", }, Object { + "label": "projects.view.leak", + "type": "view", + "value": "leak", + }, + Object { "label": "projects.visualization.risk", "type": "visualization", "value": "risk", @@ -156,6 +161,11 @@ exports[`should render with coverage selected 1`] = ` "value": "overall", }, Object { + "label": "projects.view.leak", + "type": "view", + "value": "leak", + }, + Object { "label": "projects.visualization.risk", "type": "visualization", "value": "risk", diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectCard-test.js.snap b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectCard-test.js.snap index 5221745c187..ff77d4e7b33 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectCard-test.js.snap +++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectCard-test.js.snap @@ -1,19 +1,14 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`should display analysis date 1`] = ` -<div - className="project-card-analysis-date note" -> - overview.last_analysis_on_x.January 1, 2017 12:00 AM -</div> -`; - exports[`should display loading 1`] = ` <div className="boxed-group project-card boxed-group-loading" data-key="foo" > <div + className="boxed-group-actions text-right" + /> + <div className="boxed-group-header" > <h2 @@ -37,11 +32,8 @@ exports[`should display loading 1`] = ` </div> <div className="boxed-group-inner" - /> - <div - className="project-card-analysis-date note" > - overview.last_analysis_on_x.January 1, 2017 12:00 AM + <ProjectCardMeasures /> </div> </div> `; @@ -52,6 +44,20 @@ exports[`should display tags 1`] = ` data-key="foo" > <div + className="boxed-group-actions text-right" + > + <TagsList + allowUpdate={false} + customClass="spacer-left" + tags={ + Array [ + "foo", + "bar", + ] + } + /> + </div> + <div className="boxed-group-header" > <h2 @@ -72,24 +78,13 @@ exports[`should display tags 1`] = ` Foo </Link> </h2> - <TagsList - allowUpdate={false} - customClass="spacer-left" - tags={ - Array [ - "foo", - "bar", - ] - } - /> </div> <div className="boxed-group-inner" - /> - <div - className="project-card-analysis-date note" > - overview.last_analysis_on_x.January 1, 2017 12:00 AM + <ProjectCardMeasures /> </div> </div> `; + +exports[`should not display analysis date 1`] = `undefined`; diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectCardLeakMeasures-test.js.snap b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectCardLeakMeasures-test.js.snap new file mode 100644 index 00000000000..9171745b0da --- /dev/null +++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectCardLeakMeasures-test.js.snap @@ -0,0 +1,291 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should not render new coverage 1`] = ` +<div + className="project-card-measure" + data-key="new_coverage" +> + <div + className="project-card-measure-inner" + > + <div + className="project-card-measure-number" + > + <Measure + measure={ + Object { + "leak": undefined, + } + } + metric={ + Object { + "key": "new_coverage", + "type": "PERCENT", + } + } + /> + </div> + <div + className="project-card-measure-label" + > + metric.new_coverage.name + </div> + </div> +</div> +`; + +exports[`should not render new duplications 1`] = ` +<div + className="project-card-measure" + data-key="new_duplicated_lines_density" +> + <div + className="project-card-measure-inner" + > + <div + className="project-card-measure-number" + > + <Measure + measure={ + Object { + "leak": undefined, + } + } + metric={ + Object { + "key": "new_duplicated_lines_density", + "type": "PERCENT", + } + } + /> + </div> + <div + className="project-card-measure-label" + > + metric.new_duplicated_lines_density.short_name + </div> + </div> +</div> +`; + +exports[`should not render new lines 1`] = `undefined`; + +exports[`should render correctly with all data 1`] = ` +<div + className="project-card-leak-measures" +> + <div + className="project-card-measure smaller-card" + data-key="new_reliability_rating" + > + <div + className="project-card-measure-inner" + > + <div + className="project-card-measure-number" + > + <Measure + className="spacer-right" + measure={ + Object { + "leak": "8", + } + } + metric={ + Object { + "key": "new_bugs", + "type": "SHORT_INT", + } + } + /> + <Rating + muted={false} + small={false} + value="1.0" + /> + </div> + <div + className="project-card-measure-label" + > + <BugIcon + className="little-spacer-right vertical-bottom" + /> + metric.new_bugs.name + </div> + </div> + </div> + <div + className="project-card-measure" + data-key="new_security_rating" + > + <div + className="project-card-measure-inner" + > + <div + className="project-card-measure-number" + > + <Measure + className="spacer-right" + measure={ + Object { + "leak": "2", + } + } + metric={ + Object { + "key": "new_vulnerabilities", + "type": "SHORT_INT", + } + } + /> + <Rating + muted={false} + small={false} + value="2.0" + /> + </div> + <div + className="project-card-measure-label" + > + <VulnerabilityIcon + className="little-spacer-right vertical-bottom" + /> + metric.new_vulnerabilities.name + </div> + </div> + </div> + <div + className="project-card-measure" + data-key="new_maintainability_rating" + > + <div + className="project-card-measure-inner" + > + <div + className="project-card-measure-number" + > + <Measure + className="spacer-right" + measure={ + Object { + "leak": "0", + } + } + metric={ + Object { + "key": "new_code_smells", + "type": "SHORT_INT", + } + } + /> + <Rating + muted={false} + small={false} + value="1.0" + /> + </div> + <div + className="project-card-measure-label" + > + <CodeSmellIcon + className="little-spacer-right vertical-bottom" + /> + metric.new_code_smells.name + </div> + </div> + </div> + <div + className="project-card-measure" + data-key="new_coverage" + > + <div + className="project-card-measure-inner" + > + <div + className="project-card-measure-number" + > + <Measure + measure={ + Object { + "leak": "26.55", + } + } + metric={ + Object { + "key": "new_coverage", + "type": "PERCENT", + } + } + /> + </div> + <div + className="project-card-measure-label" + > + metric.new_coverage.name + </div> + </div> + </div> + <div + className="project-card-measure" + data-key="new_duplicated_lines_density" + > + <div + className="project-card-measure-inner" + > + <div + className="project-card-measure-number" + > + <Measure + measure={ + Object { + "leak": "0.55", + } + } + metric={ + Object { + "key": "new_duplicated_lines_density", + "type": "PERCENT", + } + } + /> + </div> + <div + className="project-card-measure-label" + > + metric.new_duplicated_lines_density.short_name + </div> + </div> + </div> + <div + className="project-card-measure smaller-card pull-right" + data-key="new_lines" + > + <div + className="project-card-measure-inner" + > + <div + className="project-card-measure-number" + > + <Measure + measure={ + Object { + "leak": "87", + } + } + metric={ + Object { + "key": "new_lines", + "type": "SHORT_INT", + } + } + /> + </div> + <div + className="project-card-measure-label" + > + metric.new_lines.short_name + </div> + </div> + </div> +</div> +`; diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectCardMeasures-test.js.snap b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectCardMeasures-test.js.snap deleted file mode 100644 index 787d967682c..00000000000 --- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectCardMeasures-test.js.snap +++ /dev/null @@ -1,531 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should not render coverage 1`] = ` -<div - className="project-card-measures" -> - <div - className="project-card-measure" - data-key="reliability_rating" - > - <div - className="project-card-measure-inner" - > - <div - className="project-card-measure-number" - > - <Rating - muted={false} - small={false} - value="1.0" - /> - </div> - <div - className="project-card-measure-label" - > - metric_domain.Reliability - </div> - </div> - </div> - <div - className="project-card-measure" - data-key="security_rating" - > - <div - className="project-card-measure-inner" - > - <div - className="project-card-measure-number" - > - <Rating - muted={false} - small={false} - value="1.0" - /> - </div> - <div - className="project-card-measure-label" - > - metric_domain.Security - </div> - </div> - </div> - <div - className="project-card-measure" - data-key="sqale_rating" - > - <div - className="project-card-measure-inner" - > - <div - className="project-card-measure-number" - > - <Rating - muted={false} - small={false} - value="1.0" - /> - </div> - <div - className="project-card-measure-label" - > - metric_domain.Maintainability - </div> - </div> - </div> - <div - className="project-card-measure" - data-key="coverage" - > - <div - className="project-card-measure-inner" - > - <div - className="project-card-measure-number" - > - <Measure - measure={ - Object { - "value": undefined, - } - } - metric={ - Object { - "key": "coverage", - "type": "PERCENT", - } - } - /> - </div> - <div - className="project-card-measure-label" - > - metric.coverage.name - </div> - </div> - </div> - <div - className="project-card-measure" - data-key="duplicated_lines_density" - > - <div - className="project-card-measure-inner" - > - <div - className="project-card-measure-number" - > - <span - className="spacer-right" - > - <DuplicationsRating - muted={false} - small={false} - value="9.8" - /> - </span> - <Measure - measure={ - Object { - "value": "9.8", - } - } - metric={ - Object { - "key": "duplicated_lines_density", - "type": "PERCENT", - } - } - /> - </div> - <div - className="project-card-measure-label" - > - metric.duplicated_lines_density.short_name - </div> - </div> - </div> - <div - className="project-card-measure" - data-key="ncloc" - > - <div - className="project-card-measure-inner" - > - <div - className="project-card-measure-number" - > - <span - className="spacer-right" - > - <SizeRating - muted={false} - small={false} - value="2053" - /> - </span> - <Measure - measure={ - Object { - "value": "2053", - } - } - metric={ - Object { - "key": "ncloc", - "type": "SHORT_INT", - } - } - /> - </div> - <div - className="project-card-measure-label" - > - <Connect(ProjectCardLanguages) /> - </div> - </div> - </div> -</div> -`; - -exports[`should not render duplications 1`] = ` -<div - className="project-card-measures" -> - <div - className="project-card-measure" - data-key="reliability_rating" - > - <div - className="project-card-measure-inner" - > - <div - className="project-card-measure-number" - > - <Rating - muted={false} - small={false} - value="1.0" - /> - </div> - <div - className="project-card-measure-label" - > - metric_domain.Reliability - </div> - </div> - </div> - <div - className="project-card-measure" - data-key="security_rating" - > - <div - className="project-card-measure-inner" - > - <div - className="project-card-measure-number" - > - <Rating - muted={false} - small={false} - value="1.0" - /> - </div> - <div - className="project-card-measure-label" - > - metric_domain.Security - </div> - </div> - </div> - <div - className="project-card-measure" - data-key="sqale_rating" - > - <div - className="project-card-measure-inner" - > - <div - className="project-card-measure-number" - > - <Rating - muted={false} - small={false} - value="1.0" - /> - </div> - <div - className="project-card-measure-label" - > - metric_domain.Maintainability - </div> - </div> - </div> - <div - className="project-card-measure" - data-key="coverage" - > - <div - className="project-card-measure-inner" - > - <div - className="project-card-measure-number" - > - <span - className="spacer-right" - > - <CoverageRating - muted={false} - size="normal" - value="88.3" - /> - </span> - <Measure - measure={ - Object { - "value": "88.3", - } - } - metric={ - Object { - "key": "coverage", - "type": "PERCENT", - } - } - /> - </div> - <div - className="project-card-measure-label" - > - metric.coverage.name - </div> - </div> - </div> - <div - className="project-card-measure" - data-key="duplicated_lines_density" - > - <div - className="project-card-measure-inner" - > - <div - className="project-card-measure-number" - > - <Measure - measure={ - Object { - "value": undefined, - } - } - metric={ - Object { - "key": "duplicated_lines_density", - "type": "PERCENT", - } - } - /> - </div> - <div - className="project-card-measure-label" - > - metric.duplicated_lines_density.short_name - </div> - </div> - </div> - <div - className="project-card-measure" - data-key="ncloc" - > - <div - className="project-card-measure-inner" - > - <div - className="project-card-measure-number" - > - <span - className="spacer-right" - > - <SizeRating - muted={false} - small={false} - value="2053" - /> - </span> - <Measure - measure={ - Object { - "value": "2053", - } - } - metric={ - Object { - "key": "ncloc", - "type": "SHORT_INT", - } - } - /> - </div> - <div - className="project-card-measure-label" - > - <Connect(ProjectCardLanguages) /> - </div> - </div> - </div> -</div> -`; - -exports[`should not render ncloc 1`] = ` -<div - className="project-card-measures" -> - <div - className="project-card-measure" - data-key="reliability_rating" - > - <div - className="project-card-measure-inner" - > - <div - className="project-card-measure-number" - > - <Rating - muted={false} - small={false} - value="1.0" - /> - </div> - <div - className="project-card-measure-label" - > - metric_domain.Reliability - </div> - </div> - </div> - <div - className="project-card-measure" - data-key="security_rating" - > - <div - className="project-card-measure-inner" - > - <div - className="project-card-measure-number" - > - <Rating - muted={false} - small={false} - value="1.0" - /> - </div> - <div - className="project-card-measure-label" - > - metric_domain.Security - </div> - </div> - </div> - <div - className="project-card-measure" - data-key="sqale_rating" - > - <div - className="project-card-measure-inner" - > - <div - className="project-card-measure-number" - > - <Rating - muted={false} - small={false} - value="1.0" - /> - </div> - <div - className="project-card-measure-label" - > - metric_domain.Maintainability - </div> - </div> - </div> - <div - className="project-card-measure" - data-key="coverage" - > - <div - className="project-card-measure-inner" - > - <div - className="project-card-measure-number" - > - <span - className="spacer-right" - > - <CoverageRating - muted={false} - size="normal" - value="88.3" - /> - </span> - <Measure - measure={ - Object { - "value": "88.3", - } - } - metric={ - Object { - "key": "coverage", - "type": "PERCENT", - } - } - /> - </div> - <div - className="project-card-measure-label" - > - metric.coverage.name - </div> - </div> - </div> - <div - className="project-card-measure" - data-key="duplicated_lines_density" - > - <div - className="project-card-measure-inner" - > - <div - className="project-card-measure-number" - > - <span - className="spacer-right" - > - <DuplicationsRating - muted={false} - small={false} - value="9.8" - /> - </span> - <Measure - measure={ - Object { - "value": "9.8", - } - } - metric={ - Object { - "key": "duplicated_lines_density", - "type": "PERCENT", - } - } - /> - </div> - <div - className="project-card-measure-label" - > - metric.duplicated_lines_density.short_name - </div> - </div> - </div> -</div> -`; diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectCardOverallMeasures-test.js.snap b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectCardOverallMeasures-test.js.snap new file mode 100644 index 00000000000..b5431a1454a --- /dev/null +++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectCardOverallMeasures-test.js.snap @@ -0,0 +1,308 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should not render coverage 1`] = ` +<div + className="project-card-measure" + data-key="coverage" +> + <div + className="project-card-measure-inner" + > + <div + className="project-card-measure-number" + > + <Measure + measure={ + Object { + "value": undefined, + } + } + metric={ + Object { + "key": "coverage", + "type": "PERCENT", + } + } + /> + </div> + <div + className="project-card-measure-label" + > + metric.coverage.name + </div> + </div> +</div> +`; + +exports[`should not render duplications 1`] = ` +<div + className="project-card-measure" + data-key="duplicated_lines_density" +> + <div + className="project-card-measure-inner" + > + <div + className="project-card-measure-number" + > + <Measure + measure={ + Object { + "value": undefined, + } + } + metric={ + Object { + "key": "duplicated_lines_density", + "type": "PERCENT", + } + } + /> + </div> + <div + className="project-card-measure-label" + > + metric.duplicated_lines_density.short_name + </div> + </div> +</div> +`; + +exports[`should render correctly with all data 1`] = ` +<div + className="project-card-measures" +> + <div + className="project-card-measure smaller-card" + data-key="reliability_rating" + > + <div + className="project-card-measure-inner" + > + <div + className="project-card-measure-number" + > + <Rating + muted={false} + small={false} + value="1.0" + /> + </div> + <div + className="project-card-measure-label" + > + metric_domain.Reliability + </div> + </div> + </div> + <div + className="project-card-measure smaller-card" + data-key="security_rating" + > + <div + className="project-card-measure-inner" + > + <div + className="project-card-measure-number" + > + <Rating + muted={false} + small={false} + value="1.0" + /> + </div> + <div + className="project-card-measure-label" + > + metric_domain.Security + </div> + </div> + </div> + <div + className="project-card-measure" + data-key="sqale_rating" + > + <div + className="project-card-measure-inner" + > + <div + className="project-card-measure-number" + > + <Rating + muted={false} + small={false} + value="1.0" + /> + </div> + <div + className="project-card-measure-label" + > + metric_domain.Maintainability + </div> + </div> + </div> + <div + className="project-card-measure" + data-key="coverage" + > + <div + className="project-card-measure-inner" + > + <div + className="project-card-measure-number" + > + <span + className="spacer-right" + > + <CoverageRating + muted={false} + size="normal" + value="88.3" + /> + </span> + <Measure + measure={ + Object { + "value": "88.3", + } + } + metric={ + Object { + "key": "coverage", + "type": "PERCENT", + } + } + /> + </div> + <div + className="project-card-measure-label" + > + metric.coverage.name + </div> + </div> + </div> + <div + className="project-card-measure" + data-key="duplicated_lines_density" + > + <div + className="project-card-measure-inner" + > + <div + className="project-card-measure-number" + > + <span + className="spacer-right" + > + <DuplicationsRating + muted={false} + small={false} + value={9.8} + /> + </span> + <Measure + measure={ + Object { + "value": "9.8", + } + } + metric={ + Object { + "key": "duplicated_lines_density", + "type": "PERCENT", + } + } + /> + </div> + <div + className="project-card-measure-label" + > + metric.duplicated_lines_density.short_name + </div> + </div> + </div> + <div + className="project-card-measure pull-right" + data-key="ncloc" + > + <div + className="project-card-measure-inner" + > + <div + className="project-card-measure-number" + > + <span + className="spacer-right" + > + <SizeRating + muted={false} + small={false} + value={2053} + /> + </span> + <Measure + measure={ + Object { + "value": "2053", + } + } + metric={ + Object { + "key": "ncloc", + "type": "SHORT_INT", + } + } + /> + </div> + <div + className="project-card-measure-label" + > + <Connect(ProjectCardLanguages) /> + </div> + </div> + </div> +</div> +`; + +exports[`should render ncloc correctly 1`] = ` +<div + className="project-card-measure pull-right" + data-key="ncloc" +> + <div + className="project-card-measure-inner" + > + <div + className="project-card-measure-number" + > + <span + className="spacer-right" + > + <SizeRating + muted={false} + small={false} + value={16549887} + /> + </span> + <Measure + measure={ + Object { + "value": "16549887", + } + } + metric={ + Object { + "key": "ncloc", + "type": "SHORT_INT", + } + } + /> + </div> + <div + className="project-card-measure-label" + > + <Connect(ProjectCardLanguages) /> + </div> + </div> +</div> +`; diff --git a/server/sonar-web/src/main/js/apps/projects/styles.css b/server/sonar-web/src/main/js/apps/projects/styles.css index 5a94f6006a7..a5c32750f3c 100644 --- a/server/sonar-web/src/main/js/apps/projects/styles.css +++ b/server/sonar-web/src/main/js/apps/projects/styles.css @@ -87,11 +87,12 @@ .project-card-leak-measures { padding: 4px 0; - margin: 0 -4px 4px; + margin: 4px -4px; background-color: #fbf3d5; border: 1px solid #eae3c7; } + .project-card-measures .project-card-measure { width: 120px; box-sizing: border-box; @@ -136,10 +137,18 @@ content: ""; } +.project-card-measure.pull-right { + text-align: right; +} + .project-card-measure.pull-right:before { display: none; } +.project-card-measure.pull-right .project-card-measure-inner { + text-align: right; +} + .project-card-measure .level { margin-top: 0; margin-bottom: 0; @@ -173,13 +182,6 @@ line-height: 24px; } -.project-card-analysis-date { - margin-top: -15px; - padding-bottom: 5px; - padding-right: 20px; - text-align: right; -} - .project-card-not-analyzed { padding: 14px 0; } diff --git a/server/sonar-web/src/main/js/components/common/PrivateBadge.js b/server/sonar-web/src/main/js/components/common/PrivateBadge.js index 775c0727911..a949dc4d1dc 100644 --- a/server/sonar-web/src/main/js/components/common/PrivateBadge.js +++ b/server/sonar-web/src/main/js/components/common/PrivateBadge.js @@ -25,13 +25,14 @@ import { translate } from '../../helpers/l10n'; import './PrivateBadge.css'; type Props = { - className?: string + className?: string, + tooltipPlacement?: string }; -export default function PrivateBadge(props: Props) { +export default function PrivateBadge({ className, tooltipPlacement = 'bottom' }: Props) { return ( - <Tooltip overlay={translate('visibility.private.description')}> - <div className={classNames('private-badge', props.className)}> + <Tooltip overlay={translate('visibility.private.description')} placement={tooltipPlacement}> + <div className={classNames('private-badge', className)}> {translate('visibility.private')} </div> </Tooltip> |