aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps/component-measures/components
diff options
context:
space:
mode:
authorStas Vilchik <stas.vilchik@sonarsource.com>2018-08-27 19:25:45 +0200
committersonartech <sonartech@sonarsource.com>2018-09-19 10:51:42 +0200
commit66855e8da8a901b2048797c79639b98a072be544 (patch)
treebde39d6c28aead7c0ef8019fe58774088a1e3f04 /server/sonar-web/src/main/js/apps/component-measures/components
parentf8d65ba2d9c01d19080e401e03eac12a55c4d4eb (diff)
downloadsonarqube-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')
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/components/App.tsx66
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/components/MeasuresEmpty.tsx17
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/components/__tests__/App-test.tsx7
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/components/__tests__/__snapshots__/App-test.tsx.snap173
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>
`;