diff --git a/dashboard/src/views/apps.js b/dashboard/src/views/apps.js
index 098311450..343f37f91 100644
--- a/dashboard/src/views/apps.js
+++ b/dashboard/src/views/apps.js
@@ -4,6 +4,7 @@
/* global $:false */
/* global APP_TYPES */
/* global onAppClick */
+/* global localStorage, document, FileReader */
angular.module('Application').controller('AppsController', ['$scope', '$translate', '$interval', '$location', 'Client', function ($scope, $translate, $interval, $location, Client) {
var ALL_DOMAINS_DOMAIN = { _alldomains: true, domain: 'All Domains' }; // dummy record for the single select filter
diff --git a/dashboard/src/views/support.html b/dashboard/src/views/support.html
index 22b616594..4bd75821e 100644
--- a/dashboard/src/views/support.html
+++ b/dashboard/src/views/support.html
@@ -18,6 +18,25 @@
+
+
Troubleshoot
+
+
+
+
+
+
+
Troubleshooting tools
+
+
+
+
+
{{ troubleshootingMessage }}
+
+
+
+
+
diff --git a/dashboard/src/views/support.js b/dashboard/src/views/support.js
index 2918bc0e1..4df7e3f52 100644
--- a/dashboard/src/views/support.js
+++ b/dashboard/src/views/support.js
@@ -2,6 +2,8 @@
/* global angular:false */
/* global $:false */
+/* global ISTATES */
+/* global async */
angular.module('Application').controller('SupportController', ['$scope', '$location', 'Client', function ($scope, $location, Client) {
Client.onReady(function () { if (!Client.getUserInfo().isAtLeastOwner) $location.path('/'); });
@@ -9,10 +11,63 @@ angular.module('Application').controller('SupportController', ['$scope', '$locat
$scope.ready = false;
$scope.config = Client.getConfig();
$scope.user = Client.getUserInfo();
+ $scope.installedApps = Client.getInstalledApps();
$scope.toggleSshSupportError = '';
$scope.sshSupportEnabled = false;
+ $scope.troubleshoot = $location.search().troubleshoot;
+
+ $scope.updateAllBusy = false;
+ $scope.repairAllBusy = false;
+ $scope.troubleshootingMessage = '';
+
+ $scope.updateAll = function () {
+ $scope.updateAllBusy = true;
+ $scope.troubleshootingMessage = '';
+ let count = 0, unstable = 0;
+
+ Client.checkForUpdates(function (error) {
+ if (error) Client.error(error);
+
+ async.eachSeries(Object.keys($scope.config.update), function (appId, iteratorDone) {
+ if ($scope.config.update[appId].unstable) { ++unstable; return iteratorDone(); }
+
+ Client.updateApp(appId, $scope.config.update[appId].manifest, { skipBackup: false }, function (error) {
+ if (error) Client.error(error);
+ else ++count;
+
+ iteratorDone();
+ });
+ }, function () {
+ $scope.troubleshootingMessage = `${count} apps updated. ${unstable} apps with unstable updates skipped.`;
+ $scope.updateAllBusy = false;
+ });
+ });
+ };
+
+ $scope.repairAll = function () {
+ $scope.repairAllBusy = true;
+ $scope.troubleshootingMessage = '';
+ let count = 0;
+
+ Client.refreshInstalledApps(function () {
+ async.eachSeries($scope.installedApps, function (app, iteratorDone) {
+ if (app.installationState !== ISTATES.ERROR) return iteratorDone();
+
+ Client.repairApp(app.id, {}, function (error) {
+ if (error) Client.error(error);
+ else ++count;
+
+ iteratorDone();
+ });
+ }, function () {
+ $scope.troubleshootingMessage = `${count} apps repaired.`;
+ $scope.repairAllBusy = false;
+ });
+ });
+ };
+
$scope.toggleSshSupport = function () {
$scope.toggleSshSupportError = '';