aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps/system
diff options
context:
space:
mode:
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>2017-10-19 17:25:23 +0200
committerGrégoire Aubert <gregoire.aubert@sonarsource.com>2017-10-23 08:01:13 -0700
commit9538f9ae5502b33651f1d916ee69aaf74c121231 (patch)
treec050fe8f85aca1eac6d3fc916d318760aec89d43 /server/sonar-web/src/main/js/apps/system
parent2d568ff3830cef88392656119bd2485a9ae9c8e1 (diff)
downloadsonarqube-9538f9ae5502b33651f1d916ee69aaf74c121231.tar.gz
sonarqube-9538f9ae5502b33651f1d916ee69aaf74c121231.zip
SONAR-9953 SONAR-9354 SONAR-7663 Redesign and move system upgrade in the system info page
Diffstat (limited to 'server/sonar-web/src/main/js/apps/system')
-rw-r--r--server/sonar-web/src/main/js/apps/system/__tests__/utils-test.ts50
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/App.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/SystemUpgradeNotif.tsx71
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeForm.tsx89
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeIntermediate.tsx86
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeItem.tsx73
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeNotif.tsx81
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/SystemUpgradeForm-test.tsx75
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/SystemUpgradeIntermediate-test.tsx58
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/SystemUpgradeItem-test.tsx59
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/SystemUpgradeNotif-test.tsx123
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/__snapshots__/SystemUpgradeForm-test.tsx.snap100
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/__snapshots__/SystemUpgradeIntermediate-test.tsx.snap57
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/__snapshots__/SystemUpgradeItem-test.tsx.snap84
-rw-r--r--server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/__snapshots__/SystemUpgradeNotif-test.tsx.snap23
-rw-r--r--server/sonar-web/src/main/js/apps/system/styles.css14
-rw-r--r--server/sonar-web/src/main/js/apps/system/utils.ts19
17 files changed, 1061 insertions, 3 deletions
diff --git a/server/sonar-web/src/main/js/apps/system/__tests__/utils-test.ts b/server/sonar-web/src/main/js/apps/system/__tests__/utils-test.ts
index 98cea1804e5..c95be747821 100644
--- a/server/sonar-web/src/main/js/apps/system/__tests__/utils-test.ts
+++ b/server/sonar-web/src/main/js/apps/system/__tests__/utils-test.ts
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as u from '../utils';
-import { ClusterSysInfo, SysInfo } from '../../../api/system';
+import { ClusterSysInfo, SysInfo, SystemUpgrade } from '../../../api/system';
describe('parseQuery', () => {
it('should correctly parse the expand array', () => {
@@ -84,3 +84,51 @@ describe('getSystemLogsLevel', () => {
expect(u.getSystemLogsLevel({ System: {} } as SysInfo)).toBe('INFO');
});
});
+
+describe('sortUpgrades', () => {
+ it('should sort correctly versions', () => {
+ expect(
+ u.sortUpgrades([
+ { version: '5.4.2' },
+ { version: '5.10' },
+ { version: '5.1' },
+ { version: '5.4' }
+ ] as SystemUpgrade[])
+ ).toEqual([{ version: '5.10' }, { version: '5.4.2' }, { version: '5.4' }, { version: '5.1' }]);
+ expect(
+ u.sortUpgrades([
+ { version: '5.10' },
+ { version: '5.1.2' },
+ { version: '6.0' },
+ { version: '6.9' }
+ ] as SystemUpgrade[])
+ ).toEqual([{ version: '6.9' }, { version: '6.0' }, { version: '5.10' }, { version: '5.1.2' }]);
+ });
+});
+
+describe('groupUpgrades', () => {
+ it('should group correctly', () => {
+ expect(
+ u.groupUpgrades([
+ { version: '5.10' },
+ { version: '5.4.2' },
+ { version: '5.4' },
+ { version: '5.1' }
+ ] as SystemUpgrade[])
+ ).toEqual([
+ [{ version: '5.10' }, { version: '5.4.2' }, { version: '5.4' }, { version: '5.1' }]
+ ]);
+ expect(
+ u.groupUpgrades([
+ { version: '6.9' },
+ { version: '6.7' },
+ { version: '6.0' },
+ { version: '5.10' },
+ { version: '5.4.2' }
+ ] as SystemUpgrade[])
+ ).toEqual([
+ [{ version: '6.9' }, { version: '6.7' }, { version: '6.0' }],
+ [{ version: '5.10' }, { version: '5.4.2' }]
+ ]);
+ });
+});
diff --git a/server/sonar-web/src/main/js/apps/system/components/App.tsx b/server/sonar-web/src/main/js/apps/system/components/App.tsx
index 38679882597..c6d333563ab 100644
--- a/server/sonar-web/src/main/js/apps/system/components/App.tsx
+++ b/server/sonar-web/src/main/js/apps/system/components/App.tsx
@@ -23,6 +23,7 @@ import Helmet from 'react-helmet';
import ClusterSysInfos from './ClusterSysInfos';
import PageHeader from './PageHeader';
import StandaloneSysInfos from './StandaloneSysInfos';
+import SystemUpgradeNotif from './system-upgrade/SystemUpgradeNotif';
import { translate } from '../../../helpers/l10n';
import { ClusterSysInfo, getSystemInfo, SysInfo } from '../../../api/system';
import { getSystemLogsLevel, isCluster, parseQuery, Query, serializeQuery } from '../utils';
@@ -117,6 +118,7 @@ export default class App extends React.PureComponent<Props, State> {
return (
<div className="page page-limited">
<Helmet title={translate('system_info.page')} />
+ <SystemUpgradeNotif />
<PageHeader
loading={loading}
isCluster={isCluster(sysInfoData)}
diff --git a/server/sonar-web/src/main/js/apps/system/components/SystemUpgradeNotif.tsx b/server/sonar-web/src/main/js/apps/system/components/SystemUpgradeNotif.tsx
new file mode 100644
index 00000000000..cdb15d71939
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/system/components/SystemUpgradeNotif.tsx
@@ -0,0 +1,71 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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 { getSystemUpgrades, SystemUpgrade } from '../../../api/system';
+import { translate } from '../../../helpers/l10n';
+
+interface State {
+ systemUpgrades?: SystemUpgrade[];
+}
+
+export default class SystemUpgradeNotif extends React.PureComponent<{}, State> {
+ mounted: boolean;
+ state: State = {};
+
+ componentDidMount() {
+ this.mounted = true;
+ this.fetchSystemUpgrades();
+ }
+
+ componentWillUnmount() {
+ this.mounted = false;
+ }
+
+ fetchSystemUpgrades = () =>
+ getSystemUpgrades().then(
+ ({ upgrades }) => {
+ if (this.mounted) {
+ this.setState({ systemUpgrades: upgrades });
+ }
+ },
+ () => {}
+ );
+
+ handleLearnMore = () => {};
+
+ render() {
+ const { systemUpgrades } = this.state;
+
+ if (!systemUpgrades || systemUpgrades.length <= 0) {
+ return null;
+ }
+
+ return (
+ <div className="page-notifs">
+ <div className="alert alert-info">
+ {translate('system.new_version_available')}
+ <button className="spacer-left" onClick={this.handleLearnMore}>
+ {translate('learn_more')}
+ </button>
+ </div>
+ </div>
+ );
+ }
+}
diff --git a/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeForm.tsx b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeForm.tsx
new file mode 100644
index 00000000000..9370ea4493b
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeForm.tsx
@@ -0,0 +1,89 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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 Modal from 'react-modal';
+import SystemUpgradeItem from './SystemUpgradeItem';
+import { SystemUpgrade } from '../../../../api/system';
+import { translate } from '../../../../helpers/l10n';
+
+interface Props {
+ systemUpgrades: SystemUpgrade[][];
+ onClose: () => void;
+}
+
+interface State {
+ upgrading: boolean;
+}
+
+export default class SystemUpgradeForm extends React.PureComponent<Props, State> {
+ state: State = { upgrading: false };
+
+ getBadge = (idx: number) => {
+ if (this.props.systemUpgrades.length <= 1) {
+ return undefined;
+ }
+ if (idx === 0) {
+ return translate('system.latest_version');
+ }
+ return translate('system.latest_lts_version');
+ };
+
+ handleCancelClick = (event: React.SyntheticEvent<HTMLElement>) => {
+ event.preventDefault();
+ event.stopPropagation();
+ this.props.onClose();
+ };
+
+ render() {
+ const { upgrading } = this.state;
+ const { systemUpgrades } = this.props;
+ const header = translate('system.system_upgrade');
+ return (
+ <Modal
+ isOpen={true}
+ contentLabel={header}
+ className="modal"
+ overlayClassName="modal-overlay"
+ onRequestClose={this.props.onClose}>
+ <div className="modal-head">
+ <h2>{header}</h2>
+ </div>
+ <div className="modal-body">
+ {systemUpgrades.map((upgrades, idx) => (
+ <SystemUpgradeItem
+ key={upgrades[upgrades.length - 1].version}
+ badge={this.getBadge(idx)}
+ systemUpgrades={upgrades}
+ />
+ ))}
+ </div>
+ <div className="modal-foot">
+ {upgrading && <i className="spinner spacer-right" />}
+ <a className="pull-left" href="https://www.sonarqube.org/downloads/" target="_blank">
+ {translate('system.see_sonarqube_downloads')}
+ </a>
+ <a href="#" onClick={this.handleCancelClick}>
+ {translate('cancel')}
+ </a>
+ </div>
+ </Modal>
+ );
+ }
+}
diff --git a/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeIntermediate.tsx b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeIntermediate.tsx
new file mode 100644
index 00000000000..d428dc2310b
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeIntermediate.tsx
@@ -0,0 +1,86 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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 * as classNames from 'classnames';
+import DateFormatter from '../../../../components/intl/DateFormatter';
+import { SystemUpgrade } from '../../../../api/system';
+import { translate } from '../../../../helpers/l10n';
+
+interface Props {
+ className?: string;
+ upgrades: SystemUpgrade[];
+}
+
+interface State {
+ showMore: boolean;
+}
+
+export default class SystemUpgradeIntermediate extends React.PureComponent<Props, State> {
+ state: State = { showMore: false };
+
+ toggleIntermediatVersions = (event: React.SyntheticEvent<HTMLAnchorElement>) => {
+ event.preventDefault();
+ event.stopPropagation();
+ this.setState(state => ({ showMore: !state.showMore }));
+ };
+
+ render() {
+ const { showMore } = this.state;
+ const { upgrades } = this.props;
+ if (upgrades.length <= 0) {
+ return null;
+ }
+
+ return (
+ <div className={this.props.className}>
+ <a
+ className="button-link little-spacer-bottom"
+ href="#"
+ onClick={this.toggleIntermediatVersions}>
+ {showMore ? (
+ translate('system.hide_intermediate_versions')
+ ) : (
+ translate('system.show_intermediate_versions')
+ )}
+ <i
+ className={classNames('little-spacer-left', {
+ 'icon-arrow-down': !showMore,
+ 'icon-arrow-up': showMore
+ })}
+ />
+ </a>
+ {showMore &&
+ upgrades.map(upgrade => (
+ <div key={upgrade.version} className="note system-upgrade-intermediate">
+ <DateFormatter date={upgrade.releaseDate} long={true}>
+ {formattedDate => (
+ <p>
+ <b className="little-spacer-right">SonarQube {upgrade.version}</b>
+ {formattedDate}
+ </p>
+ )}
+ </DateFormatter>
+ <p className="little-spacer-top">{upgrade.description}</p>
+ </div>
+ ))}
+ </div>
+ );
+ }
+}
diff --git a/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeItem.tsx b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeItem.tsx
new file mode 100644
index 00000000000..980cae8d2e1
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeItem.tsx
@@ -0,0 +1,73 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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 { FormattedMessage } from 'react-intl';
+import DateFormatter from '../../../../components/intl/DateFormatter';
+import SystemUpgradeIntermediate from './SystemUpgradeIntermediate';
+import { SystemUpgrade } from '../../../../api/system';
+import { translate, translateWithParameters } from '../../../../helpers/l10n';
+
+interface Props {
+ badge?: string;
+ systemUpgrades: SystemUpgrade[];
+}
+
+export default function SystemUpgradeItem({ badge, systemUpgrades }: Props) {
+ const lastUpgrade = systemUpgrades[0];
+ return (
+ <div className="system-upgrade-version">
+ {badge && <span className="spacer-bottom badge badge-secondary">{badge}</span>}
+ <p>
+ <FormattedMessage
+ defaultMessage={translate('system.version_is_availble')}
+ id="system.version_is_availble"
+ values={{ version: <b>SonarQube {lastUpgrade.version}</b> }}
+ />
+ </p>
+ <p className="spacer-top">{lastUpgrade.description}</p>
+ <div className="big-spacer-top">
+ <DateFormatter date={lastUpgrade.releaseDate} long={true}>
+ {formattedDate => (
+ <span>{translateWithParameters('system.released_x', formattedDate)}</span>
+ )}
+ </DateFormatter>
+ <a className="spacer-left" href={lastUpgrade.changeLogUrl} target="_blank">
+ {translate('system.release_notes')}
+ </a>
+ </div>
+ <SystemUpgradeIntermediate className="spacer-top" upgrades={systemUpgrades.slice(1)} />
+ <div className="big-spacer-top">
+ <a
+ className="button"
+ download={`sonarqube-${lastUpgrade.version}.zip`}
+ href={lastUpgrade.downloadUrl}
+ target="blank">
+ {translateWithParameters('system.download_x', lastUpgrade.version)}
+ </a>
+ <a
+ className="spacer-left"
+ href="https://redirect.sonarsource.com/doc/upgrading.html"
+ target="_blank">
+ {translate('system.how_to_upgrade')}
+ </a>
+ </div>
+ </div>
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeNotif.tsx b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeNotif.tsx
new file mode 100644
index 00000000000..42518738b3e
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/SystemUpgradeNotif.tsx
@@ -0,0 +1,81 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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 SystemUpgradeForm from './SystemUpgradeForm';
+import { getSystemUpgrades, SystemUpgrade } from '../../../../api/system';
+import { translate } from '../../../../helpers/l10n';
+import { sortUpgrades, groupUpgrades } from '../../utils';
+
+interface State {
+ systemUpgrades: SystemUpgrade[][];
+ openSystemUpgradeForm: boolean;
+}
+
+export default class SystemUpgradeNotif extends React.PureComponent<{}, State> {
+ mounted: boolean;
+ state: State = { openSystemUpgradeForm: false, systemUpgrades: [] };
+
+ componentDidMount() {
+ this.mounted = true;
+ this.fetchSystemUpgrade();
+ }
+
+ componentWillUnmount() {
+ this.mounted = false;
+ }
+
+ fetchSystemUpgrade = () =>
+ getSystemUpgrades().then(
+ ({ upgrades }) => {
+ if (this.mounted) {
+ this.setState({ systemUpgrades: groupUpgrades(sortUpgrades(upgrades)) });
+ }
+ },
+ () => {}
+ );
+
+ handleOpenSystemUpgradeForm = () => this.setState({ openSystemUpgradeForm: true });
+ handleCloseSystemUpgradeForm = () => this.setState({ openSystemUpgradeForm: false });
+
+ render() {
+ const { systemUpgrades } = this.state;
+
+ if (systemUpgrades.length <= 0) {
+ return null;
+ }
+
+ return (
+ <div className="page-notifs">
+ <div className="alert alert-info">
+ {translate('system.new_version_available')}
+ <button className="spacer-left" onClick={this.handleOpenSystemUpgradeForm}>
+ {translate('learn_more')}
+ </button>
+ </div>
+ {this.state.openSystemUpgradeForm && (
+ <SystemUpgradeForm
+ systemUpgrades={systemUpgrades}
+ onClose={this.handleCloseSystemUpgradeForm}
+ />
+ )}
+ </div>
+ );
+ }
+}
diff --git a/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/SystemUpgradeForm-test.tsx b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/SystemUpgradeForm-test.tsx
new file mode 100644
index 00000000000..1a8b987a230
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/SystemUpgradeForm-test.tsx
@@ -0,0 +1,75 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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 SystemUpgradeForm from '../SystemUpgradeForm';
+
+const UPGRADES = [
+ [
+ {
+ version: '6.4',
+ description: 'Version 6.4 description',
+ releaseDate: '2017-06-02',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ plugins: {}
+ },
+ {
+ version: '6.3',
+ description: 'Version 6.3 description',
+ releaseDate: '2017-05-02',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ plugins: {}
+ }
+ ],
+ [
+ {
+ version: '5.6.7',
+ description: 'Version 5.6.7 description',
+ releaseDate: '2017-03-01',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ plugins: {}
+ },
+ {
+ version: '5.6.6',
+ description: 'Version 5.6.6 description',
+ releaseDate: '2017-04-02',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ plugins: {}
+ },
+ {
+ version: '5.6.5',
+ description: 'Version 5.6.5 description',
+ releaseDate: '2017-03-01',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ plugins: {}
+ }
+ ]
+];
+
+it('should display correctly', () => {
+ expect(
+ shallow(<SystemUpgradeForm onClose={jest.fn()} systemUpgrades={UPGRADES} />)
+ ).toMatchSnapshot();
+});
diff --git a/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/SystemUpgradeIntermediate-test.tsx b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/SystemUpgradeIntermediate-test.tsx
new file mode 100644
index 00000000000..0718540be3b
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/SystemUpgradeIntermediate-test.tsx
@@ -0,0 +1,58 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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 { click } from '../../../../../helpers/testUtils';
+import SystemUpgradeIntermediate from '../SystemUpgradeIntermediate';
+
+const UPGRADES = [
+ {
+ version: '5.6.6',
+ description: 'Version 5.6.6 description',
+ releaseDate: '2017-04-02',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ plugins: {}
+ },
+ {
+ version: '5.6.5',
+ description: 'Version 5.6.5 description',
+ releaseDate: '2017-03-01',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ plugins: {}
+ }
+];
+
+it('should display correctly', () => {
+ const wrapper = shallow(<SystemUpgradeIntermediate upgrades={UPGRADES} />);
+ expect(wrapper).toMatchSnapshot();
+ wrapper.setState({ showMore: true });
+ expect(wrapper).toMatchSnapshot();
+});
+
+it('should allow to show and hide intermediates', () => {
+ const wrapper = shallow(<SystemUpgradeIntermediate upgrades={UPGRADES} />);
+ expect(wrapper.find('.system-upgrade-intermediate').exists()).toBeFalsy();
+ click(wrapper.find('a'));
+ expect(wrapper.find('.system-upgrade-intermediate').exists()).toBeTruthy();
+ click(wrapper.find('a'));
+ expect(wrapper.find('.system-upgrade-intermediate').exists()).toBeFalsy();
+});
diff --git a/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/SystemUpgradeItem-test.tsx b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/SystemUpgradeItem-test.tsx
new file mode 100644
index 00000000000..f23842f8689
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/SystemUpgradeItem-test.tsx
@@ -0,0 +1,59 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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 SystemUpgradeItem from '../SystemUpgradeItem';
+
+const UPGRADES = [
+ {
+ version: '5.6.7',
+ description: 'Version 5.6.7 description',
+ releaseDate: '2017-03-01',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ plugins: {}
+ },
+ {
+ version: '5.6.6',
+ description: 'Version 5.6.6 description',
+ releaseDate: '2017-04-02',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ plugins: {}
+ },
+ {
+ version: '5.6.5',
+ description: 'Version 5.6.5 description',
+ releaseDate: '2017-03-01',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ plugins: {}
+ }
+];
+
+it('should display correctly', () => {
+ const wrapper = shallow(<SystemUpgradeItem systemUpgrades={UPGRADES} />);
+ expect(wrapper).toMatchSnapshot();
+});
+
+it('should display a badge', () => {
+ const wrapper = shallow(<SystemUpgradeItem badge="test badge" systemUpgrades={UPGRADES} />);
+ expect(wrapper.find('.badge').exists()).toBeTruthy();
+});
diff --git a/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/SystemUpgradeNotif-test.tsx b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/SystemUpgradeNotif-test.tsx
new file mode 100644
index 00000000000..e043d59c98b
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/SystemUpgradeNotif-test.tsx
@@ -0,0 +1,123 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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 { mount, shallow } from 'enzyme';
+import { click } from '../../../../../helpers/testUtils';
+import SystemUpgradeNotif from '../SystemUpgradeNotif';
+
+jest.mock('../../../../../api/system', () => ({
+ getSystemUpgrades: jest.fn(() =>
+ Promise.resolve({
+ updateCenterRefresh: '',
+ upgrades: [
+ {
+ version: '5.6.7',
+ description: 'Version 5.6.7 description',
+ releaseDate: '2017-03-01',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ plugins: {}
+ },
+ {
+ version: '5.6.5',
+ description: 'Version 5.6.5 description',
+ releaseDate: '2017-03-01',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ plugins: {}
+ },
+ {
+ version: '6.3',
+ description: 'Version 6.3 description',
+ releaseDate: '2017-05-02',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ plugins: {}
+ },
+ {
+ version: '5.6.6',
+ description: 'Version 5.6.6 description',
+ releaseDate: '2017-04-02',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ plugins: {}
+ },
+ {
+ version: '6.4',
+ description: 'Version 6.4 description',
+ releaseDate: '2017-06-02',
+ changeLogUrl: 'changelogurl',
+ downloadUrl: 'downloadurl',
+ plugins: {}
+ }
+ ]
+ })
+ )
+}));
+
+const getSystemUpgrades = require('../../../../../api/system').getSystemUpgrades as jest.Mock<any>;
+
+beforeEach(() => {
+ getSystemUpgrades.mockClear();
+});
+
+it('should display correctly', async () => {
+ const wrapper = shallow(<SystemUpgradeNotif />);
+ expect(wrapper).toMatchSnapshot();
+
+ const instance = wrapper.instance() as SystemUpgradeNotif;
+ instance.mounted = true;
+ instance.fetchSystemUpgrade();
+
+ await new Promise(setImmediate);
+ wrapper.update();
+ expect(wrapper).toMatchSnapshot();
+});
+
+it('should display nothing', async () => {
+ getSystemUpgrades.mockImplementationOnce(() =>
+ Promise.resolve({ updateCenterRefresh: '', upgrades: [] })
+ );
+ const wrapper = shallow(<SystemUpgradeNotif />);
+ const instance = wrapper.instance() as SystemUpgradeNotif;
+ instance.mounted = true;
+ instance.fetchSystemUpgrade();
+
+ await new Promise(setImmediate);
+ wrapper.update();
+ expect(wrapper).toMatchSnapshot();
+});
+
+it('should fetch upgrade when mounting', () => {
+ mount(<SystemUpgradeNotif />);
+ expect(getSystemUpgrades).toHaveBeenCalled();
+});
+
+it('should open the upgrade form', async () => {
+ const wrapper = shallow(<SystemUpgradeNotif />);
+ const instance = wrapper.instance() as SystemUpgradeNotif;
+ instance.mounted = true;
+ instance.fetchSystemUpgrade();
+ await new Promise(setImmediate);
+ wrapper.update();
+
+ click(wrapper.find('button'));
+ expect(wrapper.find('SystemUpgradeForm').exists()).toBeTruthy();
+});
diff --git a/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/__snapshots__/SystemUpgradeForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/__snapshots__/SystemUpgradeForm-test.tsx.snap
new file mode 100644
index 00000000000..3bfbebace5a
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/__snapshots__/SystemUpgradeForm-test.tsx.snap
@@ -0,0 +1,100 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should display correctly 1`] = `
+<Modal
+ ariaHideApp={true}
+ bodyOpenClassName="ReactModal__Body--open"
+ className="modal"
+ closeTimeoutMS={0}
+ contentLabel="system.system_upgrade"
+ isOpen={true}
+ onRequestClose={[Function]}
+ overlayClassName="modal-overlay"
+ parentSelector={[Function]}
+ portalClassName="ReactModalPortal"
+ shouldCloseOnOverlayClick={true}
+>
+ <div
+ className="modal-head"
+ >
+ <h2>
+ system.system_upgrade
+ </h2>
+ </div>
+ <div
+ className="modal-body"
+ >
+ <SystemUpgradeItem
+ badge="system.latest_version"
+ systemUpgrades={
+ Array [
+ Object {
+ "changeLogUrl": "changelogurl",
+ "description": "Version 6.4 description",
+ "downloadUrl": "downloadurl",
+ "plugins": Object {},
+ "releaseDate": "2017-06-02",
+ "version": "6.4",
+ },
+ Object {
+ "changeLogUrl": "changelogurl",
+ "description": "Version 6.3 description",
+ "downloadUrl": "downloadurl",
+ "plugins": Object {},
+ "releaseDate": "2017-05-02",
+ "version": "6.3",
+ },
+ ]
+ }
+ />
+ <SystemUpgradeItem
+ badge="system.latest_lts_version"
+ systemUpgrades={
+ Array [
+ Object {
+ "changeLogUrl": "changelogurl",
+ "description": "Version 5.6.7 description",
+ "downloadUrl": "downloadurl",
+ "plugins": Object {},
+ "releaseDate": "2017-03-01",
+ "version": "5.6.7",
+ },
+ Object {
+ "changeLogUrl": "changelogurl",
+ "description": "Version 5.6.6 description",
+ "downloadUrl": "downloadurl",
+ "plugins": Object {},
+ "releaseDate": "2017-04-02",
+ "version": "5.6.6",
+ },
+ Object {
+ "changeLogUrl": "changelogurl",
+ "description": "Version 5.6.5 description",
+ "downloadUrl": "downloadurl",
+ "plugins": Object {},
+ "releaseDate": "2017-03-01",
+ "version": "5.6.5",
+ },
+ ]
+ }
+ />
+ </div>
+ <div
+ className="modal-foot"
+ >
+ <a
+ className="pull-left"
+ href="https://www.sonarqube.org/downloads/"
+ target="_blank"
+ >
+ system.see_sonarqube_downloads
+ </a>
+ <a
+ href="#"
+ onClick={[Function]}
+ >
+ cancel
+ </a>
+ </div>
+</Modal>
+`;
diff --git a/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/__snapshots__/SystemUpgradeIntermediate-test.tsx.snap b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/__snapshots__/SystemUpgradeIntermediate-test.tsx.snap
new file mode 100644
index 00000000000..9217e8cb640
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/__snapshots__/SystemUpgradeIntermediate-test.tsx.snap
@@ -0,0 +1,57 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should display correctly 1`] = `
+<div>
+ <a
+ className="button-link little-spacer-bottom"
+ href="#"
+ onClick={[Function]}
+ >
+ system.show_intermediate_versions
+ <i
+ className="little-spacer-left icon-arrow-down"
+ />
+ </a>
+</div>
+`;
+
+exports[`should display correctly 2`] = `
+<div>
+ <a
+ className="button-link little-spacer-bottom"
+ href="#"
+ onClick={[Function]}
+ >
+ system.hide_intermediate_versions
+ <i
+ className="little-spacer-left icon-arrow-up"
+ />
+ </a>
+ <div
+ className="note system-upgrade-intermediate"
+ >
+ <DateFormatter
+ date="2017-04-02"
+ long={true}
+ />
+ <p
+ className="little-spacer-top"
+ >
+ Version 5.6.6 description
+ </p>
+ </div>
+ <div
+ className="note system-upgrade-intermediate"
+ >
+ <DateFormatter
+ date="2017-03-01"
+ long={true}
+ />
+ <p
+ className="little-spacer-top"
+ >
+ Version 5.6.5 description
+ </p>
+ </div>
+</div>
+`;
diff --git a/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/__snapshots__/SystemUpgradeItem-test.tsx.snap b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/__snapshots__/SystemUpgradeItem-test.tsx.snap
new file mode 100644
index 00000000000..15f11c439b6
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/__snapshots__/SystemUpgradeItem-test.tsx.snap
@@ -0,0 +1,84 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should display correctly 1`] = `
+<div
+ className="system-upgrade-version"
+>
+ <p>
+ <FormattedMessage
+ defaultMessage="system.version_is_availble"
+ id="system.version_is_availble"
+ values={
+ Object {
+ "version": <b>
+ SonarQube
+ 5.6.7
+ </b>,
+ }
+ }
+ />
+ </p>
+ <p
+ className="spacer-top"
+ >
+ Version 5.6.7 description
+ </p>
+ <div
+ className="big-spacer-top"
+ >
+ <DateFormatter
+ date="2017-03-01"
+ long={true}
+ />
+ <a
+ className="spacer-left"
+ href="changelogurl"
+ target="_blank"
+ >
+ system.release_notes
+ </a>
+ </div>
+ <SystemUpgradeIntermediate
+ className="spacer-top"
+ upgrades={
+ Array [
+ Object {
+ "changeLogUrl": "changelogurl",
+ "description": "Version 5.6.6 description",
+ "downloadUrl": "downloadurl",
+ "plugins": Object {},
+ "releaseDate": "2017-04-02",
+ "version": "5.6.6",
+ },
+ Object {
+ "changeLogUrl": "changelogurl",
+ "description": "Version 5.6.5 description",
+ "downloadUrl": "downloadurl",
+ "plugins": Object {},
+ "releaseDate": "2017-03-01",
+ "version": "5.6.5",
+ },
+ ]
+ }
+ />
+ <div
+ className="big-spacer-top"
+ >
+ <a
+ className="button"
+ download="sonarqube-5.6.7.zip"
+ href="downloadurl"
+ target="blank"
+ >
+ system.download_x.5.6.7
+ </a>
+ <a
+ className="spacer-left"
+ href="https://redirect.sonarsource.com/doc/upgrading.html"
+ target="_blank"
+ >
+ system.how_to_upgrade
+ </a>
+ </div>
+</div>
+`;
diff --git a/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/__snapshots__/SystemUpgradeNotif-test.tsx.snap b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/__snapshots__/SystemUpgradeNotif-test.tsx.snap
new file mode 100644
index 00000000000..a750b00055d
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/system/components/system-upgrade/__tests__/__snapshots__/SystemUpgradeNotif-test.tsx.snap
@@ -0,0 +1,23 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should display correctly 1`] = `null`;
+
+exports[`should display correctly 2`] = `
+<div
+ className="page-notifs"
+>
+ <div
+ className="alert alert-info"
+ >
+ system.new_version_available
+ <button
+ className="spacer-left"
+ onClick={[Function]}
+ >
+ learn_more
+ </button>
+ </div>
+</div>
+`;
+
+exports[`should display nothing 1`] = `null`;
diff --git a/server/sonar-web/src/main/js/apps/system/styles.css b/server/sonar-web/src/main/js/apps/system/styles.css
index 66563a4b032..6c266bec872 100644
--- a/server/sonar-web/src/main/js/apps/system/styles.css
+++ b/server/sonar-web/src/main/js/apps/system/styles.css
@@ -61,3 +61,17 @@
overflow: hidden;
text-overflow: ellipsis;
}
+
+.system-upgrade-version {
+ padding: 8px;
+}
+
+.system-upgrade-version ~ .system-upgrade-version {
+ margin-top: 10px;
+ padding-top: 18px;
+ border-top: solid 1px #e6e6e6;
+}
+
+.system-upgrade-intermediate {
+ padding: 6px 10px;
+}
diff --git a/server/sonar-web/src/main/js/apps/system/utils.ts b/server/sonar-web/src/main/js/apps/system/utils.ts
index ac7c62ee752..1f5367bd5f9 100644
--- a/server/sonar-web/src/main/js/apps/system/utils.ts
+++ b/server/sonar-web/src/main/js/apps/system/utils.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { each, memoize, omit, omitBy, pickBy, sortBy } from 'lodash';
+import { each, groupBy, memoize, omit, omitBy, pickBy, sortBy } from 'lodash';
import {
cleanQuery,
parseAsArray,
@@ -31,7 +31,8 @@ import {
NodeInfo,
SysInfo,
SysInfoSection,
- SysValueObject
+ SysValueObject,
+ SystemUpgrade
} from '../../api/system';
import { formatMeasure } from '../../helpers/measures';
@@ -185,3 +186,17 @@ export const serializeQuery = memoize((query: Query): RawQuery =>
expand: serializeStringArray(query.expandedCards)
})
);
+
+export function sortUpgrades(upgrades: SystemUpgrade[]): SystemUpgrade[] {
+ return sortBy(upgrades, [
+ (upgrade: SystemUpgrade) => -Number(upgrade.version.split('.')[0]),
+ (upgrade: SystemUpgrade) => -Number(upgrade.version.split('.')[1] || 0),
+ (upgrade: SystemUpgrade) => -Number(upgrade.version.split('.')[2] || 0)
+ ]);
+}
+
+export function groupUpgrades(upgrades: SystemUpgrade[]): SystemUpgrade[][] {
+ const groupedVersions = groupBy(upgrades, upgrade => upgrade.version.split('.')[0]);
+ const sortedMajor = sortBy(Object.keys(groupedVersions), key => -Number(key));
+ return sortedMajor.map(key => groupedVersions[key]);
+}