} | } | ||||
isSystemActive() { | isSystemActive() { | ||||
const urls = ['/admin/update_center', '/admin/system']; | |||||
const urls = ['/admin/system']; | |||||
return this.isSomethingActive(urls); | return this.isSomethingActive(urls); | ||||
} | } | ||||
const securityClassName = classNames('dropdown-toggle', { active: isSecurity }); | const securityClassName = classNames('dropdown-toggle', { active: isSecurity }); | ||||
const projectsClassName = classNames('dropdown-toggle', { active: isProjects }); | const projectsClassName = classNames('dropdown-toggle', { active: isProjects }); | ||||
const systemClassName = classNames('dropdown-toggle', { active: isSystem }); | |||||
const configurationClassNames = classNames('dropdown-toggle', { | const configurationClassNames = classNames('dropdown-toggle', { | ||||
active: !isSecurity && !isProjects && !isSystem && !isSupport && !this.isMarketplace() | active: !isSecurity && !isProjects && !isSystem && !isSupport && !this.isMarketplace() | ||||
}); | }); | ||||
</li> | </li> | ||||
</ul> | </ul> | ||||
</li> | </li> | ||||
<li className="dropdown"> | |||||
<a className={systemClassName} data-toggle="dropdown" href="#"> | |||||
{translate('sidebar.system')} <i className="icon-dropdown" /> | |||||
</a> | |||||
<ul className="dropdown-menu"> | |||||
<li> | |||||
<IndexLink to="/admin/update_center" activeClassName="active"> | |||||
{translate('update_center.page')} | |||||
</IndexLink> | |||||
</li> | |||||
<li> | |||||
<IndexLink to="/admin/system" activeClassName="active"> | |||||
{translate('system_info.page')} | |||||
</IndexLink> | |||||
</li> | |||||
</ul> | |||||
<li> | |||||
<IndexLink to="/admin/system" activeClassName="active"> | |||||
{translate('sidebar.system')} | |||||
</IndexLink> | |||||
</li> | </li> | ||||
<li> | <li> |
</li> | </li> | ||||
</ul> | </ul> | ||||
</li> | </li> | ||||
<li | |||||
className="dropdown" | |||||
> | |||||
<a | |||||
className="dropdown-toggle" | |||||
data-toggle="dropdown" | |||||
href="#" | |||||
<li> | |||||
<IndexLink | |||||
activeClassName="active" | |||||
to="/admin/system" | |||||
> | > | ||||
sidebar.system | sidebar.system | ||||
<i | |||||
className="icon-dropdown" | |||||
/> | |||||
</a> | |||||
<ul | |||||
className="dropdown-menu" | |||||
> | |||||
<li> | |||||
<IndexLink | |||||
activeClassName="active" | |||||
to="/admin/update_center" | |||||
> | |||||
update_center.page | |||||
</IndexLink> | |||||
</li> | |||||
<li> | |||||
<IndexLink | |||||
activeClassName="active" | |||||
to="/admin/system" | |||||
> | |||||
system_info.page | |||||
</IndexLink> | |||||
</li> | |||||
</ul> | |||||
</IndexLink> | |||||
</li> | </li> | ||||
<li> | <li> | ||||
<IndexLink | <IndexLink |
import sessionsRoutes from '../../apps/sessions/routes'; | import sessionsRoutes from '../../apps/sessions/routes'; | ||||
import settingsRoutes from '../../apps/settings/routes'; | import settingsRoutes from '../../apps/settings/routes'; | ||||
import systemRoutes from '../../apps/system/routes'; | import systemRoutes from '../../apps/system/routes'; | ||||
import updateCenterRoutes from '../../apps/update-center/routes'; | |||||
import usersRoutes from '../../apps/users/routes'; | import usersRoutes from '../../apps/users/routes'; | ||||
import webAPIRoutes from '../../apps/web-api/routes'; | import webAPIRoutes from '../../apps/web-api/routes'; | ||||
import { maintenanceRoutes, setupRoutes } from '../../apps/maintenance/routes'; | import { maintenanceRoutes, setupRoutes } from '../../apps/maintenance/routes'; | ||||
<Redirect from="/system/index" to="/admin/system" /> | <Redirect from="/system/index" to="/admin/system" /> | ||||
<Redirect from="/view" to="/portfolio" /> | <Redirect from="/view" to="/portfolio" /> | ||||
<Redirect from="/users" to="/admin/users" /> | <Redirect from="/users" to="/admin/users" /> | ||||
<Redirect from="/updatecenter" to="/admin/update_center" /> | |||||
<Redirect from="/updatecenter/available" to="/admin/update_center/available" /> | |||||
<Redirect from="/updatecenter/installed" to="/admin/update_center/installed" /> | |||||
<Redirect from="/updatecenter/system" to="/admin/update_center/system" /> | |||||
<Redirect from="/updatecenter/updates" to="/admin/update_center/updates" /> | |||||
<Route path="markdown/help" component={MarkdownHelp} /> | <Route path="markdown/help" component={MarkdownHelp} /> | ||||
<Route path="projects_management" childRoutes={projectsManagementRoutes} /> | <Route path="projects_management" childRoutes={projectsManagementRoutes} /> | ||||
<Route path="settings" childRoutes={settingsRoutes} /> | <Route path="settings" childRoutes={settingsRoutes} /> | ||||
<Route path="system" childRoutes={systemRoutes} /> | <Route path="system" childRoutes={systemRoutes} /> | ||||
<Route path="update_center" childRoutes={updateCenterRoutes} /> | |||||
<Route path="marketplace" childRoutes={marketplaceRoutes} /> | <Route path="marketplace" childRoutes={marketplaceRoutes} /> | ||||
<Route path="users" childRoutes={usersRoutes} /> | <Route path="users" childRoutes={usersRoutes} /> | ||||
</Route> | </Route> |
</span> | </span> | ||||
{release.changeLogUrl && ( | {release.changeLogUrl && ( | ||||
<a className="js-plugin-changelog-link" href={release.changeLogUrl} target="_blank"> | <a className="js-plugin-changelog-link" href={release.changeLogUrl} target="_blank"> | ||||
{translate('update_center.release_notes')} | |||||
{translate('marketplace.release_notes')} | |||||
</a> | </a> | ||||
)} | )} | ||||
</div> | </div> |
/* | |||||
* 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 React from 'react'; | |||||
import Helmet from 'react-helmet'; | |||||
import { connect } from 'react-redux'; | |||||
import init from '../init'; | |||||
import { getGlobalSettingValue } from '../../../store/rootReducer'; | |||||
import { translate } from '../../../helpers/l10n'; | |||||
class UpdateCenterAppContainer extends React.PureComponent { | |||||
componentDidMount() { | |||||
this.stop = init(this.refs.container, this.props.updateCenterActive); | |||||
} | |||||
componentWillUnmount() { | |||||
this.stop(); | |||||
} | |||||
render() { | |||||
// placing container inside div is required, | |||||
// because when backbone.marionette's layout is destroyed, | |||||
// it also destroys the root element, | |||||
// but react wants it to be there to unmount it | |||||
return ( | |||||
<div> | |||||
<Helmet title={translate('update_center.page')} /> | |||||
<div ref="container" /> | |||||
</div> | |||||
); | |||||
} | |||||
} | |||||
const mapStateToProps = state => ({ | |||||
updateCenterActive: (getGlobalSettingValue(state, 'sonar.updatecenter.activate') || {}).value | |||||
}); | |||||
export default connect(mapStateToProps)(UpdateCenterAppContainer); |
/* | |||||
* 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 Marionette from 'backbone.marionette'; | |||||
export default Marionette.Controller.extend({ | |||||
initialize(options) { | |||||
this.collection = options.collection; | |||||
this.state = options.state; | |||||
}, | |||||
showInstalled() { | |||||
this.state.set({ section: 'installed' }); | |||||
this.collection.fetchInstalled(); | |||||
}, | |||||
showUpdates() { | |||||
this.state.set({ section: 'updates' }); | |||||
this.collection.fetchUpdates(); | |||||
}, | |||||
showAvailable() { | |||||
this.state.set({ section: 'available' }); | |||||
this.collection.fetchAvailable(); | |||||
}, | |||||
showSystemUpgrades() { | |||||
this.state.set({ section: 'system' }); | |||||
this.collection.fetchSystemUpgrades(); | |||||
} | |||||
}); |
/* | |||||
* 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 Marionette from 'backbone.marionette'; | |||||
import Template from './templates/update-center-footer.hbs'; | |||||
export default Marionette.ItemView.extend({ | |||||
template: Template, | |||||
collectionEvents: { | |||||
all: 'render' | |||||
}, | |||||
serializeData() { | |||||
return { | |||||
...Marionette.ItemView.prototype.serializeData.apply(this, arguments), | |||||
total: this.collection.where({ _hidden: false }).length | |||||
}; | |||||
} | |||||
}); |
/* | |||||
* 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 Marionette from 'backbone.marionette'; | |||||
import Template from './templates/update-center-header.hbs'; | |||||
import RestartModal from '../../components/RestartModal'; | |||||
export default Marionette.ItemView.extend({ | |||||
template: Template, | |||||
collectionEvents: { | |||||
all: 'render' | |||||
}, | |||||
events: { | |||||
'click .js-restart': 'restart', | |||||
'click .js-cancel-all': 'cancelAll' | |||||
}, | |||||
restart() { | |||||
new RestartModal().render(); | |||||
}, | |||||
cancelAll() { | |||||
this.collection.cancelAll(); | |||||
}, | |||||
serializeData() { | |||||
return { | |||||
...Marionette.ItemView.prototype.serializeData.apply(this, arguments), | |||||
installing: this.collection._installedCount, | |||||
updating: this.collection._updatedCount, | |||||
uninstalling: this.collection._uninstalledCount | |||||
}; | |||||
} | |||||
}); |
/* | |||||
* 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 Backbone from 'backbone'; | |||||
import Marionette from 'backbone.marionette'; | |||||
import Layout from './layout'; | |||||
import HeaderView from './header-view'; | |||||
import SearchView from './search-view'; | |||||
import ListView from './list-view'; | |||||
import FooterView from './footer-view'; | |||||
import Controller from './controller'; | |||||
import Router from './router'; | |||||
import Plugins from './plugins'; | |||||
const App = new Marionette.Application(); | |||||
const init = function({ el, updateCenterActive }) { | |||||
// State | |||||
this.state = new Backbone.Model({ updateCenterActive }); | |||||
// Layout | |||||
this.layout = new Layout({ el }); | |||||
this.layout.render(); | |||||
// Plugins | |||||
this.plugins = new Plugins(); | |||||
// Controller | |||||
this.controller = new Controller({ collection: this.plugins, state: this.state }); | |||||
// Router | |||||
this.router = new Router({ controller: this.controller }); | |||||
// Header | |||||
this.headerView = new HeaderView({ collection: this.plugins }); | |||||
this.layout.headerRegion.show(this.headerView); | |||||
// Search | |||||
this.searchView = new SearchView({ | |||||
collection: this.plugins, | |||||
router: this.router, | |||||
state: this.state | |||||
}); | |||||
this.layout.searchRegion.show(this.searchView); | |||||
this.searchView.focusSearch(); | |||||
// List | |||||
this.listView = new ListView({ collection: this.plugins }); | |||||
this.layout.listRegion.show(this.listView); | |||||
// Footer | |||||
this.footerView = new FooterView({ collection: this.plugins }); | |||||
this.layout.footerRegion.show(this.footerView); | |||||
// Go | |||||
Backbone.history.start({ | |||||
pushState: true, | |||||
root: window.baseUrl + '/admin/update_center' | |||||
}); | |||||
}; | |||||
App.on('start', options => init.call(App, options)); | |||||
export default function(el, updateCenterActive) { | |||||
App.start({ el, updateCenterActive }); | |||||
return () => { | |||||
Backbone.history.stop(); | |||||
App.layout.destroy(); | |||||
}; | |||||
} |
/* | |||||
* 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 Marionette from 'backbone.marionette'; | |||||
import Template from './templates/update-center-layout.hbs'; | |||||
export default Marionette.LayoutView.extend({ | |||||
template: Template, | |||||
regions: { | |||||
headerRegion: '#update-center-header', | |||||
searchRegion: '#update-center-search', | |||||
listRegion: '#update-center-plugins', | |||||
footerRegion: '#update-center-footer' | |||||
} | |||||
}); |
/* | |||||
* 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 $ from 'jquery'; | |||||
import Backbone from 'backbone'; | |||||
import Marionette from 'backbone.marionette'; | |||||
import PluginChangelogView from './plugin-changelog-view'; | |||||
import Template from './templates/update-center-plugin.hbs'; | |||||
import SystemTemplate from './templates/update-center-system-update.hbs'; | |||||
export default Marionette.ItemView.extend({ | |||||
tagName: 'li', | |||||
className: 'panel panel-vertical', | |||||
template: Template, | |||||
systemTemplate: SystemTemplate, | |||||
modelEvents: { | |||||
'change:_hidden': 'toggleDisplay', | |||||
change: 'onModelChange', | |||||
request: 'onRequest' | |||||
}, | |||||
events: { | |||||
'click .js-changelog': 'onChangelogClick', | |||||
'click .js-install': 'install', | |||||
'click .js-update': 'update', | |||||
'click .js-uninstall': 'uninstall', | |||||
'change .js-terms': 'onTermsChange', | |||||
'click .js-plugin-category': 'onCategoryClick' | |||||
}, | |||||
getTemplate() { | |||||
return this.model.get('_system') ? this.systemTemplate : this.template; | |||||
}, | |||||
onRender() { | |||||
this.$el.attr('data-id', this.model.id); | |||||
if (this.model.get('_system')) { | |||||
this.$el.attr('data-system', ''); | |||||
} | |||||
this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' }); | |||||
}, | |||||
onDestroy() { | |||||
this.$('[data-toggle="tooltip"]').tooltip('destroy'); | |||||
}, | |||||
onModelChange() { | |||||
if (!this.model.hasChanged('_hidden')) { | |||||
this.render(); | |||||
} | |||||
}, | |||||
onChangelogClick(e) { | |||||
e.preventDefault(); | |||||
e.stopPropagation(); | |||||
$('body').click(); | |||||
const index = $(e.currentTarget).data('idx'); | |||||
// if show changelog of update, show details of this update | |||||
// otherwise show changelog of the available release | |||||
const update = this.model.has('release') | |||||
? this.model.toJSON() | |||||
: this.model.get('updates')[index]; | |||||
const popup = new PluginChangelogView({ | |||||
triggerEl: $(e.currentTarget), | |||||
model: new Backbone.Model(update) | |||||
}); | |||||
popup.render(); | |||||
}, | |||||
onRequest() { | |||||
this.$('.js-actions').addClass('hidden'); | |||||
this.$('.js-spinner').removeClass('hidden'); | |||||
}, | |||||
toggleDisplay() { | |||||
this.$el.toggleClass('hidden', this.model.get('_hidden')); | |||||
}, | |||||
install() { | |||||
this.model.install(); | |||||
}, | |||||
update() { | |||||
this.model.update(); | |||||
}, | |||||
uninstall() { | |||||
this.model.uninstall(); | |||||
}, | |||||
onTermsChange() { | |||||
const isAccepted = this.$('.js-terms').is(':checked'); | |||||
this.$('.js-install').prop('disabled', !isAccepted); | |||||
}, | |||||
onCategoryClick(e) { | |||||
e.preventDefault(); | |||||
this.model.trigger('filter', this.model); | |||||
} | |||||
}); |
/* | |||||
* 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 Marionette from 'backbone.marionette'; | |||||
import ListItemView from './list-item-view'; | |||||
export default Marionette.CollectionView.extend({ | |||||
tagName: 'ul', | |||||
childView: ListItemView | |||||
}); |
/* | |||||
* 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 Popup from '../../components/common/popup'; | |||||
import Template from './templates/update-center-plugin-changelog.hbs'; | |||||
export default Popup.extend({ | |||||
template: Template, | |||||
onRender() { | |||||
Popup.prototype.onRender.apply(this, arguments); | |||||
this.$('.bubble-popup-container').isolatedScroll(); | |||||
this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' }); | |||||
}, | |||||
onDestroy() { | |||||
Popup.prototype.onDestroy.apply(this, arguments); | |||||
this.$('[data-toggle="tooltip"]').tooltip('destroy'); | |||||
}, | |||||
serializeData() { | |||||
return { | |||||
...Popup.prototype.serializeData.apply(this, arguments), | |||||
// if there is no status, this is a new plugin | |||||
// => force COMPATIBLE status | |||||
status: this.model.get('status') || 'COMPATIBLE' | |||||
}; | |||||
} | |||||
}); |
/* | |||||
* 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 Backbone from 'backbone'; | |||||
export default Backbone.Model.extend({ | |||||
idAttribute: 'key', | |||||
defaults: { | |||||
_hidden: false, | |||||
_system: false | |||||
}, | |||||
_matchAttribute(attr, query) { | |||||
const value = this.get(attr) || ''; | |||||
return value.toLowerCase().includes(query.toLowerCase()); | |||||
}, | |||||
match(query) { | |||||
return ( | |||||
this._matchAttribute('name', query) || | |||||
this._matchAttribute('category', query) || | |||||
this._matchAttribute('description', query) | |||||
); | |||||
}, | |||||
_action(options) { | |||||
const that = this; | |||||
const opts = { | |||||
...options, | |||||
type: 'POST', | |||||
data: { key: this.id }, | |||||
success() { | |||||
options.success(that); | |||||
}, | |||||
error(jqXHR) { | |||||
that.set({ _status: 'failed', _errors: jqXHR.responseJSON.errors }); | |||||
} | |||||
}; | |||||
const xhr = Backbone.ajax(opts); | |||||
this.trigger('request', this, xhr); | |||||
return xhr; | |||||
}, | |||||
install() { | |||||
return this._action({ | |||||
url: window.baseUrl + '/api/plugins/install', | |||||
success(model) { | |||||
model.set({ _status: 'installing' }); | |||||
} | |||||
}); | |||||
}, | |||||
update() { | |||||
return this._action({ | |||||
url: window.baseUrl + '/api/plugins/update', | |||||
success(model) { | |||||
model.set({ _status: 'updating' }); | |||||
} | |||||
}); | |||||
}, | |||||
uninstall() { | |||||
return this._action({ | |||||
url: window.baseUrl + '/api/plugins/uninstall', | |||||
success(model) { | |||||
model.set({ _status: 'uninstalling' }); | |||||
} | |||||
}); | |||||
} | |||||
}); |
/* | |||||
* 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 $ from 'jquery'; | |||||
import { findLastIndex } from 'lodash'; | |||||
import Backbone from 'backbone'; | |||||
import Plugin from './plugin'; | |||||
const Plugins = Backbone.Collection.extend({ | |||||
model: Plugin, | |||||
comparator(model) { | |||||
return model.get('name') || ''; | |||||
}, | |||||
initialize() { | |||||
this._installedCount = 0; | |||||
this._updatedCount = 0; | |||||
this._uninstalledCount = 0; | |||||
this.listenTo(this, 'change:_status', this.onStatusChange); | |||||
}, | |||||
parse(r) { | |||||
const that = this; | |||||
return r.plugins.map(plugin => { | |||||
let updates = [ | |||||
that._getLastWithStatus(plugin.updates, 'COMPATIBLE'), | |||||
that._getLastWithStatus(plugin.updates, 'REQUIRES_SYSTEM_UPGRADE'), | |||||
that._getLastWithStatus(plugin.updates, 'DEPS_REQUIRE_SYSTEM_UPGRADE') | |||||
].filter(update => update); | |||||
updates = updates.map(update => that._extendChangelog(plugin.updates, update)); | |||||
return { ...plugin, updates }; | |||||
}); | |||||
}, | |||||
_getLastWithStatus(updates, status) { | |||||
const index = findLastIndex(updates, update => update.status === status); | |||||
return index !== -1 ? updates[index] : null; | |||||
}, | |||||
_extendChangelog(updates, update) { | |||||
const index = updates.indexOf(update); | |||||
const previousUpdates = index > 0 ? updates.slice(0, index) : []; | |||||
return { ...update, previousUpdates }; | |||||
}, | |||||
_fetchInstalled() { | |||||
if (this._installed) { | |||||
return $.Deferred() | |||||
.resolve() | |||||
.promise(); | |||||
} | |||||
const that = this; | |||||
const opts = { | |||||
type: 'GET', | |||||
url: window.baseUrl + '/api/plugins/installed?f=category', | |||||
success(r) { | |||||
that._installed = that.parse(r); | |||||
} | |||||
}; | |||||
return Backbone.ajax(opts); | |||||
}, | |||||
_fetchUpdates() { | |||||
if (this._updates) { | |||||
return $.Deferred() | |||||
.resolve() | |||||
.promise(); | |||||
} | |||||
const that = this; | |||||
const opts = { | |||||
type: 'GET', | |||||
url: window.baseUrl + '/api/plugins/updates', | |||||
success(r) { | |||||
that._updates = that.parse(r); | |||||
} | |||||
}; | |||||
return Backbone.ajax(opts); | |||||
}, | |||||
_fetchAvailable() { | |||||
if (this._available) { | |||||
return $.Deferred() | |||||
.resolve() | |||||
.promise(); | |||||
} | |||||
const that = this; | |||||
const opts = { | |||||
type: 'GET', | |||||
url: window.baseUrl + '/api/plugins/available', | |||||
success(r) { | |||||
that._available = that.parse(r); | |||||
} | |||||
}; | |||||
return Backbone.ajax(opts); | |||||
}, | |||||
_fetchPending() { | |||||
const that = this; | |||||
const opts = { | |||||
type: 'GET', | |||||
url: window.baseUrl + '/api/plugins/pending', | |||||
success(r) { | |||||
const installing = r.installing.map(plugin => { | |||||
return { key: plugin.key, _status: 'installing' }; | |||||
}); | |||||
const updating = r.updating.map(plugin => { | |||||
return { key: plugin.key, _status: 'updating' }; | |||||
}); | |||||
const uninstalling = r.removing.map(plugin => { | |||||
return { key: plugin.key, _status: 'uninstalling' }; | |||||
}); | |||||
that._installedCount = installing.length; | |||||
that._updatedCount = updating.length; | |||||
that._uninstalledCount = uninstalling.length; | |||||
that._pending = new Plugins([].concat(installing, updating, uninstalling)).models; | |||||
} | |||||
}; | |||||
return Backbone.ajax(opts); | |||||
}, | |||||
_fetchSystemUpgrades() { | |||||
if (this._systemUpdates) { | |||||
return $.Deferred() | |||||
.resolve() | |||||
.promise(); | |||||
} | |||||
const that = this; | |||||
const opts = { | |||||
type: 'GET', | |||||
url: window.baseUrl + '/api/system/upgrades', | |||||
success(r) { | |||||
that._systemUpdates = r.upgrades.map(update => ({ ...update, _system: true })); | |||||
} | |||||
}; | |||||
return Backbone.ajax(opts); | |||||
}, | |||||
fetchInstalled() { | |||||
const that = this; | |||||
return $.when(this._fetchInstalled(), this._fetchUpdates(), this._fetchPending()).done(() => { | |||||
const plugins = new Plugins(); | |||||
plugins.set(that._installed); | |||||
plugins.set(that._updates, { remove: false }); | |||||
plugins.set(that._pending, { add: false, remove: false }); | |||||
that.reset(plugins.models); | |||||
}); | |||||
}, | |||||
fetchUpdates() { | |||||
const that = this; | |||||
return $.when(this._fetchInstalled(), this._fetchUpdates(), this._fetchPending()).done(() => { | |||||
const plugins = new Plugins(); | |||||
plugins.set(that._installed); | |||||
plugins.set(that._updates, { remove: true }); | |||||
plugins.set(that._pending, { add: false, remove: false }); | |||||
that.reset(plugins.models); | |||||
}); | |||||
}, | |||||
fetchAvailable() { | |||||
const that = this; | |||||
return $.when(this._fetchAvailable(), this._fetchPending()).done(() => { | |||||
const plugins = new Plugins(); | |||||
plugins.set(that._available); | |||||
plugins.set(that._pending, { add: false, remove: false }); | |||||
that.reset(plugins.models); | |||||
}); | |||||
}, | |||||
fetchSystemUpgrades() { | |||||
const that = this; | |||||
return $.when(this._fetchSystemUpgrades()).done(() => { | |||||
that.reset(that._systemUpdates); | |||||
}); | |||||
}, | |||||
search(query) { | |||||
/* eslint-disable array-callback-return */ | |||||
this.filter(model => { | |||||
model.set({ _hidden: !model.match(query) }); | |||||
}); | |||||
}, | |||||
cancelAll() { | |||||
const that = this; | |||||
const opts = { | |||||
type: 'POST', | |||||
url: window.baseUrl + '/api/plugins/cancel_all', | |||||
success() { | |||||
that._installedCount = 0; | |||||
that._updatedCount = 0; | |||||
that._uninstalledCount = 0; | |||||
that.forEach(model => { | |||||
model.unset('_status'); | |||||
}); | |||||
that.trigger('change'); | |||||
} | |||||
}; | |||||
return Backbone.ajax(opts); | |||||
}, | |||||
onStatusChange(model, status) { | |||||
if (status === 'installing') { | |||||
this._installedCount++; | |||||
} | |||||
if (status === 'updating') { | |||||
this._updatedCount++; | |||||
} | |||||
if (status === 'uninstalling') { | |||||
this._uninstalledCount++; | |||||
} | |||||
this.trigger('change'); | |||||
} | |||||
}); | |||||
export default Plugins; |
/* | |||||
* 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 Backbone from 'backbone'; | |||||
export default Backbone.Router.extend({ | |||||
routes: { | |||||
'': 'index', | |||||
installed: 'showInstalled', | |||||
updates: 'showUpdates', | |||||
available: 'showAvailable', | |||||
system: 'showSystemUpgrades' | |||||
}, | |||||
initialize(options) { | |||||
this.controller = options.controller; | |||||
}, | |||||
index() { | |||||
this.navigate('installed', { trigger: true, replace: true }); | |||||
}, | |||||
showInstalled() { | |||||
this.controller.showInstalled(); | |||||
}, | |||||
showUpdates() { | |||||
this.controller.showUpdates(); | |||||
}, | |||||
showAvailable() { | |||||
this.controller.showAvailable(); | |||||
}, | |||||
showSystemUpgrades() { | |||||
this.controller.showSystemUpgrades(); | |||||
} | |||||
}); |
/* | |||||
* 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 { RouterState, RouteComponent, IndexRouteProps } from 'react-router'; | |||||
const routes = [ | |||||
{ | |||||
getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) { | |||||
import('./components/UpdateCenterAppContainer').then(i => | |||||
callback(null, { component: i.default }) | |||||
); | |||||
} | |||||
}, | |||||
{ | |||||
path: 'installed', | |||||
getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { | |||||
import('./components/UpdateCenterAppContainer').then(i => callback(null, i.default)); | |||||
} | |||||
}, | |||||
{ | |||||
path: 'updates', | |||||
getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { | |||||
import('./components/UpdateCenterAppContainer').then(i => callback(null, i.default)); | |||||
} | |||||
}, | |||||
{ | |||||
path: 'available', | |||||
getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { | |||||
import('./components/UpdateCenterAppContainer').then(i => callback(null, i.default)); | |||||
} | |||||
}, | |||||
{ | |||||
path: 'system', | |||||
getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { | |||||
import('./components/UpdateCenterAppContainer').then(i => callback(null, i.default)); | |||||
} | |||||
} | |||||
]; | |||||
export default routes; |
/* | |||||
* 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 { debounce } from 'lodash'; | |||||
import Marionette from 'backbone.marionette'; | |||||
import Template from './templates/update-center-search.hbs'; | |||||
export default Marionette.ItemView.extend({ | |||||
template: Template, | |||||
events: { | |||||
'change [name="update-center-filter"]': 'onFilterChange', | |||||
'submit #update-center-search-form': 'onFormSubmit', | |||||
'search #update-center-search-query': 'onKeyUp', | |||||
'keyup #update-center-search-query': 'onKeyUp', | |||||
'change #update-center-search-query': 'onKeyUp' | |||||
}, | |||||
collectionEvents: { | |||||
filter: 'onFilter' | |||||
}, | |||||
initialize() { | |||||
this._bufferedValue = null; | |||||
this.search = debounce(this.search, 50); | |||||
this.listenTo(this.options.state, 'change', this.render); | |||||
}, | |||||
onRender() { | |||||
this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' }); | |||||
}, | |||||
onDestroy() { | |||||
this.$('[data-toggle="tooltip"]').tooltip('destroy'); | |||||
}, | |||||
onFilterChange() { | |||||
const value = this.$('[name="update-center-filter"]:checked').val(); | |||||
this.filter(value); | |||||
}, | |||||
filter(value) { | |||||
this.options.router.navigate(value, { trigger: true }); | |||||
}, | |||||
onFormSubmit(e) { | |||||
e.preventDefault(); | |||||
this.debouncedOnKeyUp(); | |||||
}, | |||||
onKeyUp() { | |||||
const q = this.getQuery(); | |||||
if (q === this._bufferedValue) { | |||||
return; | |||||
} | |||||
this._bufferedValue = this.getQuery(); | |||||
this.search(q); | |||||
}, | |||||
getQuery() { | |||||
return this.$('#update-center-search-query').val(); | |||||
}, | |||||
search(q) { | |||||
this.collection.search(q); | |||||
}, | |||||
focusSearch() { | |||||
const that = this; | |||||
setTimeout(() => { | |||||
that.$('#update-center-search-query').focus(); | |||||
}, 0); | |||||
}, | |||||
onFilter(model) { | |||||
const q = model.get('category'); | |||||
this.$('#update-center-search-query').val(q); | |||||
this.search(q); | |||||
}, | |||||
serializeData() { | |||||
return { | |||||
...Marionette.ItemView.prototype.serializeData.apply(this, arguments), | |||||
state: this.options.state.toJSON() | |||||
}; | |||||
} | |||||
}); |
<div class="js-actions"> | |||||
{{#if version}} | |||||
<div class="button-group"> | |||||
{{#each updates}} | |||||
{{#eq status 'COMPATIBLE'}} | |||||
<button class="js-update" data-verion="{{release.version}}">{{tp 'update_center.update_to_x' release.version}}</button> | |||||
{{/eq}} | |||||
{{/each}} | |||||
<button class="js-uninstall button-red">{{t 'update_center.uninstall'}}</button> | |||||
</div> | |||||
{{else}} | |||||
{{#if termsAndConditionsUrl}} | |||||
<p class="little-spacer-bottom"> | |||||
<input class="js-terms" type="checkbox" name="plugin-terms" id="plugin-terms-{{key}}"> | |||||
<label for="plugin-terms-{{key}}"> | |||||
{{t 'update_center.i_accept_the'}} | |||||
<a class="js-plugin-terms nowrap" href="{{termsAndConditionsUrl}}" target="_blank">{{t 'update_center.terms_and_conditions'}}</a> | |||||
</label> | |||||
</p> | |||||
<button class="js-install" disabled>{{t 'update_center.install'}}</button> | |||||
{{else}} | |||||
<button class="js-install">{{t 'update_center.install'}}</button> | |||||
{{/if}} | |||||
{{/if}} | |||||
</div> |
<div class="little-spacer-bottom"> | |||||
{{#notEq status 'COMPATIBLE'}} | |||||
<span class="js-plugin-changelog-version badge badge-warning spacer-right" data-toggle="tooltip" | |||||
title="{{t 'update_center.status' status}}">{{release.version}}</span> | |||||
{{else}} | |||||
<span class="js-plugin-changelog-version badge badge-success spacer-right">{{release.version}}</span> | |||||
{{/notEq}} | |||||
<span class="js-plugin-changelog-date note spacer-right">{{d release.date}}</span> | |||||
{{#if release.changeLogUrl}} | |||||
<a class="js-plugin-changelog-link" href="{{release.changeLogUrl}}" target="_blank">{{t 'update_center.release_notes'}}</a> | |||||
{{/if}} | |||||
</div> | |||||
<div class="js-plugin-changelog-description">{{{release.description}}}</div> |
<footer class="spacer-top note text-center"> | |||||
{{tp 'x_show' total}} | |||||
</footer> |
<header class="page-header"> | |||||
<h1 class="page-title">{{t 'update_center.page'}}</h1> | |||||
<p class="page-description">{{t 'update_center.page.description'}}</p> | |||||
</header> | |||||
{{#any installing updating uninstalling}} | |||||
<div class="js-pending panel panel-warning big-spacer-bottom"> | |||||
<div class="display-inline-block"> | |||||
<p>{{t 'update_center.sonarqube_needs_to_be_restarted_to'}}</p> | |||||
<ul class="list-styled spacer-top"> | |||||
{{#if installing}} | |||||
<li> | |||||
{{t 'update_center._install'}} | |||||
<strong class="big text-success little-spacer-left little-spacer-right">{{installing}}</strong> plugins | |||||
</li> | |||||
{{/if}} | |||||
{{#if updating}} | |||||
<li> | |||||
{{t 'update_center._update'}} | |||||
<strong class="big text-success little-spacer-left little-spacer-right">{{updating}}</strong> plugins | |||||
</li> | |||||
{{/if}} | |||||
{{#if uninstalling}} | |||||
<li> | |||||
{{t 'update_center._uninstall'}} | |||||
<strong class="big text-danger little-spacer-left little-spacer-right">{{uninstalling}}</strong> plugins | |||||
</li> | |||||
{{/if}} | |||||
</ul> | |||||
</div> | |||||
<div class="pull-right"> | |||||
<button class="js-restart">{{t 'update_center.restart'}}</button> | |||||
<button class="js-cancel-all button-red">{{t 'update_center.revert'}}</button> | |||||
</div> | |||||
</div> | |||||
{{/any}} |
<div class="page page-limited"> | |||||
<div id="update-center-header"></div> | |||||
<div id="update-center-search"></div> | |||||
<div id="update-center-plugins"></div> | |||||
<div id="update-center-footer"></div> | |||||
</div> |
<div class="bubble-popup-container"> | |||||
<div class="bubble-popup-title">{{t 'changelog'}}</div> | |||||
<ul class="js-plugin-changelog-list"> | |||||
{{#each previousUpdates}} | |||||
<li class="big-spacer-bottom"> | |||||
{{> '_update-center-plugin-changelog-entry'}} | |||||
</li> | |||||
{{/each}} | |||||
<li class="spacer-bottom"> | |||||
{{> '_update-center-plugin-changelog-entry'}} | |||||
</li> | |||||
</ul> | |||||
</div> | |||||
<div class="bubble-popup-arrow"></div> |
<table class="width-100"> | |||||
<tr> | |||||
<td class="text-top width-20 big-spacer-right"> | |||||
<div> | |||||
<strong class="js-plugin-name">{{name}}</strong> | |||||
{{#if category}} | |||||
<a class="js-plugin-category badge spacer-left" href="#">{{category}}</a> | |||||
{{/if}} | |||||
</div> | |||||
<div class="js-plugin-description little-spacer-top">{{{description}}}</div> | |||||
</td> | |||||
<td class="text-top big-spacer-right"> | |||||
<ul> | |||||
{{#if version}} | |||||
<li class="little-spacer-bottom"> | |||||
<strong class="js-plugin-installed-version">{{version}}</strong> {{t 'update_center._installed'}} | |||||
</li> | |||||
{{/if}} | |||||
{{#notEmpty updates}} | |||||
<li class="little-spacer-bottom spacer-top"> | |||||
<strong>{{t 'update_center.updates'}}:</strong> | |||||
</li> | |||||
{{#each updates}} | |||||
<li class="little-spacer-bottom"> | |||||
<div class="pull-left spacer-right"> | |||||
{{#notEq status 'COMPATIBLE'}} | |||||
<span class="js-update-version badge badge-warning" data-toggle="tooltip" | |||||
title="{{t 'update_center.status' status}}">{{release.version}}</span> | |||||
{{else}} | |||||
<span class="js-update-version badge badge-success">{{release.version}}</span> | |||||
{{/notEq}} | |||||
</div> | |||||
<div class="overflow-hidden"> | |||||
{{{release.description}}} | |||||
<button class="button-link js-changelog issue-rule icon-ellipsis-h" data-idx="{{@index}}"></button> | |||||
</div> | |||||
</li> | |||||
{{/each}} | |||||
{{/notEmpty}} | |||||
{{#if release}} | |||||
<li class="little-spacer-bottom"> | |||||
<div class="pull-left spacer-right"> | |||||
<span class="badge badge-success">{{release.version}}</span> | |||||
</div> | |||||
<div class="overflow-hidden"> | |||||
{{{release.description}}} | |||||
<button class="button-link js-changelog issue-rule icon-ellipsis-h" data-idx="{{@index}}"></button> | |||||
{{#notEmpty update.requires}} | |||||
<p class="little-spacer-top"> | |||||
<strong>{{t 'update_center.installing_this_plugin_will_also_install'}}</strong>: {{#each update.requires}} {{name}}{{/each}} | |||||
</p> | |||||
{{/notEmpty}} | |||||
</div> | |||||
</li> | |||||
{{/if}} | |||||
</ul> | |||||
</td> | |||||
<td class="text-top width-20 big-spacer-right"> | |||||
<ul> | |||||
{{#any homepageUrl issueTrackerUrl termsAndConditionsUrl}} | |||||
<li class="little-spacer-bottom"> | |||||
<ul class="list-inline"> | |||||
{{#if homepageUrl}} | |||||
<li><a class="js-plugin-homepage" href="{{homepageUrl}}" target="_blank">{{t 'update_center.homepage'}}</a></li> | |||||
{{/if}} | |||||
{{#if issueTrackerUrl}} | |||||
<li><a class="js-plugin-issues" href="{{issueTrackerUrl}}" target="_blank">{{t 'update_center.issue_tracker'}}</a></li> | |||||
{{/if}} | |||||
</ul> | |||||
</li> | |||||
{{/any}} | |||||
{{#if license}} | |||||
<li class="little-spacer-bottom text-limited" title="{{license}}"> | |||||
{{t 'update_center.licensed_under'}} | |||||
<span class="js-plugin-license">{{license}}</span> | |||||
</li> | |||||
{{/if}} | |||||
{{#if organizationName}} | |||||
<li class="little-spacer-bottom"> | |||||
{{t 'update_center.developed_by'}} | |||||
{{#if organizationUrl}} | |||||
<a class="js-plugin-organization" href="{{organizationUrl}}" target="_blank">{{organizationName}}</a> | |||||
{{else}} | |||||
<span class="js-plugin-organization">{{organizationName}}</span> | |||||
{{/if}} | |||||
</li> | |||||
{{/if}} | |||||
</ul> | |||||
</td> | |||||
<td class="text-top text-right width-20"> | |||||
{{#eq _status 'installing'}} | |||||
<p class="text-success">{{t 'update_center.install_pending'}}</p> | |||||
{{/eq}} | |||||
{{#eq _status 'updating'}} | |||||
<p class="text-success">{{t 'update_center.update_pending'}}</p> | |||||
{{/eq}} | |||||
{{#eq _status 'uninstalling'}} | |||||
<p class="text-danger">{{t 'update_center.uninstall_pending'}}</p> | |||||
{{/eq}} | |||||
{{#eq _status 'failed'}} | |||||
<span class="text-danger"> | |||||
{{#each _errors}} | |||||
{{msg}} | |||||
{{/each}} | |||||
</span> | |||||
{{/eq}} | |||||
{{#unless _status}} | |||||
<i class="js-spinner spinner hidden"></i> | |||||
{{> '_update-center-plugin-actions'}} | |||||
{{/unless}} | |||||
</td> | |||||
</tr> | |||||
</table> |
<div class="panel panel-vertical bordered-bottom spacer-bottom"> | |||||
<div class="display-inline-block text-top nowrap big-spacer-right"> | |||||
<ul class="radio-toggle"> | |||||
<li> | |||||
<input type="radio" name="update-center-filter" value="installed" id="update-center-filter-installed" | |||||
{{#eq state.section 'installed'}}checked{{/eq}}> | |||||
<label for="update-center-filter-installed">{{t 'update_center.installed'}}</label> | |||||
</li> | |||||
<li> | |||||
<input type="radio" name="update-center-filter" value="updates" id="update-center-filter-updates" | |||||
{{#eq state.section 'updates'}}checked{{/eq}} {{#unless state.updateCenterActive}}disabled{{/unless}}> | |||||
<label for="update-center-filter-updates" | |||||
{{#unless state.updateCenterActive}}data-toggle="tooltip" title="{{t 'update_center.not_activated'}}"{{/unless}}> | |||||
{{t 'update_center.updates_only'}} | |||||
</label> | |||||
</li> | |||||
<li> | |||||
<input type="radio" name="update-center-filter" value="available" id="update-center-filter-available" | |||||
{{#eq state.section 'available'}}checked{{/eq}} {{#unless state.updateCenterActive}}disabled{{/unless}}> | |||||
<label for="update-center-filter-available" | |||||
{{#unless state.updateCenterActive}}data-toggle="tooltip" title="{{t 'update_center.not_activated'}}"{{/unless}}> | |||||
{{t 'update_center.available'}} | |||||
</label> | |||||
</li> | |||||
</ul> | |||||
<ul class="radio-toggle"> | |||||
<li> | |||||
<input type="radio" name="update-center-filter" value="system" id="update-center-filter-system" | |||||
{{#eq state.section 'system'}}checked{{/eq}} {{#unless state.updateCenterActive}}disabled{{/unless}}> | |||||
<label for="update-center-filter-system" | |||||
{{#unless state.updateCenterActive}}data-toggle="tooltip" title="{{t 'update_center.not_activated'}}"{{/unless}}> | |||||
{{t 'update_center.system_upgrades'}} | |||||
</label> | |||||
</li> | |||||
</ul> | |||||
</div> | |||||
{{#notEq state.section 'system'}} | |||||
<form id="update-center-search-form" class="search-box display-inline-block text-top"> | |||||
<button id="update-center-search-submit" class="search-box-submit button-clean"><i class="icon-search"></i> | |||||
</button> | |||||
<input id="update-center-search-query" class="search-box-input" type="search" name="q" placeholder="{{t 'search_verb'}}" | |||||
maxlength="100" autocomplete="off"> | |||||
</form> | |||||
{{/notEq}} | |||||
</div> |
<table class="width-100"> | |||||
<tr> | |||||
<td class="text-top thin big-spacer-right"> | |||||
<svg width="60" height="60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"> | |||||
<g id="Layer1"> | |||||
<path d="M52.0841,58.4777L48.8003,58.4777C48.8003,32.0551 26.9663,10.4603 0,10.4603L0,7.06778C28.7278,7.06778 52.1493,30.2719 52.1493,58.4777L52.084,58.4777L52.0841,58.4777Z" style="fill:rgb(75,159,213);fill-rule:nonzero;"/> | |||||
<path d="M54.3675,40.7974C50.4096,24.2044 36.97,10.2646 20.0072,5.45851L20.7684,2.7619C38.6228,7.95943 52.8453,22.5952 56.9554,40.2755L54.3675,40.7974L54.3675,40.7974L54.3675,40.7974Z" style="fill:rgb(75,159,213);fill-rule:nonzero;"/> | |||||
<path d="M58.0863,25.27C53.9978,16.332 47.1475,8.65532 38.5792,3.47949L39.6666,1.52228C48.561,6.87202 55.8898,15.0924 60,24.3784L58.0863,25.27L58.0863,25.27L58.0863,25.27L58.0863,25.27Z" style="fill:rgb(75,159,213);fill-rule:nonzero;"/> | |||||
</g> | |||||
</svg> | |||||
</td> | |||||
<td class="text-top width-20 big-spacer-right"> | |||||
<div> | |||||
<strong class="js-plugin-name">SonarQube {{version}}</strong> | |||||
<span class="js-plugin-category badge badge-success spacer-left">{{t 'update_center.system_upgrade'}}</span> | |||||
</div> | |||||
<div class="js-plugin-description little-spacer-top">{{{description}}}</div> | |||||
<ul class="big-spacer-top"> | |||||
{{#if changeLogUrl}} | |||||
<li class="little-spacer-bottom"> | |||||
<a class="js-plugin-release-notes" href="{{changeLogUrl}}" target="_blank">{{t 'update_center.release_notes'}}</a> | |||||
</li> | |||||
{{/if}} | |||||
{{#if releaseDate}} | |||||
<li class="little-spacer-bottom">{{t 'update_center.released'}}: <span class="js-plugin-date">{{d releaseDate}}</span></li> | |||||
{{/if}} | |||||
</ul> | |||||
</td> | |||||
<td class="text-top width-60"> | |||||
<div class="pull-left spacer-right"> | |||||
<strong>{{t 'update_center.how_to_upgrade'}}</strong> | |||||
</div> | |||||
<ol class="js-plugin-update-steps list-styled overflow-hidden bordered-left"> | |||||
<li class="little-spacer-bottom"> | |||||
{{t 'update_center.how_to_upgrade.1'}} | |||||
</li> | |||||
<li class="little-spacer-bottom"> | |||||
{{t 'update_center.how_to_upgrade.2'}} | |||||
</li> | |||||
<li class="little-spacer-bottom"> | |||||
{{t 'update_center.how_to_upgrade.3'}} | |||||
</li> | |||||
<li class="little-spacer-bottom"> | |||||
{{t 'update_center.how_to_upgrade.4'}} | |||||
</li> | |||||
<li class="little-spacer-bottom"> | |||||
{{t 'update_center.how_to_upgrade.5'}} | |||||
</li> | |||||
<li> | |||||
{{t 'update_center.how_to_upgrade.6'}} | |||||
</li> | |||||
</ol> | |||||
</td> | |||||
</tr> | |||||
</table> |
marketplace.commercial_edition=Commercial Edition | marketplace.commercial_edition=Commercial Edition | ||||
marketplace.terms_and_conditions=Terms and Conditions | marketplace.terms_and_conditions=Terms and Conditions | ||||
marketplace.editions_unavailable=Explore our Commercial Editions: advanced feature packs brought to you by SonarSource on {url} | marketplace.editions_unavailable=Explore our Commercial Editions: advanced feature packs brought to you by SonarSource on {url} | ||||
marketplace.release_notes=Release Notes | |||||
marketplace.status.AUTOMATIC_IN_PROGRESS=Updating your installation... Please wait... | marketplace.status.AUTOMATIC_IN_PROGRESS=Updating your installation... Please wait... | ||||
marketplace.status.AUTOMATIC_READY=Commercial Edition successfully installed. Please restart Server to activate your new features. | marketplace.status.AUTOMATIC_READY=Commercial Edition successfully installed. Please restart Server to activate your new features. | ||||
marketplace.status.UNINSTALL_IN_PROGRESS=Commercial Edition successfully uninstalled. Please restart Server to remove the features. | marketplace.status.UNINSTALL_IN_PROGRESS=Commercial Edition successfully uninstalled. Please restart Server to remove the features. | ||||
marketplace.i_need_a_license=I need a license key | marketplace.i_need_a_license=I need a license key | ||||
marketplace.download_package=Download package | marketplace.download_package=Download package | ||||
#------------------------------------------------------------------------------ | |||||
# | |||||
# UPDATE CENTER | |||||
# | |||||
#------------------------------------------------------------------------------ | |||||
update_center.page=Update Center | |||||
update_center.page.description=Install, uninstall and delete plugins. You can also download SonarQube updates from the System Updates tab on this page. | |||||
update_center.status.COMPATIBLE=Compatible | |||||
update_center.status.INCOMPATIBLE=Incompatible | |||||
update_center.status.REQUIRES_SYSTEM_UPGRADE=Requires system update | |||||
update_center.status.DEPS_REQUIRE_SYSTEM_UPGRADE=Some of dependencies requires system update | |||||
update_center.update_to_x=Update to {0} | |||||
update_center.uninstall=Uninstall | |||||
update_center.i_accept_the=I accept the | |||||
update_center.terms_and_conditions=Terms and Conditions | |||||
update_center.install=Install | |||||
update_center.release_notes=Release Notes | |||||
update_center.sonarqube_needs_to_be_restarted_to=SonarQube needs to be restarted in order to | |||||
update_center._install=install | |||||
update_center._update=update | |||||
update_center._uninstall=uninstall | |||||
update_center.restart=Restart | |||||
update_center.revert=Revert | |||||
update_center.installed=Installed | |||||
update_center._installed=installed | |||||
update_center.updates=Updates | |||||
update_center.installing_this_plugin_will_also_install=Installing this plugin will also install | |||||
update_center.homepage=Homepage | |||||
update_center.issue_tracker=Issue Tracker | |||||
update_center.licensed_under=Licensed under | |||||
update_center.developed_by=Developed by | |||||
update_center.install_pending=Install Pending | |||||
update_center.update_pending=Update Pending | |||||
update_center.uninstall_pending=Uninstall Pending | |||||
update_center.updates_only=Updates Only | |||||
update_center.available=Available | |||||
update_center.not_activated=Update Center is not activated. | |||||
update_center.system_upgrade=System Upgrade | |||||
update_center.system_upgrades=System Upgrades | |||||
update_center.released=Released | |||||
update_center.how_to_upgrade=How to upgrade | |||||
update_center.how_to_upgrade.1=Download the new SonarQube version and start it on an empty DB (the bundled H2 DB for instance). | |||||
update_center.how_to_upgrade.2=Install (from the update center) the plugins you want. | |||||
update_center.how_to_upgrade.3=Install your custom plugins (if any). | |||||
update_center.how_to_upgrade.4=Update the conf/sonar.properties file to use the relevant configurations from your old instance, including the connection information for your production DB. | |||||
update_center.how_to_upgrade.5=Stop your old SonarQube server. | |||||
update_center.how_to_upgrade.6=Restart the new SonarQube instance: you're done! | |||||
#------------------------------------------------------------------------------ | #------------------------------------------------------------------------------ | ||||
# | # |
import com.sonar.orchestrator.Orchestrator; | import com.sonar.orchestrator.Orchestrator; | ||||
import org.junit.After; | import org.junit.After; | ||||
import org.junit.ClassRule; | import org.junit.ClassRule; | ||||
import org.junit.Ignore; | |||||
import org.junit.Rule; | import org.junit.Rule; | ||||
import org.junit.Test; | import org.junit.Test; | ||||
import util.user.UserRule; | import util.user.UserRule; | ||||
userRule.resetUsers(); | userRule.resetUsers(); | ||||
} | } | ||||
@Ignore | |||||
@Test | @Test | ||||
public void test_console() { | public void test_console() { | ||||
runSelenese(orchestrator, "/updateCenter/installed-plugins.html"); | runSelenese(orchestrator, "/updateCenter/installed-plugins.html"); |