'use strict'; angular.module('Application').controller('MainController', ['$scope', '$route', '$timeout', '$location', 'Client', 'AppStore', function ($scope, $route, $timeout, $location, Client, AppStore) { $scope.initialized = false; // used to animate the UI $scope.user = Client.getUserInfo(); $scope.installedApps = Client.getInstalledApps(); $scope.config = {}; $scope.status = {}; $scope.client = Client; $scope.appstoreConfig = {}; $scope.subscription = {}; $scope.notifications = []; $scope.ready = false; $scope.hideNavBarActions = $location.path() === '/logs'; $scope.isActive = function (url) { if (!$route.current) return false; return $route.current.$$route.originalPath.indexOf(url) === 0; }; $scope.logout = function (event) { event.stopPropagation(); $scope.initialized = false; Client.logout(); }; $scope.error = function (error) { console.error(error); window.location.href = '/error.html'; }; $scope.waitingForPlanSelection = false; $('#setupSubscriptionModal').on('hide.bs.modal', function () { $scope.waitingForPlanSelection = false; // check for updates to stay in sync Client.checkForUpdates(function (error) { if (error) return console.error(error); Client.refreshConfig(); }); }); $scope.waitForPlanSelection = function () { if ($scope.waitingForPlanSelection) return; $scope.waitingForPlanSelection = true; function checkPlan() { if (!$scope.waitingForPlanSelection) return; AppStore.getSubscription($scope.appstoreConfig, function (error, result) { if (error) return console.error(error); // check again to give more immediate feedback once a subscription was setup if (result.plan.id === 'free') { $timeout(checkPlan, 5000); } else { $scope.waitingForPlanSelection = false; $('#setupSubscriptionModal').modal('hide'); if ($scope.config.update && $scope.config.update.box) $('#updateModal').modal('show'); } }); } checkPlan(); }; $scope.showSubscriptionModal = function () { $('#setupSubscriptionModal').modal('show'); }; function refreshNotifications() { Client.getNotifications(false, 1, 20, function (error, results) { $timeout(refreshNotifications, 10000); if (error) return console.error(error); var newNotifications = results.filter(function (a) { return !$scope.notifications.find(function (b) { return a.id === b.id; }); }); newNotifications.forEach(function (n) { $scope.notifications.push(n); Client.notify(n.title, n.message, false, 'info', '/#/notifications'); }); }); } function runConfigurationChecks() { if ($scope.config.update && $scope.config.update.box) { Client.notify('Update Available', 'Update now to version ' + $scope.config.update.box.version + '.', true, 'success', '/#/settings'); } Client.getBackupConfig(function (error, backupConfig) { if (error) return console.error(error); if (backupConfig.provider === 'noop') { Client.notify('Backup Configuration', 'Cloudron backups are disabled. Please ensure this server is backed up using alternate means.', false, 'info', '/#/backups'); } else if (backupConfig.provider === 'filesystem' && !backupConfig.externalDisk) { Client.notify('Backup Configuration', 'Cloudron backups are currently on the same disk as the Cloudron server instance. This is dangerous and can lead to complete data loss if the disk fails.', false /* persistent */, 'info', '/#/backups'); } }); Client.isRebootRequired(function (error, isRequired) { if (error) return console.error(error); if (!isRequired) return; Client.notify('Reboot Required', 'To finish security updates, a reboot is necessary.', true /* persistent */, 'warning', '/#/system'); }); refreshNotifications(); } $scope.fetchAppstoreProfileAndSubscription = function (callback) { Client.getAppstoreConfig(function (error, appstoreConfig) { if (error) return callback(error); if (!appstoreConfig.token) return callback(); AppStore.getProfile(appstoreConfig.token, function (error, result) { if (error) return callback(error); // assign late to avoid UI flicketing on update appstoreConfig.profile = result; $scope.appstoreConfig = appstoreConfig; AppStore.getSubscription($scope.appstoreConfig, function (error, result) { if (error) return callback(error); $scope.subscription = result; callback(); }); }); }); }; // update state of acknowledged notification $scope.notificationAcknowledged = function (notificationId) { // remove notification from list $scope.notifications = $scope.notifications.filter(function (n) { return n.id !== notificationId; }); }; Client.getStatus(function (error, status) { if (error) return $scope.error(error); // WARNING if anything about the routing is changed here test these use-cases: // // 1. Caas // 3. selfhosted restore // 4. local development with gulp develop if (!status.activated) { console.log('Not activated yet, redirecting', status); if (status.restore.active || status.restore.errorMessage) { // show the error message in restore page window.location.href = '/restore.html'; } else { window.location.href = status.adminFqdn ? '/setup.html' : '/setupdns.html'; } return; } // support local development with localhost check if (window.location.hostname !== status.adminFqdn && window.location.hostname !== 'localhost') { // user is accessing by IP or by the old admin location (pre-migration) window.location.href = '/setupdns.html'; return; } $scope.status = status; // check version and force reload if needed if (!localStorage.version) { localStorage.version = status.version; } else if (localStorage.version !== status.version) { localStorage.version = status.version; window.location.reload(true); } console.log('Running dashboard version ', localStorage.version); // get user profile as the first thing. this populates the "scope" and affects subsequent API calls Client.refreshUserInfo(function (error) { if (error) return $scope.error(error); Client.refreshConfig(function (error) { if (error) return $scope.error(error); Client.refreshInstalledApps(function (error) { if (error) return $scope.error(error); // now mark the Client to be ready Client.setReady(); $scope.config = Client.getConfig(); $scope.initialized = true; if (!$scope.config.managed) { runConfigurationChecks(); $scope.fetchAppstoreProfileAndSubscription(function (error) { if (error) console.error(error); $scope.ready = true; }); } }); }); }); }); Client.onConfig(function (config) { if (config.cloudronName) { document.title = config.cloudronName; } }); // setup all the dialog focus handling ['updateModal'].forEach(function (id) { $('#' + id).on('shown.bs.modal', function () { $(this).find("[autofocus]:first").focus(); }); }); }]);