@@ -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> | |||
); | |||
} |
@@ -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 }); |
@@ -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]} | |||
/> |
@@ -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> | |||
); |
@@ -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; | |||
} |
@@ -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} |
@@ -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 |
@@ -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} />); | |||
} |
@@ -78,6 +78,7 @@ function getWrapper(props = {}) { | |||
<LicenseEditionForm | |||
edition={DEFAULT_EDITION} | |||
editions={[DEFAULT_EDITION]} | |||
isDowngrade={false} | |||
onClose={jest.fn()} | |||
updateEditionStatus={jest.fn()} | |||
{...props} |
@@ -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> |
@@ -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`; |
@@ -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 |
@@ -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']) |
@@ -2068,9 +2068,12 @@ marketplace.updates_only=Updates Only | |||
marketplace.restart=Restart | |||
marketplace.revert=Revert | |||
marketplace.install=Install | |||
marketplace.install_x=Install {0} | |||
marketplace.upgrade_to_x=Upgrade to {0} | |||
marketplace.downgrade_to_x=Downgrade to {0} | |||
marketplace.installed=Installed | |||
marketplace.installing=Installing... | |||
marketplace.upgrade=Upgrade | |||
marketplace.downgrade=Downgrade | |||
marketplace.uninstall_x=Uninstall {0} | |||
marketplace.uninstall_x_confirmation=Are you sure you want to uninstall {0} and get back to the Community Edition? | |||
marketplace.pending=Pending... |