Browse Source

always open default quality gate

tags/7.6
Stas Vilchik 5 years ago
parent
commit
e3b080e7a3

+ 28
- 32
server/sonar-web/src/main/js/apps/quality-gates/components/App.tsx View File

@@ -21,7 +21,6 @@ import * as React from 'react';
import { WithRouterProps } from 'react-router';
import Helmet from 'react-helmet';
import Details from './Details';
import Intro from './Intro';
import List from './List';
import ListHeader from './ListHeader';
import DeferredSpinner from '../../../components/common/DeferredSpinner';
@@ -60,6 +59,12 @@ class App extends React.PureComponent<Props, State> {
addSideBarClass();
}

componentDidUpdate(prevProps: Props) {
if (prevProps.params.id !== undefined && this.props.params.id === undefined) {
this.openDefault(this.state.qualityGates);
}
}

componentWillUnmount() {
this.mounted = false;
removeWhitePageClass();
@@ -73,10 +78,8 @@ class App extends React.PureComponent<Props, State> {
if (this.mounted) {
this.setState({ canCreate: actions.create, loading: false, qualityGates });

if (qualityGates && qualityGates.length === 1 && !actions.create) {
this.props.router.replace(
getQualityGateUrl(String(qualityGates[0].id), organization && organization.key)
);
if (!this.props.params.id) {
this.openDefault(qualityGates);
}
}
},
@@ -88,6 +91,14 @@ class App extends React.PureComponent<Props, State> {
);
};

openDefault(qualityGates: T.QualityGate[]) {
const defaultQualityGate = qualityGates.find(gate => Boolean(gate.isDefault))!;
const { organization } = this.props;
this.props.router.replace(
getQualityGateUrl(String(defaultQualityGate.id), organization && organization.key)
);
}

handleSetDefault = (qualityGate: T.QualityGate) => {
this.setState(({ qualityGates }) => {
return {
@@ -101,31 +112,8 @@ class App extends React.PureComponent<Props, State> {
});
};

renderContent() {
const { id } = this.props.params;
const organizationKey = this.props.organization && this.props.organization.key;
if (id !== undefined) {
return (
<Details
id={id}
onSetDefault={this.handleSetDefault}
organization={organizationKey}
qualityGates={this.state.qualityGates}
refreshQualityGates={this.fetchQualityGates}
/>
);
} else {
return (
<Intro
organization={organizationKey}
qualityGates={this.state.qualityGates}
router={this.props.router}
/>
);
}
}

render() {
const { id } = this.props.params;
const { canCreate, qualityGates } = this.state;
const defaultTitle = translate('quality_gates.page');
const organization = this.props.organization && this.props.organization.key;
@@ -146,16 +134,24 @@ class App extends React.PureComponent<Props, State> {
organization={organization}
refreshQualityGates={this.fetchQualityGates}
/>
{qualityGates.length > 0 && (
<DeferredSpinner loading={this.state.loading}>
<List organization={organization} qualityGates={qualityGates} />
)}
</DeferredSpinner>
</div>
</div>
</div>
)}
</ScreenPositionHelper>

<DeferredSpinner loading={this.state.loading}>{this.renderContent()}</DeferredSpinner>
{id !== undefined && (
<Details
id={id}
onSetDefault={this.handleSetDefault}
organization={organization}
qualityGates={this.state.qualityGates}
refreshQualityGates={this.fetchQualityGates}
/>
)}
</div>
</>
);

+ 27
- 26
server/sonar-web/src/main/js/apps/quality-gates/components/Details.tsx View File

@@ -26,6 +26,7 @@ import { getMetrics, Store } from '../../../store/rootReducer';
import { fetchMetrics } from '../../../store/rootActions';
import { fetchQualityGate } from '../../../api/quality-gates';
import { checkIfDefault, addCondition, replaceCondition, deleteCondition } from '../utils';
import DeferredSpinner from '../../../components/common/DeferredSpinner';

interface OwnProps {
id: string;
@@ -130,34 +131,34 @@ export class Details extends React.PureComponent<Props, State> {

render() {
const { organization, metrics, refreshQualityGates } = this.props;
const { qualityGate } = this.state;

if (!qualityGate) {
return null;
}
const { loading, qualityGate } = this.state;

return (
<>
<Helmet title={qualityGate.name} />
<div className="layout-page-main">
<DetailsHeader
onSetDefault={this.handleSetDefault}
organization={organization}
qualityGate={qualityGate}
refreshItem={this.fetchDetails}
refreshList={refreshQualityGates}
/>
<DetailsContent
isDefault={checkIfDefault(qualityGate, this.props.qualityGates)}
metrics={metrics}
onAddCondition={this.handleAddCondition}
onRemoveCondition={this.handleRemoveCondition}
onSaveCondition={this.handleSaveCondition}
organization={organization}
qualityGate={qualityGate}
/>
</div>
</>
<div className="layout-page-main">
<DeferredSpinner loading={loading} timeout={200}>
{qualityGate && (
<>
<Helmet title={qualityGate.name} />
<DetailsHeader
onSetDefault={this.handleSetDefault}
organization={organization}
qualityGate={qualityGate}
refreshItem={this.fetchDetails}
refreshList={refreshQualityGates}
/>
<DetailsContent
isDefault={checkIfDefault(qualityGate, this.props.qualityGates)}
metrics={metrics}
onAddCondition={this.handleAddCondition}
onRemoveCondition={this.handleRemoveCondition}
onSaveCondition={this.handleSaveCondition}
organization={organization}
qualityGate={qualityGate}
/>
</>
)}
</DeferredSpinner>
</div>
);
}
}

+ 0
- 55
server/sonar-web/src/main/js/apps/quality-gates/components/Intro.tsx View File

@@ -1,55 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2019 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 * as React from 'react';
import { InjectedRouter } from 'react-router';
import { translate } from '../../../helpers/l10n';
import { getQualityGateUrl } from '../../../helpers/urls';

interface Props {
organization?: string;
qualityGates: T.QualityGate[];
router: InjectedRouter;
}

export default class Intro extends React.PureComponent<Props> {
componentDidMount() {
const defaultQualityGate = this.props.qualityGates.find(qualityGate =>
Boolean(qualityGate.isDefault)
);
if (defaultQualityGate) {
this.props.router.replace(
getQualityGateUrl(String(defaultQualityGate.id), this.props.organization)
);
}
}

render() {
return (
<div className="layout-page-main">
<div className="layout-page-main-inner">
<div className="search-navigator-intro markdown">
<p>{translate('quality_gates.intro.1')}</p>
<p>{translate('quality_gates.intro.2')}</p>
</div>
</div>
</div>
);
}
}

+ 0
- 40
server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/Intro-test.tsx View File

@@ -1,40 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2019 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 * as React from 'react';
import { shallow } from 'enzyme';
import Intro from '../Intro';

it('should redirect to detail of default quality gate', () => {
const replace = jest.fn();
shallow(
<Intro
organization="foo"
qualityGates={[{ id: 1, name: 'Bar', isDefault: true }]}
router={{ replace } as any}
/>
);
expect(replace).toHaveBeenCalledWith({ pathname: '/organizations/foo/quality_gates/show/1' });
});

it('should display the intro', () => {
expect(
shallow(<Intro organization="foo" qualityGates={[]} router={{} as any} />)
).toMatchSnapshot();
});

+ 0
- 22
server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/Intro-test.tsx.snap View File

@@ -1,22 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should display the intro 1`] = `
<div
className="layout-page-main"
>
<div
className="layout-page-main-inner"
>
<div
className="search-navigator-intro markdown"
>
<p>
quality_gates.intro.1
</p>
<p>
quality_gates.intro.2
</p>
</div>
</div>
</div>
`;

Loading…
Cancel
Save