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);
+}
*/
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';
'ComputeEngine'];
export default React.createClass({
+ getInitialState() {
+ return { restarting: false };
+ },
+
componentDidMount() {
getSystemInfo().then(info => this.setState({ sections: this.parseSections(info) }));
},
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}/>;
});
<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}
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,
},
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
});
}
});
{{/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}}
float: right;
margin-bottom: 10px;
margin-left: 10px;
+ line-height: @formControlHeight;
.badge {
margin: 3px 0;
}
+
+ .spinner {
+ top: 0 !important;
+ }
}
.page-description {