@@ -29,3 +29,31 @@ export function getSystemInfo () { | |||
const url = window.baseUrl + '/api/system/info'; | |||
return getJSON(url); | |||
} | |||
export function getStatus () { | |||
const url = window.baseUrl + '/api/system/status'; | |||
return getJSON(url); | |||
} | |||
export function restart () { | |||
const url = window.baseUrl + '/api/system/restart'; | |||
return post(url); | |||
} | |||
const POLLING_INTERVAL = 2000; | |||
function pollStatus (cb) { | |||
setTimeout(() => { | |||
getStatus() | |||
.then(() => cb()) | |||
.catch(() => pollStatus(cb)); | |||
}, POLLING_INTERVAL); | |||
} | |||
function promiseStatus () { | |||
return new Promise(resolve => pollStatus(resolve)); | |||
} | |||
export function restartAndWait () { | |||
return restart().then(promiseStatus); | |||
} |
@@ -19,7 +19,7 @@ | |||
*/ | |||
import _ from 'underscore'; | |||
import React from 'react'; | |||
import { getSystemInfo } from '../../api/system'; | |||
import { getSystemInfo, restartAndWait } from '../../api/system'; | |||
import Section from './section'; | |||
import { translate } from '../../helpers/l10n'; | |||
@@ -27,6 +27,10 @@ const SECTIONS_ORDER = ['SonarQube', 'Database', 'Plugins', 'System', 'ElasticSe | |||
'ComputeEngine']; | |||
export default React.createClass({ | |||
getInitialState() { | |||
return { restarting: false }; | |||
}, | |||
componentDidMount() { | |||
getSystemInfo().then(info => this.setState({ sections: this.parseSections(info) })); | |||
}, | |||
@@ -53,9 +57,16 @@ export default React.createClass({ | |||
return _.sortBy(items, 'name'); | |||
}, | |||
handleServerRestart () { | |||
this.setState({ restarting: true }); | |||
restartAndWait().then(() => { | |||
document.location.reload(); | |||
}); | |||
}, | |||
render() { | |||
let sections = null; | |||
if (this.state && this.state.sections) { | |||
if (this.state.sections) { | |||
sections = this.state.sections.map(section => { | |||
return <Section key={section.name} section={section.name} items={section.items}/>; | |||
}); | |||
@@ -67,6 +78,16 @@ export default React.createClass({ | |||
<div className="page-actions"> | |||
<a className="spacer-right" href={window.baseUrl + '/api/system/logs'} id="logs-link">Logs</a> | |||
<a href={window.baseUrl + '/api/system/info'} id="download-link">Download</a> | |||
{this.state.restarting ? ( | |||
<i className="spinner"/> | |||
) : ( | |||
<button | |||
id="restart-server-button" | |||
className="big-spacer-left" | |||
onClick={this.handleServerRestart}> | |||
Restart Server | |||
</button> | |||
)} | |||
</div> | |||
</header> | |||
{sections} |
@@ -20,6 +20,7 @@ | |||
import _ from 'underscore'; | |||
import Marionette from 'backbone.marionette'; | |||
import Template from './templates/update-center-header.hbs'; | |||
import { restartAndWait } from '../../api/system'; | |||
export default Marionette.ItemView.extend({ | |||
template: Template, | |||
@@ -29,17 +30,31 @@ export default Marionette.ItemView.extend({ | |||
}, | |||
events: { | |||
'click .js-restart': 'restart', | |||
'click .js-cancel-all': 'cancelAll' | |||
}, | |||
cancelAll: function () { | |||
initialize () { | |||
this.restarting = false; | |||
}, | |||
restart () { | |||
this.restarting = true; | |||
this.render(); | |||
restartAndWait().then(() => { | |||
document.location.reload(true); | |||
}); | |||
}, | |||
cancelAll () { | |||
this.collection.cancelAll(); | |||
}, | |||
serializeData: function () { | |||
serializeData () { | |||
return _.extend(Marionette.ItemView.prototype.serializeData.apply(this, arguments), { | |||
installing: this.collection._installedCount, | |||
uninstalling: this.collection._uninstalledCount | |||
uninstalling: this.collection._uninstalledCount, | |||
restarting: this.restarting | |||
}); | |||
} | |||
}); |
@@ -21,8 +21,13 @@ | |||
{{/if}} | |||
</p> | |||
</div> | |||
<div class="button-group pull-right"> | |||
<button class="js-cancel-all button-red">Revert</button> | |||
<div class="pull-right"> | |||
{{#if restarting}} | |||
<i class="spinner"></i> | |||
{{else}} | |||
<button class="js-restart">Restart</button> | |||
<button class="js-cancel-all button-red">Revert</button> | |||
{{/if}} | |||
</div> | |||
</div> | |||
{{/any}} |
@@ -86,10 +86,15 @@ body { | |||
float: right; | |||
margin-bottom: 10px; | |||
margin-left: 10px; | |||
line-height: @formControlHeight; | |||
.badge { | |||
margin: 3px 0; | |||
} | |||
.spinner { | |||
top: 0 !important; | |||
} | |||
} | |||
.page-description { |