diff options
author | Pascal Mugnier <pascal.mugnier@sonarsource.com> | 2018-04-11 14:32:57 +0200 |
---|---|---|
committer | SonarTech <sonartech@sonarsource.com> | 2018-04-17 20:20:47 +0200 |
commit | b9d7623d0ce7d804f0c5a6dcfc476ae96c9b8518 (patch) | |
tree | cbde1c6db4914aca80dd68f4660300b54ad4bb90 /server/sonar-web/src/main | |
parent | febe5e5d486667bb8c523825285f1c22e4a48bb6 (diff) | |
download | sonarqube-b9d7623d0ce7d804f0c5a6dcfc476ae96c9b8518.tar.gz sonarqube-b9d7623d0ce7d804f0c5a6dcfc476ae96c9b8518.zip |
GOV-288 Portfolio containing only provisioned projects is not 'empty'
Diffstat (limited to 'server/sonar-web/src/main')
9 files changed, 163 insertions, 71 deletions
diff --git a/server/sonar-web/src/main/js/apps/issues/components/App.tsx b/server/sonar-web/src/main/js/apps/issues/components/App.tsx index 37e354aca8d..a433057b301 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/App.tsx +++ b/server/sonar-web/src/main/js/apps/issues/components/App.tsx @@ -67,6 +67,7 @@ import { import { translate, translateWithParameters } from '../../../helpers/l10n'; import { RawQuery } from '../../../helpers/query'; import { scrollToElement } from '../../../helpers/scrolling'; +import EmptySearch from '../../../components/common/EmptySearch'; import Checkbox from '../../../components/controls/Checkbox'; import '../styles.css'; @@ -926,6 +927,17 @@ export default class App extends React.PureComponent<Props, State> { return null; } + let noIssuesMessage = null; + if (paging.total === 0) { + if (this.isFiltered()) { + noIssuesMessage = <EmptySearch />; + } else if (this.state.myIssues) { + noIssuesMessage = <NoMyIssues />; + } else { + noIssuesMessage = <NoIssues />; + } + } + return ( <div> {paging.total > 0 && ( @@ -949,8 +961,7 @@ export default class App extends React.PureComponent<Props, State> { <ListFooter count={issues.length} loadMore={this.fetchMoreIssues} total={paging.total} /> )} - {paging.total === 0 && - (this.state.myIssues && !this.isFiltered() ? <NoMyIssues /> : <NoIssues />)} + {noIssuesMessage} </div> ); } diff --git a/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.tsx b/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.tsx index 4a0fce06905..f1860ce427e 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.tsx +++ b/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.tsx @@ -45,6 +45,7 @@ import { isSameBranchLike, getBranchLikeQuery } from '../../../helpers/branches' import { fetchMetrics } from '../../../store/rootActions'; import { getMetrics } from '../../../store/rootReducer'; import { BranchLike, Component, Metric } from '../../../app/types'; +import { translate } from '../../../helpers/l10n'; import '../styles.css'; interface OwnProps { @@ -158,6 +159,10 @@ export class OverviewApp extends React.PureComponent<Props, State> { ? { index: 1 } : undefined; + isEmpty = () => + this.state.measures === undefined || + this.state.measures.find(measure => measure.metric.key === 'ncloc') === undefined; + renderLoading() { return ( <div className="text-center"> @@ -166,14 +171,22 @@ export class OverviewApp extends React.PureComponent<Props, State> { ); } - render() { - const { branchLike, component } = this.props; - const { loading, measures, periods, history, historyStartDate } = this.state; - - if (loading) { - return this.renderLoading(); - } + renderEmpty() { + return ( + <div className="overview-main page-main"> + <h3> + {!this.state.measures || + !this.state.measures.find(measure => measure.metric.key === 'projects') + ? translate('portfolio.app.empty') + : translate('portfolio.app.no_lines_of_code')} + </h3> + </div> + ); + } + renderMain() { + const { branchLike, component } = this.props; + const { periods, measures, history, historyStartDate } = this.state; const leakPeriod = component.qualifier === 'APP' ? this.getApplicationLeakPeriod() : getLeakPeriod(periods); const domainProps = { @@ -185,23 +198,40 @@ export class OverviewApp extends React.PureComponent<Props, State> { historyStartDate }; + if (this.isEmpty()) { + return this.renderEmpty(); + } + + return ( + <div className="overview-main page-main"> + {component.qualifier === 'APP' ? ( + <ApplicationQualityGate component={component} /> + ) : ( + <QualityGate branchLike={branchLike} component={component} measures={measures} /> + )} + + <div className="overview-domains-list"> + <BugsAndVulnerabilities {...domainProps} /> + <CodeSmells {...domainProps} /> + <Coverage {...domainProps} /> + <Duplications {...domainProps} /> + </div> + </div> + ); + } + + render() { + const { branchLike, component } = this.props; + const { loading, measures, history } = this.state; + + if (loading) { + return this.renderLoading(); + } + return ( <div className="page page-limited"> <div className="overview page-with-sidebar"> - <div className="overview-main page-main"> - {component.qualifier === 'APP' ? ( - <ApplicationQualityGate component={component} /> - ) : ( - <QualityGate branchLike={branchLike} component={component} measures={measures} /> - )} - - <div className="overview-domains-list"> - <BugsAndVulnerabilities {...domainProps} /> - <CodeSmells {...domainProps} /> - <Coverage {...domainProps} /> - <Duplications {...domainProps} /> - </div> - </div> + {this.renderMain()} <div className="overview-sidebar page-sidebar-fixed"> <Meta diff --git a/server/sonar-web/src/main/js/apps/overview/meta/MetaSize.tsx b/server/sonar-web/src/main/js/apps/overview/meta/MetaSize.tsx index 0fe760979f5..243a5765d77 100644 --- a/server/sonar-web/src/main/js/apps/overview/meta/MetaSize.tsx +++ b/server/sonar-web/src/main/js/apps/overview/meta/MetaSize.tsx @@ -34,21 +34,27 @@ interface Props { } export default class MetaSize extends React.PureComponent<Props> { - renderLoC = (ncloc: MeasureEnhanced) => ( + renderLoC = (ncloc?: MeasureEnhanced) => ( <div - id="overview-ncloc" className={classNames('overview-meta-size-ncloc', { 'is-half-width': this.props.component.qualifier === 'APP' - })}> - <span className="spacer-right"> - <SizeRating value={Number(ncloc.value)} /> - </span> - <DrilldownLink - branchLike={this.props.branchLike} - component={this.props.component.key} - metric="ncloc"> - {formatMeasure(ncloc.value, 'SHORT_INT')} - </DrilldownLink> + })} + id="overview-ncloc"> + {ncloc && ( + <span className="spacer-right"> + <SizeRating value={Number(ncloc.value)} /> + </span> + )} + {ncloc ? ( + <DrilldownLink + branchLike={this.props.branchLike} + component={this.props.component.key} + metric="ncloc"> + {formatMeasure(ncloc.value, 'SHORT_INT')} + </DrilldownLink> + ) : ( + <span>0</span> + )} <div className="spacer-top text-muted">{getMetricName('ncloc')}</div> </div> ); @@ -70,24 +76,27 @@ export default class MetaSize extends React.PureComponent<Props> { renderProjects = () => { const projects = this.props.measures.find(measure => measure.metric.key === 'projects'); - - return projects ? ( - <div id="overview-projects" className="overview-meta-size-ncloc is-half-width"> - <DrilldownLink - branchLike={this.props.branchLike} - component={this.props.component.key} - metric="projects"> - {formatMeasure(projects.value, 'SHORT_INT')} - </DrilldownLink> + return ( + <div className="overview-meta-size-ncloc is-half-width" id="overview-projects"> + {projects ? ( + <DrilldownLink + branchLike={this.props.branchLike} + component={this.props.component.key} + metric="projects"> + {formatMeasure(projects.value, 'SHORT_INT')} + </DrilldownLink> + ) : ( + <span>0</span> + )} <div className="spacer-top text-muted">{translate('metric.projects.name')}</div> </div> - ) : null; + ); }; render() { const ncloc = this.props.measures.find(measure => measure.metric.key === 'ncloc'); - if (ncloc == null) { + if (ncloc == null && this.props.component.qualifier !== 'APP') { return null; } diff --git a/server/sonar-web/src/main/js/apps/overview/styles.css b/server/sonar-web/src/main/js/apps/overview/styles.css index 5b556ae3a88..ac492720ff5 100644 --- a/server/sonar-web/src/main/js/apps/overview/styles.css +++ b/server/sonar-web/src/main/js/apps/overview/styles.css @@ -363,7 +363,8 @@ box-sizing: border-box; } -.overview-meta-size-ncloc a { +.overview-meta-size-ncloc a, +.overview-meta-size-ncloc span { line-height: var(--controlHeight); font-size: 18px; font-weight: 300; diff --git a/server/sonar-web/src/main/js/apps/portfolio/components/App.tsx b/server/sonar-web/src/main/js/apps/portfolio/components/App.tsx index ab35a37e8ae..188130d59e1 100644 --- a/server/sonar-web/src/main/js/apps/portfolio/components/App.tsx +++ b/server/sonar-web/src/main/js/apps/portfolio/components/App.tsx @@ -123,8 +123,11 @@ export class App extends React.PureComponent<Props, State> { renderEmpty() { return ( <div className="empty-search"> - <h3>{translate('portfolio.empty')}</h3> - <p>{translate('portfolio.empty.hint')}</p> + <h3> + {!this.state.measures || !this.state.measures['projects'] + ? translate('portfolio.empty') + : translate('portfolio.no_lines_of_code')} + </h3> </div> ); } @@ -188,8 +191,7 @@ export class App extends React.PureComponent<Props, State> { <h4 className="portfolio-meta-header"> {translate('overview.about_this_portfolio')} </h4> - {!this.isEmpty() && - !this.isNotComputed() && <Summary component={component} measures={measures!} />} + <Summary component={component} measures={measures || {}} /> </div> <div className="portfolio-meta-card"> diff --git a/server/sonar-web/src/main/js/apps/portfolio/components/RatingFreshness.tsx b/server/sonar-web/src/main/js/apps/portfolio/components/RatingFreshness.tsx index bb28c4be116..13c37926c03 100644 --- a/server/sonar-web/src/main/js/apps/portfolio/components/RatingFreshness.tsx +++ b/server/sonar-web/src/main/js/apps/portfolio/components/RatingFreshness.tsx @@ -33,9 +33,11 @@ export default function RatingFreshness({ lastChange, rating }: Props) { return ( <div className="portfolio-freshness"> {rating && ( - <> - {translate('portfolio.has_always_been')} <Rating small={true} value={rating} /> - </> + <FormattedMessage + defaultMessage={translate('portfolio.has_always_been_x')} + id="portfolio.has_always_been_x" + values={{ rating: <Rating small={true} value={rating} /> }} + /> )} </div> ); diff --git a/server/sonar-web/src/main/js/apps/portfolio/components/Summary.tsx b/server/sonar-web/src/main/js/apps/portfolio/components/Summary.tsx index b32e4cda434..7d438b6167f 100644 --- a/server/sonar-web/src/main/js/apps/portfolio/components/Summary.tsx +++ b/server/sonar-web/src/main/js/apps/portfolio/components/Summary.tsx @@ -40,17 +40,25 @@ export default function Summary({ component, measures }: Props) { <ul className="portfolio-grid"> <li> <div className="portfolio-measure-secondary-value"> - <Link to={getComponentDrilldownUrl(component.key, 'projects')}> - <Measure metricKey="projects" metricType="SHORT_INT" value={projects} /> - </Link> + {projects ? ( + <Link to={getComponentDrilldownUrl(component.key, 'projects')}> + <Measure metricKey="projects" metricType="SHORT_INT" value={projects} /> + </Link> + ) : ( + '0' + )} </div> <div className="spacer-top text-muted">{translate('projects')}</div> </li> <li> <div className="portfolio-measure-secondary-value"> - <Link to={getComponentDrilldownUrl(component.key, 'ncloc')}> - <Measure metricKey="ncloc" metricType="SHORT_INT" value={ncloc} /> - </Link> + {ncloc ? ( + <Link to={getComponentDrilldownUrl(component.key, 'ncloc')}> + <Measure metricKey="ncloc" metricType="SHORT_INT" value={ncloc} /> + </Link> + ) : ( + '0' + )} </div> <div className="spacer-top text-muted">{translate('metric.ncloc.name')}</div> </li> diff --git a/server/sonar-web/src/main/js/apps/portfolio/components/__tests__/__snapshots__/App-test.tsx.snap b/server/sonar-web/src/main/js/apps/portfolio/components/__tests__/__snapshots__/App-test.tsx.snap index 4a89b29c509..bee7a5e17b9 100644 --- a/server/sonar-web/src/main/js/apps/portfolio/components/__tests__/__snapshots__/App-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/portfolio/components/__tests__/__snapshots__/App-test.tsx.snap @@ -127,9 +127,6 @@ exports[`renders when portfolio is empty 1`] = ` <h3> portfolio.empty </h3> - <p> - portfolio.empty.hint - </p> </div> </div> <aside @@ -143,6 +140,20 @@ exports[`renders when portfolio is empty 1`] = ` > overview.about_this_portfolio </h4> + <Summary + component={ + Object { + "key": "foo", + "name": "Foo", + "qualifier": "TRK", + } + } + measures={ + Object { + "reliability_rating": "1", + } + } + /> </div> <div className="portfolio-meta-card" @@ -199,6 +210,20 @@ exports[`renders when portfolio is not computed 1`] = ` > overview.about_this_portfolio </h4> + <Summary + component={ + Object { + "key": "foo", + "name": "Foo", + "qualifier": "TRK", + } + } + measures={ + Object { + "ncloc": "173", + } + } + /> </div> <div className="portfolio-meta-card" diff --git a/server/sonar-web/src/main/js/apps/portfolio/components/__tests__/__snapshots__/RatingFreshness-test.tsx.snap b/server/sonar-web/src/main/js/apps/portfolio/components/__tests__/__snapshots__/RatingFreshness-test.tsx.snap index 4cb8a857051..e7bb08f34e3 100644 --- a/server/sonar-web/src/main/js/apps/portfolio/components/__tests__/__snapshots__/RatingFreshness-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/portfolio/components/__tests__/__snapshots__/RatingFreshness-test.tsx.snap @@ -32,13 +32,17 @@ exports[`renders has always been 1`] = ` <div className="portfolio-freshness" > - <React.Fragment> - portfolio.has_always_been - - <Rating - small={true} - value="A" - /> - </React.Fragment> + <FormattedMessage + defaultMessage="portfolio.has_always_been_x" + id="portfolio.has_always_been_x" + values={ + Object { + "rating": <Rating + small={true} + value="A" + />, + } + } + /> </div> `; |