rework update ui
- this is not modal anymore - can be canceled
This commit is contained in:
@@ -31,22 +31,6 @@ angular.module('Application').service('Client', ['$http', '$interval', 'md5', 'N
|
||||
function defaultErrorHandler(callback) {
|
||||
return function (data, status) {
|
||||
if (status === 401) return client.login();
|
||||
if (status === 503) {
|
||||
// this could indicate a update/upgrade/restore/migration
|
||||
client.progress(function (error, result) {
|
||||
if (error) {
|
||||
client.error(error);
|
||||
return callback(new ClientError(status, data));
|
||||
}
|
||||
|
||||
if (result.update && result.update.percent !== -1) window.location.href = '/update.html';
|
||||
else callback(new ClientError(status, data));
|
||||
}, function (data, status) {
|
||||
client.error(data);
|
||||
return callback(new ClientError(status, data));
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (status >= 500) {
|
||||
client.error(data);
|
||||
return callback(new ClientError(status, data));
|
||||
@@ -435,16 +419,6 @@ angular.module('Application').service('Client', ['$http', '$interval', 'md5', 'N
|
||||
}).error(defaultErrorHandler(callback));
|
||||
};
|
||||
|
||||
Client.prototype.progress = function (callback, errorCallback) {
|
||||
// this is used in the defaultErrorHandler itself, and avoids a loop
|
||||
if (typeof errorCallback !== 'function') errorCallback = defaultErrorHandler(callback);
|
||||
|
||||
get('/api/v1/cloudron/progress').success(function(data, status) {
|
||||
if (status !== 200 || typeof data !== 'object') return callback(new ClientError(status, data));
|
||||
callback(null, data);
|
||||
}).error(errorCallback);
|
||||
};
|
||||
|
||||
Client.prototype.version = function (callback) {
|
||||
get('/api/v1/cloudron/status').success(function(data, status) {
|
||||
if (status !== 200 || typeof data !== 'object') return callback(new ClientError(status, data));
|
||||
|
||||
@@ -201,11 +201,6 @@ angular.module('Application').controller('MainController', ['$scope', '$route',
|
||||
});
|
||||
|
||||
Client.onConfig(function (config) {
|
||||
// check if we are actually updating
|
||||
// if (config.progress.update && config.progress.update.percent !== -1) {
|
||||
// window.location.href = '/update.html';
|
||||
// }
|
||||
|
||||
if (config.cloudronName) {
|
||||
document.title = config.cloudronName;
|
||||
}
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
// create main application module
|
||||
var app = angular.module('Application', []);
|
||||
|
||||
app.controller('Controller', ['$scope', '$http', '$interval', function ($scope, $http, $interval) {
|
||||
$scope.title = '';
|
||||
$scope.percent = 0;
|
||||
$scope.message = '';
|
||||
$scope.error = false;
|
||||
|
||||
$scope.loadWebadmin = function () {
|
||||
window.location.href = '/';
|
||||
};
|
||||
|
||||
function fetchProgress() {
|
||||
$http.get('/api/v1/cloudron/progress').success(function(data, status) {
|
||||
if (status === 404) return; // just wait until we create the progress.json on the server side
|
||||
if (status !== 200 || typeof data !== 'object') return console.error('Invalid response for progress', status, data);
|
||||
if (!data.update && !data.migrate) return $scope.loadWebadmin();
|
||||
|
||||
if (data.update) {
|
||||
if (data.update.percent >= 100) {
|
||||
return $scope.loadWebadmin();
|
||||
} else if (data.update.percent === -1) {
|
||||
$scope.title = 'Update Error';
|
||||
$scope.error = true;
|
||||
$scope.message = data.update.message;
|
||||
} else {
|
||||
if (data.backup && data.backup.percent < 100) {
|
||||
$scope.title = 'Backup in progress...';
|
||||
$scope.percent = data.backup.percent < 0 ? 5 : (data.backup.percent / 100) * 50; // never show 0 as it looks like nothing happens
|
||||
$scope.message = data.backup.message;
|
||||
} else {
|
||||
$scope.title = 'Update in progress...';
|
||||
$scope.percent = 50 + ((data.update.percent / 100) * 50); // first half is backup
|
||||
$scope.message = data.update.message;
|
||||
}
|
||||
}
|
||||
} else { // migrating
|
||||
if (data.migrate.percent === -1) {
|
||||
$scope.title = 'Migration Error';
|
||||
$scope.error = true;
|
||||
$scope.message = data.migrate.message;
|
||||
} else {
|
||||
$scope.title = 'Migration in progress...';
|
||||
$scope.percent = data.migrate.percent;
|
||||
$scope.message = data.migrate.message;
|
||||
|
||||
if (!data.migrate.info) return;
|
||||
|
||||
// check if the new domain is available via the appstore (cannot use cloudron
|
||||
// directly as we might hit NXDOMAIN)
|
||||
$http.get(data.apiServerOrigin + '/api/v1/boxes/' + data.migrate.info.domain + '/status').success(function(data2, status) {
|
||||
if (status === 200 && data2.status === 'ready') {
|
||||
window.location = 'https://my.' + data.migrate.info.domain;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}).error(function (data, status) {
|
||||
console.error('Error getting progress', status, data);
|
||||
});
|
||||
}
|
||||
|
||||
$interval(fetchProgress, 2000);
|
||||
|
||||
fetchProgress();
|
||||
}]);
|
||||
@@ -1,69 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height"/>
|
||||
|
||||
<title> Cloudron Update </title>
|
||||
|
||||
<link id="favicon" href="/api/v1/cloudron/avatar" rel="icon" type="image/png">
|
||||
|
||||
<!-- Theme CSS -->
|
||||
<link type="text/css" rel="stylesheet" href="/theme.css">
|
||||
|
||||
<!-- Custom Fonts -->
|
||||
<link type="text/css" rel="stylesheet" href="/3rdparty/fontawesome/css/all.min.css">
|
||||
|
||||
<!-- jQuery-->
|
||||
<script type="text/javascript" src="/3rdparty/js/jquery.min.js"></script>
|
||||
|
||||
<!-- Bootstrap Core JavaScript -->
|
||||
<script type="text/javascript" src="/3rdparty/js/bootstrap.min.js"></script>
|
||||
|
||||
<!-- Angularjs scripts -->
|
||||
<script type="text/javascript" src="/3rdparty/js/angular.min.js"></script>
|
||||
<script type="text/javascript" src="/3rdparty/js/angular-loader.min.js"></script>
|
||||
|
||||
<!-- Update Application -->
|
||||
<script type="text/javascript" src="/js/update.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body ng-app="Application" ng-controller="Controller" style="background-color: #7F7F7F">
|
||||
|
||||
<div class="modal show" id="updateProgressModal" tabindex="-1" role="dialog" aria-labelledby="updateProgressModalLabel" aria-hidden="true" data-keyboard="false" data-backdrop="static">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title" ng-show="!error">{{title}}</h4>
|
||||
<h4 class="modal-title text-danger" ng-show="error">{{title}}</h4>
|
||||
</div>
|
||||
<div class="modal-body" ng-show="!error">
|
||||
<div class="progress progress-striped active">
|
||||
<div class="progress-bar progress-bar-success" role="progressbar" style="width: {{percent}}%"></div>
|
||||
</div>
|
||||
<span>{{message}}</span>
|
||||
</div>
|
||||
<div class="modal-body" ng-show="error">
|
||||
<span>{{message}}</span>
|
||||
</div>
|
||||
<div class="modal-footer" ng-show="error">
|
||||
<button type="button" class="btn btn-primary" ng-click="loadWebadmin()">OK</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layout-root">
|
||||
<div class="layout-content"></div>
|
||||
|
||||
<footer class="text-center">
|
||||
<span class="text-muted">©2018 <a href="https://cloudron.io" target="_blank">Cloudron</a></span>
|
||||
<span class="text-muted"><a href="https://twitter.com/cloudron_io" target="_blank">Twitter <i class="fa fa-twitter"></i></a></span>
|
||||
<span class="text-muted"><a href="https://forum.cloudron.io" target="_blank">Forum <i class="fa fa-comments"></i></a></span>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+13
-17
@@ -19,30 +19,17 @@
|
||||
</div>
|
||||
|
||||
<div ng-show="installedApps | readyToUpdate">
|
||||
<b ng-show="config.update.box.upgrade" class="text-danger">
|
||||
This update upgrades the base system and will cause some application downtime.<br/>
|
||||
</b>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li ng-repeat="change in config.update.box.changelog" ng-bind-html="change | markdown2html"></li>
|
||||
</ul>
|
||||
<br/>
|
||||
<p ng-show="update.error.generic" class="text-danger">{{ update.error.generic }}</p>
|
||||
<div ng-hide="config.provider !== 'caas' && config.update.box.upgrade">
|
||||
<fieldset>
|
||||
<form name="update_form" role="form" ng-submit="update.submit()" autocomplete="off">
|
||||
<input class="ng-hide" type="submit" ng-disabled="update_form.$invalid || update.busy"/>
|
||||
</form>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div ng-show="config.provider !== 'caas' && config.update.box.upgrade">
|
||||
<b>Please use the CLI tool to upgrade by following the instructions <a ng-href="{{ config.webServerOrigin + '/documentation/updates/' }}" target="_blank" >here</a>.</b>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
<button type="button" class="btn btn-success" ng-click="update.submit()" ng-disabled="update_form.$invalid || update.busy" ng-show="(installedApps | readyToUpdate) && !(config.provider !== 'caas' && config.update.box.upgrade)"><i class="fa fa-circle-notch fa-spin" ng-show="update.busy"></i> Update</button>
|
||||
<button type="button" class="btn btn-success" ng-click="update.startUpdate()" ng-disabled="update.busy" ng-show="(installedApps | readyToUpdate)"><i class="fa fa-circle-notch fa-spin" ng-show="update.busy"></i> Update</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -185,10 +172,19 @@
|
||||
<td colspan="2"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-muted" style="vertical-align: top;"></td>
|
||||
<td class="text-muted" style="vertical-align: top;">
|
||||
<div ng-show="update.busy" class="progress progress-striped active animateMe">
|
||||
<div class="progress-bar progress-bar-success" role="progressbar" style="width: {{update.percent}}%"></div>
|
||||
</div>
|
||||
<div>
|
||||
<div ng-show="update.busy">{{ update.message }}</div>
|
||||
<div class="has-error" ng-show="!update.busy && update.errorMessage">{{ update.errorMessage }}</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-right" style="vertical-align: bottom;">
|
||||
<button class="btn btn-primary pull-right" ng-hide="config.update.box" ng-disabled="autoUpdate.busy" ng-click="autoUpdate.checkNow()"><i class="fa fa-circle-notch fa-spin" ng-show="autoUpdate.busy"></i> Check for Updates</button>
|
||||
<button class="btn btn-success pull-right" ng-show="config.update.box" ng-click="update.show(update_form)">Update Available</button>
|
||||
<button class="btn btn-primary pull-right" ng-show="!config.update.box && !update.busy" ng-disabled="autoUpdate.busy" ng-click="autoUpdate.checkNow()"><i class="fa fa-circle-notch fa-spin" ng-show="autoUpdate.busy"></i> Check for Updates</button>
|
||||
<button class="btn btn-success pull-right" ng-show="config.update.box && !update.busy" ng-click="update.show()">Update Available</button>
|
||||
<button class="btn btn-danger pull-right" ng-show="config.update.box && update.busy" ng-click="update.stopUpdate()">Stop Update</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
+52
-7
@@ -26,16 +26,16 @@ angular.module('Application').controller('SettingsController', ['$scope', '$loca
|
||||
};
|
||||
|
||||
$scope.update = {
|
||||
error: {},
|
||||
error: {}, // this is for the dialog
|
||||
busy: false,
|
||||
percent: 0,
|
||||
message: '',
|
||||
errorMessage: '', // this shows inline
|
||||
|
||||
show: function (form) {
|
||||
show: function () {
|
||||
$scope.update.error.generic = null;
|
||||
$scope.update.busy = false;
|
||||
|
||||
form.$setPristine();
|
||||
form.$setUntouched();
|
||||
|
||||
if (!$scope.config.update.box.sourceTarballUrl) {
|
||||
$('#setupSubscriptionModal').modal('show');
|
||||
} else {
|
||||
@@ -43,9 +43,52 @@ angular.module('Application').controller('SettingsController', ['$scope', '$loca
|
||||
}
|
||||
},
|
||||
|
||||
submit: function () {
|
||||
stopUpdate: function () {
|
||||
Client.stopTask('update', function (error) {
|
||||
if (error) {
|
||||
if (error.statusCode === 409) {
|
||||
$scope.update.errorMessage = 'No update is currently in progress';
|
||||
} else {
|
||||
console.error(error);
|
||||
$scope.update.errorMessage = error.message;
|
||||
}
|
||||
|
||||
$scope.update.busy = false;
|
||||
|
||||
return;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
updateStatus: function () {
|
||||
Client.getTaskProgress('update', function (error, data) {
|
||||
if (error) return window.setTimeout($scope.update.updateStatus, 2000);
|
||||
|
||||
if (!data.active) {
|
||||
$scope.update.busy = false;
|
||||
$scope.update.message = '';
|
||||
$scope.update.percent = 100; // indicates that 'result' is valid
|
||||
$scope.update.errorMessage = data.errorMessage;
|
||||
|
||||
if (!data.errorMessage) window.location.reload(true); // assume success
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.update.busy = true;
|
||||
$scope.update.percent = data.percent;
|
||||
$scope.update.message = data.message;
|
||||
|
||||
window.setTimeout($scope.update.updateStatus, 500);
|
||||
});
|
||||
},
|
||||
|
||||
startUpdate: function () {
|
||||
$scope.update.error.generic = null;
|
||||
$scope.update.busy = true;
|
||||
$scope.update.percent = 0;
|
||||
$scope.update.message = '';
|
||||
$scope.update.errorMessage = '';
|
||||
|
||||
Client.update(function (error) {
|
||||
if (error) {
|
||||
@@ -59,7 +102,9 @@ angular.module('Application').controller('SettingsController', ['$scope', '$loca
|
||||
return;
|
||||
}
|
||||
|
||||
window.location.href = '/update.html';
|
||||
$('#updateModal').modal('hide');
|
||||
|
||||
$scope.update.updateStatus();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user