diff options
author | Jeremy Davis <jeremy.davis@sonarsource.com> | 2019-06-18 16:21:01 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2019-06-28 08:45:43 +0200 |
commit | bf1a177bdd101ee445a502c969e125a1fe066e8d (patch) | |
tree | 3b211354ed1d5bffa435cc553a67d4e9f3c45fc9 /server/sonar-web | |
parent | d835fdaa1d594451b554af805db9869134c716df (diff) | |
download | sonarqube-bf1a177bdd101ee445a502c969e125a1fe066e8d.tar.gz sonarqube-bf1a177bdd101ee445a502c969e125a1fe066e8d.zip |
SONAR-12209 Prevent flashing page in PR QG overview
Diffstat (limited to 'server/sonar-web')
3 files changed, 96 insertions, 552 deletions
diff --git a/server/sonar-web/src/main/js/apps/overview/pullRequests/ReviewApp.tsx b/server/sonar-web/src/main/js/apps/overview/pullRequests/ReviewApp.tsx index ceee7deba0b..11905e375a1 100644 --- a/server/sonar-web/src/main/js/apps/overview/pullRequests/ReviewApp.tsx +++ b/server/sonar-web/src/main/js/apps/overview/pullRequests/ReviewApp.tsx @@ -26,7 +26,6 @@ import IssueLabel from './IssueLabel'; import IssueRating from './IssueRating'; import MeasurementLabel from './MeasurementLabel'; import { Alert } from '../../../components/ui/Alert'; -import DeferredSpinner from '../../../components/common/DeferredSpinner'; import DocTooltip from '../../../components/docs/DocTooltip'; import HelpTooltip from '../../../components/controls/HelpTooltip'; import QualityGateConditions from '../qualityGate/QualityGateConditions'; @@ -119,114 +118,119 @@ export class ReviewApp extends React.PureComponent<Props, State> { }; render() { - const { branchLike, component, conditions = [], ignoredConditions, status } = this.props; + const { branchLike, component, conditions, ignoredConditions, status } = this.props; const { loading, measures } = this.state; + + if (loading || !conditions) { + return ( + <div className="page page-limited"> + <i className="spinner" /> + </div> + ); + } + const erroredConditions = conditions.filter(condition => condition.level === 'ERROR'); return ( <div className="page page-limited"> - {loading ? ( - <DeferredSpinner /> - ) : ( - <div - className={classNames('pr-overview', { - 'has-conditions': erroredConditions.length > 0 - })}> - {ignoredConditions && ( - <Alert className="big-spacer-bottom" display="inline" variant="info"> - <span className="text-middle"> - {translate('overview.quality_gate.ignored_conditions')} - </span> - <HelpTooltip + <div + className={classNames('pr-overview', { + 'has-conditions': erroredConditions.length > 0 + })}> + {ignoredConditions && ( + <Alert className="big-spacer-bottom" display="inline" variant="info"> + <span className="text-middle"> + {translate('overview.quality_gate.ignored_conditions')} + </span> + <HelpTooltip + className="spacer-left" + overlay={translate('overview.quality_gate.ignored_conditions.tooltip')} + /> + </Alert> + )} + <div className="display-flex-row"> + <div className="pr-overview-quality-gate big-spacer-right"> + <h3 className="spacer-bottom small"> + {translate('overview.quality_gate')} + <DocTooltip className="spacer-left" - overlay={translate('overview.quality_gate.ignored_conditions.tooltip')} + doc={import(/* webpackMode: "eager" */ 'Docs/tooltips/quality-gates/project-homepage-quality-gate.md')} /> - </Alert> - )} - <div className="display-flex-row"> - <div className="pr-overview-quality-gate big-spacer-right"> - <h3 className="spacer-bottom small"> - {translate('overview.quality_gate')} - <DocTooltip - className="spacer-left" - doc={import(/* webpackMode: "eager" */ 'Docs/tooltips/quality-gates/project-homepage-quality-gate.md')} - /> - </h3> - <LargeQualityGateBadge component={component} level={status} /> - </div> + </h3> + <LargeQualityGateBadge component={component} level={status} /> + </div> - {erroredConditions.length > 0 && ( - <div className="pr-overview-failed-conditions big-spacer-right"> - <h3 className="spacer-bottom small">{translate('overview.failed_conditions')}</h3> - <QualityGateConditions - branchLike={branchLike} - collapsible={true} - component={component} - conditions={erroredConditions} - /> - </div> - )} + {erroredConditions.length > 0 && ( + <div className="pr-overview-failed-conditions big-spacer-right"> + <h3 className="spacer-bottom small">{translate('overview.failed_conditions')}</h3> + <QualityGateConditions + branchLike={branchLike} + collapsible={true} + component={component} + conditions={erroredConditions} + /> + </div> + )} - <div className="pr-overview-measurements flex-1"> - <h3 className="spacer-bottom small">{translate('overview.metrics')}</h3> + <div className="pr-overview-measurements flex-1"> + <h3 className="spacer-bottom small">{translate('overview.metrics')}</h3> - {['BUG', 'VULNERABILITY', 'CODE_SMELL'].map((type: IssueType) => ( - <div className="pr-overview-measurements-row display-flex-row" key={type}> + {['BUG', 'VULNERABILITY', 'CODE_SMELL'].map((type: IssueType) => ( + <div className="pr-overview-measurements-row display-flex-row" key={type}> + <div className="pr-overview-measurements-value flex-1 small display-flex-center"> + <IssueLabel + branchLike={branchLike} + className="overview-domain-measure-value" + component={component} + measures={measures} + type={type} + /> + </div> + {type === 'VULNERABILITY' && ( <div className="pr-overview-measurements-value flex-1 small display-flex-center"> <IssueLabel branchLike={branchLike} - className="overview-domain-measure-value" + className="huge" component={component} + docTooltip={import(/* webpackMode: "eager" */ 'Docs/tooltips/metrics/security-hotspots.md')} measures={measures} - type={type} - /> - </div> - {type === 'VULNERABILITY' && ( - <div className="pr-overview-measurements-value flex-1 small display-flex-center"> - <IssueLabel - branchLike={branchLike} - className="huge" - component={component} - docTooltip={import(/* webpackMode: "eager" */ 'Docs/tooltips/metrics/security-hotspots.md')} - measures={measures} - type="SECURITY_HOTSPOT" - /> - </div> - )} - <div className="pr-overview-measurements-rating display-flex-center"> - <IssueRating - branchLike={branchLike} - component={component} - measures={measures} - type={type} + type="SECURITY_HOTSPOT" /> </div> + )} + <div className="pr-overview-measurements-rating display-flex-center"> + <IssueRating + branchLike={branchLike} + component={component} + measures={measures} + type={type} + /> </div> - ))} - - {['COVERAGE', 'DUPLICATION'].map((type: MeasurementType) => ( - <div className="pr-overview-measurements-row display-flex-row" key={type}> - <div className="pr-overview-measurements-value flex-1 small display-flex-center"> - <MeasurementLabel - branchLike={branchLike} - className="overview-domain-measure-value" - component={component} - measures={measures} - type={type} - /> - </div> - - <AfterMergeEstimate - className="pr-overview-measurements-estimate" + </div> + ))} + + {['COVERAGE', 'DUPLICATION'].map((type: MeasurementType) => ( + <div className="pr-overview-measurements-row display-flex-row" key={type}> + <div className="pr-overview-measurements-value flex-1 small display-flex-center"> + <MeasurementLabel + branchLike={branchLike} + className="overview-domain-measure-value" + component={component} measures={measures} type={type} /> </div> - ))} - </div> + + <AfterMergeEstimate + className="pr-overview-measurements-estimate" + measures={measures} + type={type} + /> + </div> + ))} </div> </div> - )} + </div> </div> ); } diff --git a/server/sonar-web/src/main/js/apps/overview/pullRequests/__tests__/ReviewApp-test.tsx b/server/sonar-web/src/main/js/apps/overview/pullRequests/__tests__/ReviewApp-test.tsx index 565982b1825..cdbfe0d8ce5 100644 --- a/server/sonar-web/src/main/js/apps/overview/pullRequests/__tests__/ReviewApp-test.tsx +++ b/server/sonar-web/src/main/js/apps/overview/pullRequests/__tests__/ReviewApp-test.tsx @@ -48,8 +48,11 @@ beforeEach(() => { it('should render correctly for a passed QG', async () => { const fetchBranchStatus = jest.fn(); + const wrapper = shallowRender({ fetchBranchStatus, status: 'OK' }); + wrapper.setProps({ conditions: [] }); + await waitAndUpdate(wrapper); expect(wrapper).toMatchSnapshot(); @@ -60,7 +63,7 @@ it('should render correctly for a passed QG', async () => { }); it('should render correctly if conditions are ignored', async () => { - const wrapper = shallowRender({ ignoredConditions: true }); + const wrapper = shallowRender({ conditions: [], ignoredConditions: true }); await waitAndUpdate(wrapper); expect(wrapper.find('Alert').exists()).toBe(true); }); diff --git a/server/sonar-web/src/main/js/apps/overview/pullRequests/__tests__/__snapshots__/ReviewApp-test.tsx.snap b/server/sonar-web/src/main/js/apps/overview/pullRequests/__tests__/__snapshots__/ReviewApp-test.tsx.snap index 530b37dda8b..f23c3a895ff 100644 --- a/server/sonar-web/src/main/js/apps/overview/pullRequests/__tests__/__snapshots__/ReviewApp-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/overview/pullRequests/__tests__/__snapshots__/ReviewApp-test.tsx.snap @@ -4,472 +4,9 @@ exports[`should correctly handle a WS failure 1`] = ` <div className="page page-limited" > - <div - className="pr-overview" - > - <div - className="display-flex-row" - > - <div - className="pr-overview-quality-gate big-spacer-right" - > - <h3 - className="spacer-bottom small" - > - overview.quality_gate - <DocTooltip - className="spacer-left" - doc={Promise {}} - /> - </h3> - <LargeQualityGateBadge - component={ - Object { - "breadcrumbs": Array [], - "key": "my-project", - "name": "MyProject", - "organization": "foo", - "qualifier": "TRK", - "qualityGate": Object { - "isDefault": true, - "key": "30", - "name": "Sonar way", - }, - "qualityProfiles": Array [ - Object { - "deleted": false, - "key": "my-qp", - "language": "ts", - "name": "Sonar way", - }, - ], - "tags": Array [], - } - } - /> - </div> - <div - className="pr-overview-measurements flex-1" - > - <h3 - className="spacer-bottom small" - > - overview.metrics - </h3> - <div - className="pr-overview-measurements-row display-flex-row" - key="BUG" - > - <div - className="pr-overview-measurements-value flex-1 small display-flex-center" - > - <IssueLabel - branchLike={ - Object { - "analysisDate": "2018-01-01", - "base": "master", - "branch": "feature/foo/bar", - "key": "1001", - "target": "master", - "title": "Foo Bar feature", - } - } - className="overview-domain-measure-value" - component={ - Object { - "breadcrumbs": Array [], - "key": "my-project", - "name": "MyProject", - "organization": "foo", - "qualifier": "TRK", - "qualityGate": Object { - "isDefault": true, - "key": "30", - "name": "Sonar way", - }, - "qualityProfiles": Array [ - Object { - "deleted": false, - "key": "my-qp", - "language": "ts", - "name": "Sonar way", - }, - ], - "tags": Array [], - } - } - measures={Array []} - type="BUG" - /> - </div> - <div - className="pr-overview-measurements-rating display-flex-center" - > - <IssueRating - branchLike={ - Object { - "analysisDate": "2018-01-01", - "base": "master", - "branch": "feature/foo/bar", - "key": "1001", - "target": "master", - "title": "Foo Bar feature", - } - } - component={ - Object { - "breadcrumbs": Array [], - "key": "my-project", - "name": "MyProject", - "organization": "foo", - "qualifier": "TRK", - "qualityGate": Object { - "isDefault": true, - "key": "30", - "name": "Sonar way", - }, - "qualityProfiles": Array [ - Object { - "deleted": false, - "key": "my-qp", - "language": "ts", - "name": "Sonar way", - }, - ], - "tags": Array [], - } - } - measures={Array []} - type="BUG" - /> - </div> - </div> - <div - className="pr-overview-measurements-row display-flex-row" - key="VULNERABILITY" - > - <div - className="pr-overview-measurements-value flex-1 small display-flex-center" - > - <IssueLabel - branchLike={ - Object { - "analysisDate": "2018-01-01", - "base": "master", - "branch": "feature/foo/bar", - "key": "1001", - "target": "master", - "title": "Foo Bar feature", - } - } - className="overview-domain-measure-value" - component={ - Object { - "breadcrumbs": Array [], - "key": "my-project", - "name": "MyProject", - "organization": "foo", - "qualifier": "TRK", - "qualityGate": Object { - "isDefault": true, - "key": "30", - "name": "Sonar way", - }, - "qualityProfiles": Array [ - Object { - "deleted": false, - "key": "my-qp", - "language": "ts", - "name": "Sonar way", - }, - ], - "tags": Array [], - } - } - measures={Array []} - type="VULNERABILITY" - /> - </div> - <div - className="pr-overview-measurements-value flex-1 small display-flex-center" - > - <IssueLabel - branchLike={ - Object { - "analysisDate": "2018-01-01", - "base": "master", - "branch": "feature/foo/bar", - "key": "1001", - "target": "master", - "title": "Foo Bar feature", - } - } - className="huge" - component={ - Object { - "breadcrumbs": Array [], - "key": "my-project", - "name": "MyProject", - "organization": "foo", - "qualifier": "TRK", - "qualityGate": Object { - "isDefault": true, - "key": "30", - "name": "Sonar way", - }, - "qualityProfiles": Array [ - Object { - "deleted": false, - "key": "my-qp", - "language": "ts", - "name": "Sonar way", - }, - ], - "tags": Array [], - } - } - docTooltip={Promise {}} - measures={Array []} - type="SECURITY_HOTSPOT" - /> - </div> - <div - className="pr-overview-measurements-rating display-flex-center" - > - <IssueRating - branchLike={ - Object { - "analysisDate": "2018-01-01", - "base": "master", - "branch": "feature/foo/bar", - "key": "1001", - "target": "master", - "title": "Foo Bar feature", - } - } - component={ - Object { - "breadcrumbs": Array [], - "key": "my-project", - "name": "MyProject", - "organization": "foo", - "qualifier": "TRK", - "qualityGate": Object { - "isDefault": true, - "key": "30", - "name": "Sonar way", - }, - "qualityProfiles": Array [ - Object { - "deleted": false, - "key": "my-qp", - "language": "ts", - "name": "Sonar way", - }, - ], - "tags": Array [], - } - } - measures={Array []} - type="VULNERABILITY" - /> - </div> - </div> - <div - className="pr-overview-measurements-row display-flex-row" - key="CODE_SMELL" - > - <div - className="pr-overview-measurements-value flex-1 small display-flex-center" - > - <IssueLabel - branchLike={ - Object { - "analysisDate": "2018-01-01", - "base": "master", - "branch": "feature/foo/bar", - "key": "1001", - "target": "master", - "title": "Foo Bar feature", - } - } - className="overview-domain-measure-value" - component={ - Object { - "breadcrumbs": Array [], - "key": "my-project", - "name": "MyProject", - "organization": "foo", - "qualifier": "TRK", - "qualityGate": Object { - "isDefault": true, - "key": "30", - "name": "Sonar way", - }, - "qualityProfiles": Array [ - Object { - "deleted": false, - "key": "my-qp", - "language": "ts", - "name": "Sonar way", - }, - ], - "tags": Array [], - } - } - measures={Array []} - type="CODE_SMELL" - /> - </div> - <div - className="pr-overview-measurements-rating display-flex-center" - > - <IssueRating - branchLike={ - Object { - "analysisDate": "2018-01-01", - "base": "master", - "branch": "feature/foo/bar", - "key": "1001", - "target": "master", - "title": "Foo Bar feature", - } - } - component={ - Object { - "breadcrumbs": Array [], - "key": "my-project", - "name": "MyProject", - "organization": "foo", - "qualifier": "TRK", - "qualityGate": Object { - "isDefault": true, - "key": "30", - "name": "Sonar way", - }, - "qualityProfiles": Array [ - Object { - "deleted": false, - "key": "my-qp", - "language": "ts", - "name": "Sonar way", - }, - ], - "tags": Array [], - } - } - measures={Array []} - type="CODE_SMELL" - /> - </div> - </div> - <div - className="pr-overview-measurements-row display-flex-row" - key="COVERAGE" - > - <div - className="pr-overview-measurements-value flex-1 small display-flex-center" - > - <MeasurementLabel - branchLike={ - Object { - "analysisDate": "2018-01-01", - "base": "master", - "branch": "feature/foo/bar", - "key": "1001", - "target": "master", - "title": "Foo Bar feature", - } - } - className="overview-domain-measure-value" - component={ - Object { - "breadcrumbs": Array [], - "key": "my-project", - "name": "MyProject", - "organization": "foo", - "qualifier": "TRK", - "qualityGate": Object { - "isDefault": true, - "key": "30", - "name": "Sonar way", - }, - "qualityProfiles": Array [ - Object { - "deleted": false, - "key": "my-qp", - "language": "ts", - "name": "Sonar way", - }, - ], - "tags": Array [], - } - } - measures={Array []} - type="COVERAGE" - /> - </div> - <AfterMergeEstimate - className="pr-overview-measurements-estimate" - measures={Array []} - type="COVERAGE" - /> - </div> - <div - className="pr-overview-measurements-row display-flex-row" - key="DUPLICATION" - > - <div - className="pr-overview-measurements-value flex-1 small display-flex-center" - > - <MeasurementLabel - branchLike={ - Object { - "analysisDate": "2018-01-01", - "base": "master", - "branch": "feature/foo/bar", - "key": "1001", - "target": "master", - "title": "Foo Bar feature", - } - } - className="overview-domain-measure-value" - component={ - Object { - "breadcrumbs": Array [], - "key": "my-project", - "name": "MyProject", - "organization": "foo", - "qualifier": "TRK", - "qualityGate": Object { - "isDefault": true, - "key": "30", - "name": "Sonar way", - }, - "qualityProfiles": Array [ - Object { - "deleted": false, - "key": "my-qp", - "language": "ts", - "name": "Sonar way", - }, - ], - "tags": Array [], - } - } - measures={Array []} - type="DUPLICATION" - /> - </div> - <AfterMergeEstimate - className="pr-overview-measurements-estimate" - measures={Array []} - type="DUPLICATION" - /> - </div> - </div> - </div> - </div> + <i + className="spinner" + /> </div> `; |