aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main
diff options
context:
space:
mode:
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>2017-10-27 11:26:58 +0200
committerGrégoire Aubert <gregoire.aubert@sonarsource.com>2017-10-27 16:03:44 +0200
commit35a5d851cedbe4fee51fe5cecb7cb3205e7713fe (patch)
treee0285271a46ceb4b41f61200e74f4860ced6ee56 /server/sonar-web/src/main
parente5b81bb8654d0a6ffa4aa80cbc2928410fdf1b68 (diff)
downloadsonarqube-35a5d851cedbe4fee51fe5cecb7cb3205e7713fe.tar.gz
sonarqube-35a5d851cedbe4fee51fe5cecb7cb3205e7713fe.zip
SONAR-9936 Switch to upgrade/downgrade buttons in the editions
Diffstat (limited to 'server/sonar-web/src/main')
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/EditionBoxes.tsx68
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/__tests__/EditionBoxes-test.tsx16
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/__tests__/__snapshots__/EditionBoxes-test.tsx.snap22
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/EditionBox.tsx62
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/EditionBoxBadge.tsx56
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/LicenseEditionForm.tsx8
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/__tests__/EditionBox-test.tsx44
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/__tests__/EditionBoxBadge-test.tsx81
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/__tests__/LicenseEditionForm-test.tsx1
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/EditionBox-test.tsx.snap140
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/EditionBoxBadge-test.tsx.snap9
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/LicenseEditionForm-test.tsx.snap4
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/utils.ts11
13 files changed, 348 insertions, 174 deletions
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 d8a0a5e3533..ddba3af1b72 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/EditionBoxes.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/EditionBoxes.tsx
@@ -24,6 +24,7 @@ import LicenseEditionForm from './components/LicenseEditionForm';
import UninstallEditionForm from './components/UninstallEditionForm';
import { Edition, EditionStatus } from '../../api/marketplace';
import { translate } from '../../helpers/l10n';
+import { sortEditions } from './utils';
export interface Props {
canInstall: boolean;
@@ -49,9 +50,45 @@ export default class EditionBoxes extends React.PureComponent<Props, State> {
handleOpenUninstallForm = () => this.setState({ openUninstallForm: true });
handleCloseUninstallForm = () => this.setState({ openUninstallForm: false });
+ renderForms(sortedEditions: Edition[], installedIdx?: number) {
+ const { canInstall, canUninstall, editionStatus } = this.props;
+ const { installEdition, openUninstallForm } = this.state;
+ const installEditionIdx =
+ installEdition && sortedEditions.findIndex(edition => edition.key === installEdition.key);
+
+ if (canInstall && installEdition) {
+ return (
+ <LicenseEditionForm
+ edition={installEdition}
+ editions={sortedEditions}
+ isDowngrade={
+ installedIdx !== undefined &&
+ installEditionIdx !== undefined &&
+ installEditionIdx < installedIdx
+ }
+ onClose={this.handleCloseLicenseForm}
+ updateEditionStatus={this.props.updateEditionStatus}
+ />
+ );
+ }
+
+ if (canUninstall && openUninstallForm && editionStatus && editionStatus.currentEditionKey) {
+ return (
+ <UninstallEditionForm
+ edition={sortedEditions.find(edition => edition.key === editionStatus.currentEditionKey)}
+ editionStatus={editionStatus}
+ onClose={this.handleCloseUninstallForm}
+ updateEditionStatus={this.props.updateEditionStatus}
+ />
+ );
+ }
+
+ return null;
+ }
+
render() {
const { canInstall, canUninstall, editions, editionStatus, loading } = this.props;
- const { installEdition, openUninstallForm } = this.state;
+
if (loading) {
return <i className="big-spacer-bottom spinner" />;
}
@@ -76,41 +113,26 @@ export default class EditionBoxes extends React.PureComponent<Props, State> {
);
}
+ const sortedEditions = sortEditions(editions);
+ const installedIdx =
+ editionStatus &&
+ sortedEditions.findIndex(edition => edition.key === editionStatus.currentEditionKey);
return (
<div className="spacer-bottom marketplace-editions">
- {editions.map(edition => (
+ {sortedEditions.map((edition, idx) => (
<EditionBox
canInstall={canInstall}
canUninstall={canUninstall}
edition={edition}
editionStatus={editionStatus}
+ isDowngrade={installedIdx !== undefined && idx < installedIdx}
key={edition.key}
onInstall={this.handleOpenLicenseForm}
onUninstall={this.handleOpenUninstallForm}
/>
))}
- {canInstall &&
- installEdition && (
- <LicenseEditionForm
- edition={installEdition}
- editions={editions}
- onClose={this.handleCloseLicenseForm}
- updateEditionStatus={this.props.updateEditionStatus}
- />
- )}
-
- {canUninstall &&
- openUninstallForm &&
- editionStatus &&
- editionStatus.currentEditionKey && (
- <UninstallEditionForm
- edition={editions.find(edition => edition.key === editionStatus.currentEditionKey)}
- editionStatus={editionStatus}
- onClose={this.handleCloseUninstallForm}
- updateEditionStatus={this.props.updateEditionStatus}
- />
- )}
+ {this.renderForms(sortedEditions, installedIdx)}
</div>
);
}
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 fe3880cc9f0..0201372b086 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
@@ -23,31 +23,31 @@ import EditionBoxes from '../EditionBoxes';
import { EditionStatus } from '../../../api/marketplace';
const DEFAULT_STATUS: EditionStatus = {
- currentEditionKey: 'foo',
+ currentEditionKey: 'developer',
nextEditionKey: '',
installationStatus: 'NONE'
};
const DEFAULT_EDITIONS = [
{
- key: 'foo',
- name: 'Foo',
- textDescription: 'Foo desc',
+ key: 'developer',
+ name: 'Developer Edition',
+ textDescription: 'foo',
downloadUrl: 'download_url',
homeUrl: 'more_url',
requestUrl: 'license_url'
},
{
- key: 'bar',
- name: 'Bar',
- textDescription: 'Bar desc',
+ key: 'comunity',
+ name: 'Comunity Edition',
+ textDescription: 'bar',
downloadUrl: 'download_url',
homeUrl: 'more_url',
requestUrl: 'license_url'
}
];
-it('should display the edition boxes', () => {
+it('should display the edition boxes correctly', () => {
const wrapper = getWrapper({ editions: DEFAULT_EDITIONS, loading: true });
expect(wrapper).toMatchSnapshot();
wrapper.setProps({ loading: false });
diff --git a/server/sonar-web/src/main/js/apps/marketplace/__tests__/__snapshots__/EditionBoxes-test.tsx.snap b/server/sonar-web/src/main/js/apps/marketplace/__tests__/__snapshots__/EditionBoxes-test.tsx.snap
index f9b86d68f00..952e8dc78c1 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/__tests__/__snapshots__/EditionBoxes-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/marketplace/__tests__/__snapshots__/EditionBoxes-test.tsx.snap
@@ -25,13 +25,13 @@ exports[`should display an error message 1`] = `
</div>
`;
-exports[`should display the edition boxes 1`] = `
+exports[`should display the edition boxes correctly 1`] = `
<i
className="big-spacer-bottom spinner"
/>
`;
-exports[`should display the edition boxes 2`] = `
+exports[`should display the edition boxes correctly 2`] = `
<div
className="spacer-bottom marketplace-editions"
>
@@ -42,19 +42,20 @@ exports[`should display the edition boxes 2`] = `
Object {
"downloadUrl": "download_url",
"homeUrl": "more_url",
- "key": "foo",
- "name": "Foo",
+ "key": "comunity",
+ "name": "Comunity Edition",
"requestUrl": "license_url",
- "textDescription": "Foo desc",
+ "textDescription": "bar",
}
}
editionStatus={
Object {
- "currentEditionKey": "foo",
+ "currentEditionKey": "developer",
"installationStatus": "NONE",
"nextEditionKey": "",
}
}
+ isDowngrade={true}
onInstall={[Function]}
onUninstall={[Function]}
/>
@@ -65,19 +66,20 @@ exports[`should display the edition boxes 2`] = `
Object {
"downloadUrl": "download_url",
"homeUrl": "more_url",
- "key": "bar",
- "name": "Bar",
+ "key": "developer",
+ "name": "Developer Edition",
"requestUrl": "license_url",
- "textDescription": "Bar desc",
+ "textDescription": "foo",
}
}
editionStatus={
Object {
- "currentEditionKey": "foo",
+ "currentEditionKey": "developer",
"installationStatus": "NONE",
"nextEditionKey": "",
}
}
+ isDowngrade={false}
onInstall={[Function]}
onUninstall={[Function]}
/>
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/EditionBox.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/EditionBox.tsx
index ca8457fe4d1..6f90fda970e 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/components/EditionBox.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/EditionBox.tsx
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import CheckIcon from '../../../components/icons-components/CheckIcon';
+import EditionBoxBadge from './EditionBoxBadge';
import { Edition, EditionStatus } from '../../../api/marketplace';
import { translate } from '../../../helpers/l10n';
@@ -27,6 +27,7 @@ interface Props {
canUninstall: boolean;
edition: Edition;
editionStatus?: EditionStatus;
+ isDowngrade?: boolean;
onInstall: (edition: Edition) => void;
onUninstall: () => void;
}
@@ -34,40 +35,45 @@ interface Props {
export default class EditionBox extends React.PureComponent<Props> {
handleInstall = () => this.props.onInstall(this.props.edition);
- renderBadge(isInstalled?: boolean, installInProgress?: boolean) {
- const { edition, editionStatus } = this.props;
- const installReady = editionStatus && editionStatus.installationStatus === 'AUTOMATIC_READY';
- const isInstalling =
- installInProgress && editionStatus && editionStatus.nextEditionKey === edition.key;
- if (isInstalling) {
+ renderActions(isInstalled?: boolean, installInProgress?: boolean) {
+ const { canInstall, canUninstall, editionStatus } = this.props;
+ const uninstallInProgress =
+ editionStatus && editionStatus.installationStatus === 'UNINSTALL_IN_PROGRESS';
+
+ if (canInstall && !isInstalled) {
return (
- <span className="marketplace-edition-badge badge badge-normal-size">
- {installReady ? translate('marketplace.pending') : translate('marketplace.installing')}
- </span>
+ <button disabled={installInProgress || uninstallInProgress} onClick={this.handleInstall}>
+ {this.props.isDowngrade ? (
+ translate('marketplace.downgrade')
+ ) : (
+ translate('marketplace.upgrade')
+ )}
+ </button>
);
}
- if (isInstalled) {
+ if (canUninstall && isInstalled) {
return (
- <span className="marketplace-edition-badge badge badge-normal-size">
- <CheckIcon size={14} className="little-spacer-right text-bottom" />
- {translate('marketplace.installed')}
- </span>
+ <button
+ className="button-red"
+ disabled={installInProgress || uninstallInProgress}
+ onClick={this.props.onUninstall}>
+ {translate('marketplace.uninstall')}
+ </button>
);
}
+
return null;
}
render() {
- const { canInstall, canUninstall, edition, editionStatus } = this.props;
+ const { edition, editionStatus } = this.props;
const isInstalled = editionStatus && editionStatus.currentEditionKey === edition.key;
- const uninstallInProgress =
- editionStatus && editionStatus.installationStatus === 'UNINSTALL_IN_PROGRESS';
const installInProgress =
editionStatus &&
['AUTOMATIC_IN_PROGRESS', 'AUTOMATIC_READY'].includes(editionStatus.installationStatus);
return (
<div className="boxed-group boxed-group-inner marketplace-edition">
- {this.renderBadge(isInstalled, installInProgress)}
+ {editionStatus && <EditionBoxBadge editionKey={edition.key} status={editionStatus} />}
<div>
<h3 className="spacer-bottom">{edition.name}</h3>
<p>{edition.textDescription}</p>
@@ -76,23 +82,7 @@ export default class EditionBox extends React.PureComponent<Props> {
<a href={edition.homeUrl} target="_blank">
{translate('marketplace.learn_more')}
</a>
- {canUninstall &&
- isInstalled && (
- <button
- className="button-red"
- disabled={installInProgress || uninstallInProgress}
- onClick={this.props.onUninstall}>
- {translate('marketplace.uninstall')}
- </button>
- )}
- {canInstall &&
- !isInstalled && (
- <button
- disabled={installInProgress || uninstallInProgress}
- onClick={this.handleInstall}>
- {translate('marketplace.install')}
- </button>
- )}
+ {this.renderActions(isInstalled, installInProgress)}
</div>
</div>
);
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/EditionBoxBadge.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/EditionBoxBadge.tsx
new file mode 100644
index 00000000000..47b3e767fe2
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/EditionBoxBadge.tsx
@@ -0,0 +1,56 @@
+/*
+ * 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 CheckIcon from '../../../components/icons-components/CheckIcon';
+import { EditionStatus } from '../../../api/marketplace';
+import { translate } from '../../../helpers/l10n';
+
+interface Props {
+ editionKey: string;
+ status: EditionStatus;
+}
+
+export default function EditionBoxBadge({ editionKey, status }: Props) {
+ const inProgress = ['AUTOMATIC_IN_PROGRESS', 'AUTOMATIC_READY'].includes(
+ status.installationStatus
+ );
+ const isInstalling = inProgress && status.nextEditionKey === editionKey;
+
+ if (isInstalling) {
+ const installReady = status.installationStatus === 'AUTOMATIC_READY';
+ return (
+ <span className="marketplace-edition-badge badge badge-normal-size">
+ {installReady ? translate('marketplace.pending') : translate('marketplace.installing')}
+ </span>
+ );
+ }
+
+ const isInstalled = status.currentEditionKey === editionKey;
+ if (isInstalled) {
+ return (
+ <span className="marketplace-edition-badge badge badge-normal-size">
+ <CheckIcon size={14} className="little-spacer-right text-bottom" />
+ {translate('marketplace.installed')}
+ </span>
+ );
+ }
+
+ 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 e099465dc43..abab7c84ed4 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
@@ -26,6 +26,7 @@ import { translate, translateWithParameters } from '../../../helpers/l10n';
export interface Props {
edition: Edition;
editions: Edition[];
+ isDowngrade: boolean;
onClose: () => void;
updateEditionStatus: (editionStatus: EditionStatus) => void;
}
@@ -79,9 +80,12 @@ export default class LicenseEditionForm extends React.PureComponent<Props, State
};
render() {
- const { edition } = this.props;
+ const { edition, isDowngrade } = this.props;
const { submitting, status } = this.state;
- const header = translateWithParameters('marketplace.install_x', edition.name);
+
+ const header = isDowngrade
+ ? translateWithParameters('marketplace.downgrade_to_x', edition.name)
+ : translateWithParameters('marketplace.upgrade_to_x', edition.name);
return (
<Modal
isOpen={true}
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/EditionBox-test.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/EditionBox-test.tsx
index dbfa141f629..1fdf88ee8db 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/EditionBox-test.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/EditionBox-test.tsx
@@ -41,31 +41,16 @@ it('should display the edition', () => {
expect(getWrapper()).toMatchSnapshot();
});
-it('should display installed badge', () => {
+it('should disable upgrade button', () => {
expect(
getWrapper({
editionStatus: {
- currentEditionKey: 'foo',
- nextEditionKey: '',
- installationStatus: 'NONE'
- }
- })
- ).toMatchSnapshot();
-});
-
-it('should display installing badge', () => {
- expect(
- getWrapper({
- editionStatus: {
- currentEditionKey: 'foo',
+ currentEditionKey: '',
nextEditionKey: 'foo',
installationStatus: 'AUTOMATIC_IN_PROGRESS'
}
})
).toMatchSnapshot();
-});
-
-it('should display pending badge', () => {
expect(
getWrapper({
editionStatus: {
@@ -77,39 +62,36 @@ it('should display pending badge', () => {
).toMatchSnapshot();
});
-it('should disable install button', () => {
+it('should disable uninstall button', () => {
expect(
getWrapper({
editionStatus: {
- currentEditionKey: '',
+ currentEditionKey: 'foo',
nextEditionKey: 'foo',
installationStatus: 'AUTOMATIC_IN_PROGRESS'
}
})
).toMatchSnapshot();
- expect(
- getWrapper({
- editionStatus: {
- currentEditionKey: '',
- nextEditionKey: 'foo',
- installationStatus: 'AUTOMATIC_READY'
- }
- })
- ).toMatchSnapshot();
});
-it('should disable uninstall button', () => {
+it('should correctly hide upgrade/uninstall buttons', () => {
+ expect(getWrapper({ canInstall: false })).toMatchSnapshot();
expect(
getWrapper({
+ canUninstall: false,
editionStatus: {
currentEditionKey: 'foo',
- nextEditionKey: 'foo',
- installationStatus: 'AUTOMATIC_IN_PROGRESS'
+ nextEditionKey: '',
+ installationStatus: 'NONE'
}
})
).toMatchSnapshot();
});
+it('should display a downgrade button', () => {
+ expect(getWrapper({ isDowngrade: true })).toMatchSnapshot();
+});
+
function getWrapper(props = {}) {
return shallow(
<EditionBox
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/EditionBoxBadge-test.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/EditionBoxBadge-test.tsx
new file mode 100644
index 00000000000..88a9c2c4ab0
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/EditionBoxBadge-test.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 { shallow } from 'enzyme';
+import { EditionStatus } from '../../../../api/marketplace';
+import EditionBoxBadge from '../EditionBoxBadge';
+
+const DEFAULT_STATUS: EditionStatus = {
+ currentEditionKey: '',
+ nextEditionKey: '',
+ installationStatus: 'NONE'
+};
+
+it('should display installed badge', () => {
+ expect(
+ getWrapper({
+ editionStatus: {
+ currentEditionKey: 'foo',
+ nextEditionKey: '',
+ installationStatus: 'NONE'
+ }
+ })
+ ).toMatchSnapshot();
+});
+
+it('should display installing badge', () => {
+ expect(
+ getWrapper({
+ editionStatus: {
+ currentEditionKey: 'foo',
+ nextEditionKey: 'foo',
+ installationStatus: 'AUTOMATIC_IN_PROGRESS'
+ }
+ })
+ ).toMatchSnapshot();
+});
+
+it('should display pending badge', () => {
+ expect(
+ getWrapper({
+ editionStatus: {
+ currentEditionKey: '',
+ nextEditionKey: 'foo',
+ installationStatus: 'AUTOMATIC_READY'
+ }
+ })
+ ).toMatchSnapshot();
+});
+
+it('should not display a badge', () => {
+ expect(
+ getWrapper({
+ editionStatus: {
+ currentEditionKey: '',
+ nextEditionKey: 'bar',
+ installationStatus: 'AUTOMATIC_READY'
+ }
+ })
+ ).toMatchSnapshot();
+});
+
+function getWrapper(props = {}) {
+ return shallow(<EditionBoxBadge editionKey="foo" status={DEFAULT_STATUS} {...props} />);
+}
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 bb6e8d213ee..133ac464913 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
@@ -78,6 +78,7 @@ function getWrapper(props = {}) {
<LicenseEditionForm
edition={DEFAULT_EDITION}
editions={[DEFAULT_EDITION]}
+ isDowngrade={false}
onClose={jest.fn()}
updateEditionStatus={jest.fn()}
{...props}
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/EditionBox-test.tsx.snap b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/EditionBox-test.tsx.snap
index b7dbb58a562..c054a76bac9 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/EditionBox-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/EditionBox-test.tsx.snap
@@ -1,14 +1,19 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`should disable install button 1`] = `
+exports[`should correctly hide upgrade/uninstall buttons 1`] = `
<div
className="boxed-group boxed-group-inner marketplace-edition"
>
- <span
- className="marketplace-edition-badge badge badge-normal-size"
- >
- marketplace.installing
- </span>
+ <EditionBoxBadge
+ editionKey="foo"
+ status={
+ Object {
+ "currentEditionKey": "",
+ "installationStatus": "NONE",
+ "nextEditionKey": "",
+ }
+ }
+ />
<div>
<h3
className="spacer-bottom"
@@ -28,25 +33,24 @@ exports[`should disable install button 1`] = `
>
marketplace.learn_more
</a>
- <button
- disabled={true}
- onClick={[Function]}
- >
- marketplace.install
- </button>
</div>
</div>
`;
-exports[`should disable install button 2`] = `
+exports[`should correctly hide upgrade/uninstall buttons 2`] = `
<div
className="boxed-group boxed-group-inner marketplace-edition"
>
- <span
- className="marketplace-edition-badge badge badge-normal-size"
- >
- marketplace.pending
- </span>
+ <EditionBoxBadge
+ editionKey="foo"
+ status={
+ Object {
+ "currentEditionKey": "foo",
+ "installationStatus": "NONE",
+ "nextEditionKey": "",
+ }
+ }
+ />
<div>
<h3
className="spacer-bottom"
@@ -66,12 +70,6 @@ exports[`should disable install button 2`] = `
>
marketplace.learn_more
</a>
- <button
- disabled={true}
- onClick={[Function]}
- >
- marketplace.install
- </button>
</div>
</div>
`;
@@ -80,11 +78,16 @@ exports[`should disable uninstall button 1`] = `
<div
className="boxed-group boxed-group-inner marketplace-edition"
>
- <span
- className="marketplace-edition-badge badge badge-normal-size"
- >
- marketplace.installing
- </span>
+ <EditionBoxBadge
+ editionKey="foo"
+ status={
+ Object {
+ "currentEditionKey": "foo",
+ "installationStatus": "AUTOMATIC_IN_PROGRESS",
+ "nextEditionKey": "foo",
+ }
+ }
+ />
<div>
<h3
className="spacer-bottom"
@@ -115,19 +118,20 @@ exports[`should disable uninstall button 1`] = `
</div>
`;
-exports[`should display installed badge 1`] = `
+exports[`should disable upgrade button 1`] = `
<div
className="boxed-group boxed-group-inner marketplace-edition"
>
- <span
- className="marketplace-edition-badge badge badge-normal-size"
- >
- <CheckIcon
- className="little-spacer-right text-bottom"
- size={14}
- />
- marketplace.installed
- </span>
+ <EditionBoxBadge
+ editionKey="foo"
+ status={
+ Object {
+ "currentEditionKey": "",
+ "installationStatus": "AUTOMATIC_IN_PROGRESS",
+ "nextEditionKey": "foo",
+ }
+ }
+ />
<div>
<h3
className="spacer-bottom"
@@ -148,25 +152,29 @@ exports[`should display installed badge 1`] = `
marketplace.learn_more
</a>
<button
- className="button-red"
- disabled={false}
+ disabled={true}
onClick={[Function]}
>
- marketplace.uninstall
+ marketplace.upgrade
</button>
</div>
</div>
`;
-exports[`should display installing badge 1`] = `
+exports[`should disable upgrade button 2`] = `
<div
className="boxed-group boxed-group-inner marketplace-edition"
>
- <span
- className="marketplace-edition-badge badge badge-normal-size"
- >
- marketplace.installing
- </span>
+ <EditionBoxBadge
+ editionKey="foo"
+ status={
+ Object {
+ "currentEditionKey": "",
+ "installationStatus": "AUTOMATIC_READY",
+ "nextEditionKey": "foo",
+ }
+ }
+ />
<div>
<h3
className="spacer-bottom"
@@ -187,25 +195,29 @@ exports[`should display installing badge 1`] = `
marketplace.learn_more
</a>
<button
- className="button-red"
disabled={true}
onClick={[Function]}
>
- marketplace.uninstall
+ marketplace.upgrade
</button>
</div>
</div>
`;
-exports[`should display pending badge 1`] = `
+exports[`should display a downgrade button 1`] = `
<div
className="boxed-group boxed-group-inner marketplace-edition"
>
- <span
- className="marketplace-edition-badge badge badge-normal-size"
- >
- marketplace.pending
- </span>
+ <EditionBoxBadge
+ editionKey="foo"
+ status={
+ Object {
+ "currentEditionKey": "",
+ "installationStatus": "NONE",
+ "nextEditionKey": "",
+ }
+ }
+ />
<div>
<h3
className="spacer-bottom"
@@ -226,10 +238,10 @@ exports[`should display pending badge 1`] = `
marketplace.learn_more
</a>
<button
- disabled={true}
+ disabled={false}
onClick={[Function]}
>
- marketplace.install
+ marketplace.downgrade
</button>
</div>
</div>
@@ -239,6 +251,16 @@ exports[`should display the edition 1`] = `
<div
className="boxed-group boxed-group-inner marketplace-edition"
>
+ <EditionBoxBadge
+ editionKey="foo"
+ status={
+ Object {
+ "currentEditionKey": "",
+ "installationStatus": "NONE",
+ "nextEditionKey": "",
+ }
+ }
+ />
<div>
<h3
className="spacer-bottom"
@@ -262,7 +284,7 @@ exports[`should display the edition 1`] = `
disabled={false}
onClick={[Function]}
>
- marketplace.install
+ marketplace.upgrade
</button>
</div>
</div>
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/EditionBoxBadge-test.tsx.snap b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/EditionBoxBadge-test.tsx.snap
new file mode 100644
index 00000000000..7e824591e02
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/EditionBoxBadge-test.tsx.snap
@@ -0,0 +1,9 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should display installed badge 1`] = `null`;
+
+exports[`should display installing badge 1`] = `null`;
+
+exports[`should display pending badge 1`] = `null`;
+
+exports[`should not display a badge 1`] = `null`;
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/LicenseEditionForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/LicenseEditionForm-test.tsx.snap
index 382c562bb02..9e07155c292 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/LicenseEditionForm-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/LicenseEditionForm-test.tsx.snap
@@ -36,7 +36,7 @@ exports[`should display correctly 1`] = `
bodyOpenClassName="ReactModal__Body--open"
className="modal"
closeTimeoutMS={0}
- contentLabel="marketplace.install_x.Foo"
+ contentLabel="marketplace.upgrade_to_x.Foo"
isOpen={true}
onRequestClose={[Function]}
overlayClassName="modal-overlay"
@@ -48,7 +48,7 @@ exports[`should display correctly 1`] = `
className="modal-head"
>
<h2>
- marketplace.install_x.Foo
+ marketplace.upgrade_to_x.Foo
</h2>
</header>
<LicenseEditionSet
diff --git a/server/sonar-web/src/main/js/apps/marketplace/utils.ts b/server/sonar-web/src/main/js/apps/marketplace/utils.ts
index 780fafb3af8..c3979bd8802 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/utils.ts
+++ b/server/sonar-web/src/main/js/apps/marketplace/utils.ts
@@ -17,17 +17,16 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { memoize } from 'lodash';
+import { memoize, sortBy } from 'lodash';
import { Plugin, PluginAvailable, PluginInstalled, PluginPending } from '../../api/plugins';
import { cleanQuery, parseAsString, RawQuery, serializeString } from '../../helpers/query';
+import { Edition } from '../../api/marketplace';
export interface Query {
filter: string;
search?: string;
}
-export const DEFAULT_FILTER = 'all';
-
export function isPluginAvailable(plugin: Plugin): plugin is PluginAvailable {
return (plugin as any).release !== undefined;
}
@@ -51,6 +50,12 @@ export function filterPlugins(plugins: Plugin[], search: string): Plugin[] {
});
}
+const EDITIONS_ORDER = ['community', 'developer', 'enterprise', 'datacenter'];
+export function sortEditions(editions: Edition[]): Edition[] {
+ return sortBy(editions, edition => EDITIONS_ORDER.indexOf(edition.key));
+}
+
+export const DEFAULT_FILTER = 'all';
export const parseQuery = memoize((urlQuery: RawQuery): Query => ({
filter: parseAsString(urlQuery['filter']) || DEFAULT_FILTER,
search: parseAsString(urlQuery['search'])