aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>2017-10-17 16:17:11 +0200
committerGrégoire Aubert <gregoire.aubert@sonarsource.com>2017-10-23 08:01:13 -0700
commitbff95ad641af2546712ea61d38a259f0847343c5 (patch)
tree56a4e216e4068da8062a2b8b0fd40a3dbf85d2d0 /server
parent3979c1713989085fa72b7d355ed544197de5b283 (diff)
downloadsonarqube-bff95ad641af2546712ea61d38a259f0847343c5.tar.gz
sonarqube-bff95ad641af2546712ea61d38a259f0847343c5.zip
SONAR-9936 Update edition notification to be scoped to page and not whole administration
Diffstat (limited to 'server')
-rw-r--r--server/sonar-web/src/main/js/app/components/AdminContainer.tsx15
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.tsx14
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/settings/__tests__/SettingsNav-test.tsx19
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/SettingsNav-test.tsx.snap15
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/App.tsx25
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/AppContainer.tsx1
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/EditionBoxes.tsx7
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/PendingActions.tsx5
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/__tests__/EditionBoxes-test.tsx1
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/EditionsStatusNotif.tsx (renamed from server/sonar-web/src/main/js/app/components/nav/settings/SettingsEditionsNotif.tsx)34
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/LicenseEditionForm.tsx7
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/__tests__/EditionsStatusNotif-test.tsx (renamed from server/sonar-web/src/main/js/app/components/nav/settings/__tests__/SettingsEditionsNotif-test.tsx)8
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/__tests__/LicenseEditionForm-test.tsx23
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/EditionsStatusNotif-test.tsx.snap (renamed from server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/SettingsEditionsNotif-test.tsx.snap)24
-rw-r--r--server/sonar-web/src/main/js/store/appState/duck.ts21
-rw-r--r--server/sonar-web/src/main/less/components/alerts.less5
16 files changed, 103 insertions, 121 deletions
diff --git a/server/sonar-web/src/main/js/app/components/AdminContainer.tsx b/server/sonar-web/src/main/js/app/components/AdminContainer.tsx
index fec085b91f2..ea9c6f1301b 100644
--- a/server/sonar-web/src/main/js/app/components/AdminContainer.tsx
+++ b/server/sonar-web/src/main/js/app/components/AdminContainer.tsx
@@ -24,20 +24,17 @@ import { connect } from 'react-redux';
import SettingsNav from './nav/settings/SettingsNav';
import { getAppState } from '../../store/rootReducer';
import { getSettingsNavigation } from '../../api/nav';
-import { EditionStatus, getEditionStatus } from '../../api/marketplace';
-import { setAdminPages, setEditionStatus } from '../../store/appState/duck';
+import { setAdminPages } from '../../store/appState/duck';
import { translate } from '../../helpers/l10n';
import { Extension } from '../types';
interface Props {
appState: {
adminPages: Extension[];
- editionStatus?: EditionStatus;
organizationsEnabled: boolean;
};
location: {};
setAdminPages: (adminPages: Extension[]) => void;
- setEditionStatus: (editionStatus: EditionStatus) => void;
}
class AdminContainer extends React.PureComponent<Props> {
@@ -56,17 +53,16 @@ class AdminContainer extends React.PureComponent<Props> {
}
loadData() {
- Promise.all([getSettingsNavigation(), getEditionStatus()]).then(
- ([r, editionStatus]) => {
+ getSettingsNavigation().then(
+ r => {
this.props.setAdminPages(r.extensions);
- this.props.setEditionStatus(editionStatus);
},
() => {}
);
}
render() {
- const { adminPages, editionStatus, organizationsEnabled } = this.props.appState;
+ const { adminPages, organizationsEnabled } = this.props.appState;
// Check that the adminPages are loaded
if (!adminPages) {
@@ -80,7 +76,6 @@ class AdminContainer extends React.PureComponent<Props> {
<Helmet defaultTitle={defaultTitle} titleTemplate={'%s - ' + defaultTitle} />
<SettingsNav
customOrganizations={organizationsEnabled}
- editionStatus={editionStatus}
extensions={adminPages}
location={this.props.location}
/>
@@ -94,6 +89,6 @@ const mapStateToProps = (state: any) => ({
appState: getAppState(state)
});
-const mapDispatchToProps = { setAdminPages, setEditionStatus };
+const mapDispatchToProps = { setAdminPages };
export default connect(mapStateToProps, mapDispatchToProps)(AdminContainer as any);
diff --git a/server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.tsx b/server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.tsx
index b677146a392..7f7632d6630 100644
--- a/server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.tsx
+++ b/server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.tsx
@@ -21,14 +21,11 @@ import * as React from 'react';
import * as classNames from 'classnames';
import { IndexLink, Link } from 'react-router';
import ContextNavBar from '../../../../components/nav/ContextNavBar';
-import SettingsEditionsNotif from './SettingsEditionsNotif';
import NavBarTabs from '../../../../components/nav/NavBarTabs';
-import { EditionStatus } from '../../../../api/marketplace';
import { Extension } from '../../../types';
import { translate } from '../../../../helpers/l10n';
interface Props {
- editionStatus?: EditionStatus;
extensions: Extension[];
customOrganizations: boolean;
location: {};
@@ -75,7 +72,7 @@ export default class SettingsNav extends React.PureComponent<Props> {
};
render() {
- const { customOrganizations, editionStatus, extensions } = this.props;
+ const { customOrganizations, extensions } = this.props;
const isSecurity = this.isSecurityActive();
const isProjects = this.isProjectsActive();
const isSystem = this.isSystemActive();
@@ -94,15 +91,8 @@ export default class SettingsNav extends React.PureComponent<Props> {
const hasSupportExtension = extensionsWithoutSupport.length < extensions.length;
- let notifComponent;
- if (editionStatus && editionStatus.installationStatus !== 'NONE') {
- notifComponent = <SettingsEditionsNotif editionStatus={editionStatus} />;
- }
return (
- <ContextNavBar
- id="context-navigation"
- height={notifComponent ? 95 : 65}
- notif={notifComponent}>
+ <ContextNavBar id="context-navigation" height={65}>
<h1 className="navbar-context-header">
<strong>{translate('layout.settings')}</strong>
</h1>
diff --git a/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/SettingsNav-test.tsx b/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/SettingsNav-test.tsx
index f819af90c49..9650ec9f4a9 100644
--- a/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/SettingsNav-test.tsx
+++ b/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/SettingsNav-test.tsx
@@ -24,24 +24,7 @@ import SettingsNav from '../SettingsNav';
it('should work with extensions', () => {
const extensions = [{ key: 'foo', name: 'Foo' }];
const wrapper = shallow(
- <SettingsNav
- customOrganizations={false}
- editionStatus={{ installationStatus: 'NONE' }}
- extensions={extensions}
- location={{}}
- />
+ <SettingsNav customOrganizations={false} extensions={extensions} location={{}} />
);
expect(wrapper).toMatchSnapshot();
});
-
-it('should display an edition notification', () => {
- const wrapper = shallow(
- <SettingsNav
- customOrganizations={false}
- editionStatus={{ installationStatus: 'AUTOMATIC_IN_PROGRESS' }}
- extensions={[]}
- location={{}}
- />
- );
- expect({ ...wrapper.find('ContextNavBar').props(), children: [] }).toMatchSnapshot();
-});
diff --git a/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/SettingsNav-test.tsx.snap b/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/SettingsNav-test.tsx.snap
index 9dd9e567752..62c113f24bb 100644
--- a/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/SettingsNav-test.tsx.snap
+++ b/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/SettingsNav-test.tsx.snap
@@ -1,20 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`should display an edition notification 1`] = `
-Object {
- "children": Array [],
- "height": 95,
- "id": "context-navigation",
- "notif": <SettingsEditionsNotif
- editionStatus={
- Object {
- "installationStatus": "AUTOMATIC_IN_PROGRESS",
- }
- }
-/>,
-}
-`;
-
exports[`should work with extensions 1`] = `
<ContextNavBar
height={65}
diff --git a/server/sonar-web/src/main/js/apps/marketplace/App.tsx b/server/sonar-web/src/main/js/apps/marketplace/App.tsx
index 18fc8adaaee..02910f26c5e 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/App.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/App.tsx
@@ -22,6 +22,7 @@ import * as PropTypes from 'prop-types';
import { sortBy, uniqBy } from 'lodash';
import Helmet from 'react-helmet';
import Header from './Header';
+import EditionsStatusNotif from './components/EditionsStatusNotif';
import EditionBoxes from './EditionBoxes';
import Footer from './Footer';
import PendingActions from './PendingActions';
@@ -35,13 +36,12 @@ import {
Plugin,
PluginPending
} from '../../api/plugins';
-import { EditionStatus } from '../../api/marketplace';
+import { EditionStatus, getEditionStatus } from '../../api/marketplace';
import { RawQuery } from '../../helpers/query';
import { translate } from '../../helpers/l10n';
import { filterPlugins, parseQuery, Query, serializeQuery } from './utils';
export interface Props {
- editionStatus?: EditionStatus;
editionsUrl: string;
location: { pathname: string; query: RawQuery };
sonarqubeVersion: string;
@@ -49,6 +49,7 @@ export interface Props {
}
interface State {
+ editionStatus?: EditionStatus;
loading: boolean;
pending: {
installing: PluginPending[];
@@ -81,6 +82,7 @@ export default class App extends React.PureComponent<Props, State> {
componentDidMount() {
this.mounted = true;
this.fetchPendingPlugins();
+ this.fetchEditionStatus();
this.fetchQueryPlugins();
}
@@ -148,6 +150,19 @@ export default class App extends React.PureComponent<Props, State> {
() => {}
);
+ fetchEditionStatus = () =>
+ getEditionStatus().then(
+ editionStatus => {
+ if (this.mounted) {
+ this.updateEditionStatus(editionStatus);
+ }
+ },
+ () => {}
+ );
+
+ updateEditionStatus = (editionStatus: EditionStatus) =>
+ this.setState({ editionStatus: editionStatus });
+
updateQuery = (newQuery: Partial<Query>) => {
const query = serializeQuery({
...parseQuery(this.props.location.query),
@@ -160,18 +175,20 @@ export default class App extends React.PureComponent<Props, State> {
};
render() {
- const { plugins, pending } = this.state;
+ const { editionStatus, plugins, pending } = this.state;
const query = parseQuery(this.props.location.query);
const filteredPlugins = query.search ? filterPlugins(plugins, query.search) : plugins;
return (
<div className="page page-limited" id="marketplace-page">
<Helmet title={translate('marketplace.page')} />
+ {editionStatus && <EditionsStatusNotif editionStatus={editionStatus} />}
<Header />
<EditionBoxes
- editionStatus={this.props.editionStatus}
+ editionStatus={editionStatus}
editionsUrl={this.props.editionsUrl}
sonarqubeVersion={this.props.sonarqubeVersion}
updateCenterActive={this.props.updateCenterActive}
+ updateEditionStatus={this.updateEditionStatus}
/>
<PendingActions refreshPending={this.fetchPendingPlugins} pending={pending} />
<Search
diff --git a/server/sonar-web/src/main/js/apps/marketplace/AppContainer.tsx b/server/sonar-web/src/main/js/apps/marketplace/AppContainer.tsx
index 64794ebbda2..909f284fbdf 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/AppContainer.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/AppContainer.tsx
@@ -23,7 +23,6 @@ import { getAppState, getGlobalSettingValue } from '../../store/rootReducer';
import './style.css';
const mapStateToProps = (state: any) => ({
- editionStatus: getAppState(state).editionStatus,
editionsUrl: (getGlobalSettingValue(state, 'sonar.editions.jsonUrl') || {}).value,
sonarqubeVersion: getAppState(state).version,
updateCenterActive: (getGlobalSettingValue(state, 'sonar.updatecenter.activate') || {}).value
diff --git a/server/sonar-web/src/main/js/apps/marketplace/EditionBoxes.tsx b/server/sonar-web/src/main/js/apps/marketplace/EditionBoxes.tsx
index 58ffe846c63..e1f5f373f1f 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/EditionBoxes.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/EditionBoxes.tsx
@@ -30,6 +30,7 @@ export interface Props {
editionsUrl: string;
sonarqubeVersion: string;
updateCenterActive: boolean;
+ updateEditionStatus: (editionStatus: EditionStatus) => void;
}
interface State {
@@ -108,7 +109,11 @@ export default class EditionBoxes extends React.PureComponent<Props, State> {
)}
{installEdition && (
- <LicenseEditionForm edition={installEdition} onClose={this.handleCloseLicenseForm} />
+ <LicenseEditionForm
+ edition={installEdition}
+ onClose={this.handleCloseLicenseForm}
+ updateEditionStatus={this.props.updateEditionStatus}
+ />
)}
</div>
);
diff --git a/server/sonar-web/src/main/js/apps/marketplace/PendingActions.tsx b/server/sonar-web/src/main/js/apps/marketplace/PendingActions.tsx
index 921afeef3da..bc96da9bbf0 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/PendingActions.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/PendingActions.tsx
@@ -19,9 +19,9 @@
*/
import * as React from 'react';
import { FormattedMessage } from 'react-intl';
-import { translate } from '../../helpers/l10n';
-import { cancelPendingPlugins, PluginPending } from '../../api/plugins';
import RestartForm from '../../components/common/RestartForm';
+import { cancelPendingPlugins, PluginPending } from '../../api/plugins';
+import { translate } from '../../helpers/l10n';
interface Props {
pending: {
@@ -40,7 +40,6 @@ export default class PendingActions extends React.PureComponent<Props, State> {
state: State = { openRestart: false };
handleOpenRestart = () => this.setState({ openRestart: true });
-
hanleCloseRestart = () => this.setState({ openRestart: false });
handleRevert = () => {
diff --git a/server/sonar-web/src/main/js/apps/marketplace/__tests__/EditionBoxes-test.tsx b/server/sonar-web/src/main/js/apps/marketplace/__tests__/EditionBoxes-test.tsx
index c3525b0e304..e64c714577f 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/__tests__/EditionBoxes-test.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/__tests__/EditionBoxes-test.tsx
@@ -80,6 +80,7 @@ function getWrapper(props = {}) {
editionsUrl=""
sonarqubeVersion="6.7.5"
updateCenterActive={true}
+ updateEditionStatus={jest.fn()}
{...props}
/>
);
diff --git a/server/sonar-web/src/main/js/app/components/nav/settings/SettingsEditionsNotif.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/EditionsStatusNotif.tsx
index 5df886e38b2..1ef4aacc308 100644
--- a/server/sonar-web/src/main/js/app/components/nav/settings/SettingsEditionsNotif.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/EditionsStatusNotif.tsx
@@ -18,41 +18,53 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import NavBarNotif from '../../../../components/nav/NavBarNotif';
-import { EditionStatus } from '../../../../api/marketplace';
-import { translate } from '../../../../helpers/l10n';
+import RestartForm from '../../../components/common/RestartForm';
+import { EditionStatus } from '../../../api/marketplace';
+import { translate } from '../../../helpers/l10n';
interface Props {
editionStatus: EditionStatus;
}
-export default class SettingsEditionsNotif extends React.PureComponent<Props> {
+interface State {
+ openRestart: boolean;
+}
+
+export default class EditionsStatusNotif extends React.PureComponent<Props, State> {
+ state: State = { openRestart: false };
+
+ handleOpenRestart = () => this.setState({ openRestart: true });
+ hanleCloseRestart = () => this.setState({ openRestart: false });
+
render() {
const { editionStatus } = this.props;
-
if (editionStatus.installationStatus === 'AUTOMATIC_IN_PROGRESS') {
return (
- <NavBarNotif className="alert alert-info">
+ <div className="alert alert-page alert-info">
<i className="spinner spacer-right text-bottom" />
<span>{translate('marketplace.status.AUTOMATIC_IN_PROGRESS')}</span>
- </NavBarNotif>
+ </div>
);
} else if (editionStatus.installationStatus === 'AUTOMATIC_READY') {
return (
- <NavBarNotif className="alert alert-success">
+ <div className="alert alert-page alert-success">
<span>{translate('marketplace.status.AUTOMATIC_READY')}</span>
- </NavBarNotif>
+ <button className="js-restart spacer-left" onClick={this.handleOpenRestart}>
+ {translate('marketplace.restart')}
+ </button>
+ {this.state.openRestart && <RestartForm onClose={this.hanleCloseRestart} />}
+ </div>
);
} else if (
['MANUAL_IN_PROGRESS', 'AUTOMATIC_FAILURE'].includes(editionStatus.installationStatus)
) {
return (
- <NavBarNotif className="alert alert-danger">
+ <div className="alert alert-page alert-danger">
{translate('marketplace.status', editionStatus.installationStatus)}
<a className="little-spacer-left" href="https://www.sonarsource.com" target="_blank">
{translate('marketplace.how_to_install')}
</a>
- </NavBarNotif>
+ </div>
);
}
return null;
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/LicenseEditionForm.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/LicenseEditionForm.tsx
index 1f00178f113..fb513eba0bc 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/components/LicenseEditionForm.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/LicenseEditionForm.tsx
@@ -20,14 +20,13 @@
import * as React from 'react';
import Modal from 'react-modal';
import LicenseEditionSet from './LicenseEditionSet';
-import getStore from '../../../app/utils/getStore';
-import { setEditionStatus } from '../../../store/appState/duck';
-import { Edition, applyLicense } from '../../../api/marketplace';
+import { Edition, EditionStatus, applyLicense } from '../../../api/marketplace';
import { translate, translateWithParameters } from '../../../helpers/l10n';
export interface Props {
edition: Edition;
onClose: () => void;
+ updateEditionStatus: (editionStatus: EditionStatus) => void;
}
interface State {
@@ -66,7 +65,7 @@ export default class LicenseEditionForm extends React.PureComponent<Props, State
this.setState({ loading: true });
applyLicense({ license }).then(
editionStatus => {
- getStore().dispatch(setEditionStatus(editionStatus));
+ this.props.updateEditionStatus(editionStatus);
this.props.onClose();
},
() => {
diff --git a/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/SettingsEditionsNotif-test.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/EditionsStatusNotif-test.tsx
index 55612c06b34..48a65f4b20f 100644
--- a/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/SettingsEditionsNotif-test.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/EditionsStatusNotif-test.tsx
@@ -19,25 +19,25 @@
*/
import * as React from 'react';
import { shallow } from 'enzyme';
-import SettingsEditionsNotif from '../SettingsEditionsNotif';
+import EditionsStatusNotif from '../EditionsStatusNotif';
it('should display an in progress notif', () => {
const wrapper = shallow(
- <SettingsEditionsNotif editionStatus={{ installationStatus: 'AUTOMATIC_IN_PROGRESS' }} />
+ <EditionsStatusNotif editionStatus={{ installationStatus: 'AUTOMATIC_IN_PROGRESS' }} />
);
expect(wrapper).toMatchSnapshot();
});
it('should display an error notification', () => {
const wrapper = shallow(
- <SettingsEditionsNotif editionStatus={{ installationStatus: 'AUTOMATIC_FAILURE' }} />
+ <EditionsStatusNotif editionStatus={{ installationStatus: 'AUTOMATIC_FAILURE' }} />
);
expect(wrapper).toMatchSnapshot();
});
it('should display a ready notification', () => {
const wrapper = shallow(
- <SettingsEditionsNotif editionStatus={{ installationStatus: 'AUTOMATIC_READY' }} />
+ <EditionsStatusNotif editionStatus={{ installationStatus: 'AUTOMATIC_READY' }} />
);
expect(wrapper).toMatchSnapshot();
});
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/LicenseEditionForm-test.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/LicenseEditionForm-test.tsx
index 7dff71932d5..a08b002a718 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/LicenseEditionForm-test.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/LicenseEditionForm-test.tsx
@@ -22,10 +22,6 @@ import { shallow } from 'enzyme';
import { click } from '../../../../helpers/testUtils';
import LicenseEditionForm from '../LicenseEditionForm';
-jest.mock('../../../../app/utils/getStore', () => {
- const dispatch = jest.fn();
- return { default: () => ({ dispatch }) };
-});
jest.mock('../../../../api/marketplace', () => ({
applyLicense: jest.fn(() =>
Promise.resolve({ nextEditionKey: 'foo', installationStatus: 'AUTOMATIC_IN_PROGRESS' })
@@ -33,7 +29,6 @@ jest.mock('../../../../api/marketplace', () => ({
}));
const applyLicense = require('../../../../api/marketplace').applyLicense as jest.Mock<any>;
-const getStore = require('../../../../app/utils/getStore').default as jest.Mock<any>;
const DEFAULT_EDITION = {
key: 'foo',
@@ -46,7 +41,6 @@ const DEFAULT_EDITION = {
beforeEach(() => {
applyLicense.mockClear();
- getStore().dispatch.mockClear();
});
it('should display correctly', () => {
@@ -65,16 +59,27 @@ it('should correctly change the button based on the status', () => {
});
it('should update the edition status after install', async () => {
- const wrapper = getWrapper();
+ const updateEditionStatus = jest.fn();
+ const wrapper = getWrapper({ updateEditionStatus });
const form = wrapper.instance() as LicenseEditionForm;
form.mounted = true;
form.handleLicenseChange('mylicense', 'AUTOMATIC_INSTALL');
click(wrapper.find('button'));
expect(applyLicense).toHaveBeenCalledWith({ license: 'mylicense' });
await new Promise(setImmediate);
- expect(getStore().dispatch).toHaveBeenCalled();
+ expect(updateEditionStatus).toHaveBeenCalledWith({
+ nextEditionKey: 'foo',
+ installationStatus: 'AUTOMATIC_IN_PROGRESS'
+ });
});
function getWrapper(props = {}) {
- return shallow(<LicenseEditionForm edition={DEFAULT_EDITION} onClose={jest.fn()} {...props} />);
+ return shallow(
+ <LicenseEditionForm
+ edition={DEFAULT_EDITION}
+ onClose={jest.fn()}
+ updateEditionStatus={jest.fn()}
+ {...props}
+ />
+ );
}
diff --git a/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/SettingsEditionsNotif-test.tsx.snap b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/EditionsStatusNotif-test.tsx.snap
index 030ff105e6a..807a7c6714a 100644
--- a/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/SettingsEditionsNotif-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/EditionsStatusNotif-test.tsx.snap
@@ -1,18 +1,24 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should display a ready notification 1`] = `
-<NavBarNotif
- className="alert alert-success"
+<div
+ className="alert alert-page alert-success"
>
<span>
marketplace.status.AUTOMATIC_READY
</span>
-</NavBarNotif>
+ <button
+ className="js-restart spacer-left"
+ onClick={[Function]}
+ >
+ marketplace.restart
+ </button>
+</div>
`;
exports[`should display an error notification 1`] = `
-<NavBarNotif
- className="alert alert-danger"
+<div
+ className="alert alert-page alert-danger"
>
marketplace.status.AUTOMATIC_FAILURE
<a
@@ -22,12 +28,12 @@ exports[`should display an error notification 1`] = `
>
marketplace.how_to_install
</a>
-</NavBarNotif>
+</div>
`;
exports[`should display an in progress notif 1`] = `
-<NavBarNotif
- className="alert alert-info"
+<div
+ className="alert alert-page alert-info"
>
<i
className="spinner spacer-right text-bottom"
@@ -35,5 +41,5 @@ exports[`should display an in progress notif 1`] = `
<span>
marketplace.status.AUTOMATIC_IN_PROGRESS
</span>
-</NavBarNotif>
+</div>
`;
diff --git a/server/sonar-web/src/main/js/store/appState/duck.ts b/server/sonar-web/src/main/js/store/appState/duck.ts
index d783242272f..abb05d0b309 100644
--- a/server/sonar-web/src/main/js/store/appState/duck.ts
+++ b/server/sonar-web/src/main/js/store/appState/duck.ts
@@ -19,13 +19,11 @@
*/
import { Extension } from '../../app/types';
-import { EditionStatus } from '../../api/marketplace';
interface AppState {
adminPages?: Extension[];
authenticationError: boolean;
authorizationError: boolean;
- editionStatus?: EditionStatus;
organizationsEnabled: boolean;
qualifiers?: string[];
}
@@ -40,20 +38,11 @@ interface SetAdminPagesAction {
adminPages: Extension[];
}
-interface SetEditionStatusAction {
- type: 'SET_EDITION_STATUS';
- editionStatus: EditionStatus;
-}
-
interface RequireAuthorizationAction {
type: 'REQUIRE_AUTHORIZATION';
}
-export type Action =
- | SetAppStateAction
- | SetAdminPagesAction
- | SetEditionStatusAction
- | RequireAuthorizationAction;
+export type Action = SetAppStateAction | SetAdminPagesAction | RequireAuthorizationAction;
export function setAppState(appState: AppState): SetAppStateAction {
return {
@@ -70,10 +59,6 @@ export function requireAuthorization(): RequireAuthorizationAction {
return { type: 'REQUIRE_AUTHORIZATION' };
}
-export function setEditionStatus(editionStatus: EditionStatus): SetEditionStatusAction {
- return { type: 'SET_EDITION_STATUS', editionStatus };
-}
-
const defaultValue: AppState = {
authenticationError: false,
authorizationError: false,
@@ -89,10 +74,6 @@ export default function(state: AppState = defaultValue, action: Action): AppStat
return { ...state, adminPages: action.adminPages };
}
- if (action.type === 'SET_EDITION_STATUS') {
- return { ...state, editionStatus: action.editionStatus };
- }
-
if (action.type === 'REQUIRE_AUTHORIZATION') {
return { ...state, authorizationError: true };
}
diff --git a/server/sonar-web/src/main/less/components/alerts.less b/server/sonar-web/src/main/less/components/alerts.less
index 65694046261..ee471b96bbb 100644
--- a/server/sonar-web/src/main/less/components/alerts.less
+++ b/server/sonar-web/src/main/less/components/alerts.less
@@ -38,6 +38,11 @@
vertical-align: middle;
}
+.alert-page {
+ margin-bottom: 16px;
+ padding: 8px;
+}
+
.modal-alert {
margin: -10px -10px 16px;
padding: 10px;