diff options
author | Stas Vilchik <stas.vilchik@sonarsource.com> | 2018-08-27 19:25:45 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2018-09-19 10:51:42 +0200 |
commit | 66855e8da8a901b2048797c79639b98a072be544 (patch) | |
tree | bde39d6c28aead7c0ef8019fe58774088a1e3f04 /server/sonar-web/src/main/js/apps/component-measures/components | |
parent | f8d65ba2d9c01d19080e401e03eac12a55c4d4eb (diff) | |
download | sonarqube-66855e8da8a901b2048797c79639b98a072be544.tar.gz sonarqube-66855e8da8a901b2048797c79639b98a072be544.zip |
SONAR-11164 improve display of empty measures page
Diffstat (limited to 'server/sonar-web/src/main/js/apps/component-measures/components')
4 files changed, 152 insertions, 111 deletions
diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/App.tsx b/server/sonar-web/src/main/js/apps/component-measures/components/App.tsx index 236c96619a2..8deaaf8742e 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/App.tsx +++ b/server/sonar-web/src/main/js/apps/component-measures/components/App.tsx @@ -89,13 +89,6 @@ export default class App extends React.PureComponent<Props, State> { componentDidMount() { this.mounted = true; - document.body.classList.add('white-page'); - document.documentElement.classList.add('white-page'); - const footer = document.getElementById('footer'); - if (footer) { - footer.classList.add('page-footer-with-sidebar'); - } - key.setScope('measures-files'); this.props.fetchMetrics(); this.fetchMeasures(this.props); @@ -111,6 +104,17 @@ export default class App extends React.PureComponent<Props, State> { } } + componentDidUpdate(_prevProps: Props, prevState: State) { + if (prevState.measures.length === 0 && this.state.measures.length > 0) { + document.body.classList.add('white-page'); + document.documentElement.classList.add('white-page'); + const footer = document.getElementById('footer'); + if (footer) { + footer.classList.add('page-footer-with-sidebar'); + } + } + } + componentWillUnmount() { this.mounted = false; @@ -194,12 +198,7 @@ export default class App extends React.PureComponent<Props, State> { renderContent = (displayOverview: boolean, query: Query, metric?: Metric) => { const { branchLike, component, fetchMeasures, metrics } = this.props; - const { leakPeriod, measures } = this.state; - - if (measures.length === 0) { - return <MeasuresEmpty />; - } - + const { leakPeriod } = this.state; if (displayOverview) { return ( <MeasureOverviewContainer @@ -251,28 +250,33 @@ export default class App extends React.PureComponent<Props, State> { const displayOverview = hasOverview && hasBubbleChart(query.metric); const metric = this.getSelectedMetric(query, displayOverview); return ( - <div className="layout-page" id="component-measures"> + <div id="component-measures"> <Suggestions suggestions="component_measures" /> <Helmet title={this.getHelmetTitle(query, displayOverview, metric)} /> - <ScreenPositionHelper className="layout-page-side-outer"> - {({ top }) => ( - <div className="layout-page-side" style={{ top }}> - <div className="layout-page-side-inner"> - <div className="layout-page-filters"> - <Sidebar - hasOverview={hasOverview} - measures={measures} - selectedMetric={metric ? metric.key : query.metric} - updateQuery={this.updateQuery} - /> + {measures.length > 0 ? ( + <div className="layout-page"> + <ScreenPositionHelper className="layout-page-side-outer"> + {({ top }) => ( + <div className="layout-page-side" style={{ top }}> + <div className="layout-page-side-inner"> + <div className="layout-page-filters"> + <Sidebar + hasOverview={hasOverview} + measures={measures} + selectedMetric={metric ? metric.key : query.metric} + updateQuery={this.updateQuery} + /> + </div> + </div> </div> - </div> - </div> - )} - </ScreenPositionHelper> - - {this.renderContent(displayOverview, query, metric)} + )} + </ScreenPositionHelper> + {this.renderContent(displayOverview, query, metric)} + </div> + ) : ( + <MeasuresEmpty branchLike={branchLike} /> + )} </div> ); } diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/MeasuresEmpty.tsx b/server/sonar-web/src/main/js/apps/component-measures/components/MeasuresEmpty.tsx index ea25a2d2f69..7b795fa6faa 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/MeasuresEmpty.tsx +++ b/server/sonar-web/src/main/js/apps/component-measures/components/MeasuresEmpty.tsx @@ -19,11 +19,22 @@ */ import * as React from 'react'; import { translate } from '../../../helpers/l10n'; +import { BranchLike } from '../../../app/types'; +import { isShortLivingBranch, isPullRequest } from '../../../helpers/branches'; + +interface Props { + branchLike?: BranchLike; +} + +export default function MeasuresEmpty({ branchLike }: Props) { + const message = + isShortLivingBranch(branchLike) || isPullRequest(branchLike) + ? translate('component_measures.no_coverage') + : translate('component_measures.empty'); -export default function MeasuresEmpty() { return ( - <div className="layout-page-main"> - <div className="note text-center">{translate('component_measures.empty')}</div> + <div className="page page-limited"> + <div className="note">{message}</div> </div> ); } diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/App-test.tsx b/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/App-test.tsx index c6505527b5e..a289907ff56 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/App-test.tsx +++ b/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/App-test.tsx @@ -77,3 +77,10 @@ it('should render a measure overview', async () => { await waitAndUpdate(wrapper); expect(wrapper.find('MeasureOverviewContainer')).toHaveLength(1); }); + +it('should render a message when there are no measures', async () => { + const fetchMeasures = jest.fn().mockResolvedValue({ component: COMPONENT, measures: [] }); + const wrapper = shallow(<App {...PROPS} fetchMeasures={fetchMeasures} />); + await waitAndUpdate(wrapper); + expect(wrapper).toMatchSnapshot(); +}); diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/__snapshots__/App-test.tsx.snap b/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/__snapshots__/App-test.tsx.snap index b0436ae2851..4c4df7e7538 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/__snapshots__/App-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/__snapshots__/App-test.tsx.snap @@ -1,8 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`should render correctly 1`] = ` +exports[`should render a message when there are no measures 1`] = ` <div - className="layout-page" id="component-measures" > <Suggestions @@ -13,94 +12,114 @@ exports[`should render correctly 1`] = ` encodeSpecialCharacters={true} title="Coverage" /> - <ScreenPositionHelper - className="layout-page-side-outer" + <MeasuresEmpty /> +</div> +`; + +exports[`should render correctly 1`] = ` +<div + id="component-measures" +> + <Suggestions + suggestions="component_measures" + /> + <HelmetWrapper + defer={true} + encodeSpecialCharacters={true} + title="Coverage" /> - <MeasureContentContainer - className="layout-page-main" - currentUser={ - Object { - "isLoggedIn": false, + <div + className="layout-page" + > + <ScreenPositionHelper + className="layout-page-side-outer" + /> + <MeasureContentContainer + className="layout-page-main" + currentUser={ + Object { + "isLoggedIn": false, + } } - } - fetchMeasures={ - [MockFunction] { - "calls": Array [ - Array [ - "foo", + fetchMeasures={ + [MockFunction] { + "calls": Array [ Array [ - "lines_to_cover", - "coverage", - "duplicated_lines_density", - "new_bugs", + "foo", + Array [ + "lines_to_cover", + "coverage", + "duplicated_lines_density", + "new_bugs", + ], + undefined, ], - undefined, ], - ], - "results": Array [ - Object { - "isThrow": false, - "value": Promise {}, - }, - ], - } - } - metric={ - Object { - "domain": "Coverage", - "id": "2", - "key": "coverage", - "name": "Coverage", - "type": "PERCENT", + "results": Array [ + Object { + "isThrow": false, + "value": Promise {}, + }, + ], + } } - } - metrics={ - Object { - "coverage": Object { + metric={ + Object { "domain": "Coverage", "id": "2", "key": "coverage", "name": "Coverage", "type": "PERCENT", - }, - "duplicated_lines_density": Object { - "domain": "Duplications", - "id": "3", - "key": "duplicated_lines_density", - "name": "Duplicated Lines (%)", - "type": "PERCENT", - }, - "lines_to_cover": Object { - "domain": "Coverage", - "id": "1", - "key": "lines_to_cover", - "name": "Lines to Cover", - "type": "INT", - }, - "new_bugs": Object { - "domain": "Reliability", - "id": "4", - "key": "new_bugs", - "name": "New Bugs", - "type": "INT", - }, + } } - } - rootComponent={ - Object { - "key": "foo", - "name": "Foo", - "qualifier": "TRK", + metrics={ + Object { + "coverage": Object { + "domain": "Coverage", + "id": "2", + "key": "coverage", + "name": "Coverage", + "type": "PERCENT", + }, + "duplicated_lines_density": Object { + "domain": "Duplications", + "id": "3", + "key": "duplicated_lines_density", + "name": "Duplicated Lines (%)", + "type": "PERCENT", + }, + "lines_to_cover": Object { + "domain": "Coverage", + "id": "1", + "key": "lines_to_cover", + "name": "Lines to Cover", + "type": "INT", + }, + "new_bugs": Object { + "domain": "Reliability", + "id": "4", + "key": "new_bugs", + "name": "New Bugs", + "type": "INT", + }, + } } - } - router={ - Object { - "push": [MockFunction], + rootComponent={ + Object { + "key": "foo", + "name": "Foo", + "qualifier": "TRK", + } } - } - selected="" - updateQuery={[Function]} - view="list" - /> + router={ + Object { + "push": [MockFunction], + } + } + selected="" + updateQuery={[Function]} + view="list" + /> + </div> </div> `; |