diff --git a/Makefile b/Makefile
index 37018d1f..500418bf 100644
--- a/Makefile
+++ b/Makefile
@@ -6,10 +6,12 @@ sync: up
# set up the database tablea
docker-compose exec cartoview python manage.py migrate
docker-compose exec cartoview python manage.py loaddata sample_admin.json
- docker-compose exec cartoview python manage.py loaddata default_oauth_apps.json
+ docker-compose exec cartoview python manage.py loaddata default_oauth_apps_docker.json
docker-compose exec cartoview python manage.py loaddata app_stores.json
docker-compose exec cartoview python manage.py loaddata initial_data.json
+backfill_api_keys:
+ docker-compose exec cartoview python manage.py backfill_api_keys
prepare_manager: up
#make migration for app_manager
@@ -34,7 +36,12 @@ reset: down up wait sync
collect_static: up
docker-compose exec cartoview python manage.py collectstatic --noinput
-run: up wait prepare_manager sync collect_static
+
+prepare_oauth:
+ docker-compose exec cartoview paver prepare_docker_oauth_fixture
+ docker-compose exec cartoview paver install_docker_data_dir
+
+run: up wait prepare_oauth prepare_manager sync collect_static backfill_api_keys
static_db: up sync wait collect_static
diff --git a/cartoview/app_manager/installer.py b/cartoview/app_manager/installer.py
index 106e4c1e..7f7cfaf8 100644
--- a/cartoview/app_manager/installer.py
+++ b/cartoview/app_manager/installer.py
@@ -71,13 +71,16 @@ def restart_server(cls):
def cherry_restart(cls):
try:
import cherrypy
- cherrypy.engine.restart()
+ # completely stop the cherrypy server instead of reloading
+ # to avoid waiting to stop used threads error
+ cherrypy.engine.stop()
+ cherrypy.engine.start()
except ImportError:
exit(0)
def remove_unwanted(info):
- dictionary = info.__dict__.get('_data', {})
+ dictionary = info.__dict__.get('_data', {}) if info else {}
app_fields = [
str(field.name)
for field in sorted(App._meta.fields + App._meta.many_to_many)
@@ -139,7 +142,7 @@ def get_store(self, store_id=None):
def get_app_version(self):
if not self.version or self.version == 'latest' or \
- self.info.latest_version.version == self.version:
+ (self.info and self.info.latest_version.version == self.version):
self.version = self.info.latest_version
else:
data = self._request_rest_data("appversion/?app__name=", self.name,
diff --git a/cartoview/app_manager/rest.py b/cartoview/app_manager/rest.py
index 3b1ce3de..8fbf07de 100644
--- a/cartoview/app_manager/rest.py
+++ b/cartoview/app_manager/rest.py
@@ -97,6 +97,7 @@ class AppResource(ModelResource):
store = fields.ForeignKey(AppStoreResource, 'store', full=False, null=True)
order = fields.IntegerField()
active = fields.BooleanField()
+ pending = fields.BooleanField()
categories = fields.ListField()
default_config = fields.DictField(default={})
@@ -119,6 +120,11 @@ def dehydrate_active(self, bundle):
active = bundle.obj.config.active
return active
+ def dehydrate_pending(self, bundle):
+ app = bundle.obj
+ cartoview_app = CartoviewApp.objects.get(app.name)
+ return cartoview_app.pending
+
def dehydrate_categories(self, bundle):
return [category.name for category in bundle.obj.category.all()]
diff --git a/cartoview/app_manager/settings.py b/cartoview/app_manager/settings.py
index 5f1a21fc..ec34d793 100644
--- a/cartoview/app_manager/settings.py
+++ b/cartoview/app_manager/settings.py
@@ -48,10 +48,10 @@ def load_apps(APPS_DIR):
APPS_SETTINGS += (app_settings_file,)
if os.path.exists(libs_dir) and libs_dir not in sys.path:
logger.info(
- "Install {} libs folder to the system.\n".format(
+ "Append {} libs folder to the system path.\n".format(
app.name))
sys.path.append(libs_dir)
- logger.info("add {} to INSTALLED_APPS.\n".format(app.name))
+ logger.info("add {} to django INSTALLED_APPS.\n".format(app.name))
if app.name not in CARTOVIEW_APPS:
# app_config.name.__str__() because Django don't like
# unicode_literals
diff --git a/cartoview/app_manager/static/app_manager/css/manager.css b/cartoview/app_manager/static/app_manager/css/manager.css
index 4b0a63d2..c206f44c 100644
--- a/cartoview/app_manager/static/app_manager/css/manager.css
+++ b/cartoview/app_manager/static/app_manager/css/manager.css
@@ -625,6 +625,7 @@ div {
.actions-wrapper {
margin-top: 10px;
padding: 0 10px;
+ min-height: 30px;
}
.actions-wrapper button {
margin-right: 10px;
diff --git a/cartoview/app_manager/static/app_manager/js/manager.js b/cartoview/app_manager/static/app_manager/js/manager.js
index 5af87a78..c0919c83 100644
--- a/cartoview/app_manager/static/app_manager/js/manager.js
+++ b/cartoview/app_manager/static/app_manager/js/manager.js
@@ -1,498 +1,543 @@
(function () {
- var app = angular.module('cartoview.appManager.manager', ["cartoview.appManager.resources", 'ui.bootstrap', "dndLists"]);
+ var app = angular.module("cartoview.appManager.manager", [
+ "cartoview.appManager.resources",
+ "ui.bootstrap",
+ "dndLists",
+ ]);
- app.config(function ($httpProvider) {
- $httpProvider.defaults.xsrfCookieName = 'csrftoken';
- $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
- });
- app.directive('dynamicTemplate', function ($compile) {
- return {
- restrict: 'A',
- scope: {
- context: '=',
- template: '='
- },
- controller: function ($scope, $element, $compile) {
- $scope.$watch(function () {
- return $scope.context;
- }, function () {
- if ($scope.context) {
- $element.html($scope.template);
- angular.extend($scope, $scope.context);
- $compile($element.contents())($scope);
- }
- });
+ app.config(function ($httpProvider) {
+ $httpProvider.defaults.xsrfCookieName = "csrftoken";
+ $httpProvider.defaults.xsrfHeaderName = "X-CSRFToken";
+ });
+ app.directive("dynamicTemplate", function ($compile) {
+ return {
+ restrict: "A",
+ scope: {
+ context: "=",
+ template: "=",
+ },
+ controller: function ($scope, $element, $compile) {
+ $scope.$watch(
+ function () {
+ return $scope.context;
+ },
+ function () {
+ if ($scope.context) {
+ $element.html($scope.template);
+ angular.extend($scope, $scope.context);
+ $compile($element.contents())($scope);
}
- }
- });
+ }
+ );
+ },
+ };
+ });
- app.directive('appsReorder', function ($compile) {
- return {
- restrict: 'E',
- templateUrl: "apps-reorder.html",
- scope: {
- installedApps: "="
- }
- }
- });
- app.service("Dialogs", function ($uibModal, $log, $document) {
- this.confirm = function (options) {
+ app.directive("appsReorder", function ($compile) {
+ return {
+ restrict: "E",
+ templateUrl: "apps-reorder.html",
+ scope: {
+ installedApps: "=",
+ },
+ };
+ });
+ app.service("Dialogs", function ($uibModal, $log, $document) {
+ this.confirm = function (options) {
+ var controller = function ($scope, $uibModalInstance) {
+ options.template = options.template || "{{msg}}";
+ $scope.options = options;
+ options.okText = options.okText || "Ok";
+ $scope.ok = function () {
+ $uibModalInstance.close(true);
+ };
+ $scope.cancel = function () {
+ $uibModalInstance.dismiss("cancel");
+ };
+ };
+ var modalInstance = $uibModal.open({
+ animation: true,
+ templateUrl: "confirm-dialog.html",
+ controller: controller,
+ });
- var controller = function ($scope, $uibModalInstance) {
- options.template = options.template || "{{msg}}";
- $scope.options = options;
- options.okText = options.okText || "Ok";
- $scope.ok = function () {
- $uibModalInstance.close(true);
- };
- $scope.cancel = function () {
- $uibModalInstance.dismiss('cancel');
- };
- };
- var modalInstance = $uibModal.open({
- animation: true,
- templateUrl: 'confirm-dialog.html',
- controller: controller
+ return modalInstance.result;
+ };
+ });
+ app.service("Alerts", function () {
+ var service = this;
+ this.alerts = [];
+ this.addAlert = function (alert) {
+ service.alerts.push(alert);
+ };
+
+ this.closeAlert = function (index) {
+ service.alerts.splice(index, 1);
+ };
+ this.closeAll = function () {
+ service.alerts = [];
+ };
+ });
+ app.service("AppInstaller", function ($http, urls) {
+ var service = this;
+ // get the apps required to install this app
+ var _getDependencies = function (app, appsHash, dependencies) {
+ angular.forEach(app.latest_version.dependencies, function (
+ version,
+ name
+ ) {
+ if (appsHash[name] && appsHash[name].installedApp) {
+ if (appsHash[name].installedApp.version < version) {
+ dependencies.push({
+ name: name,
+ version: version,
+ upgrade: true,
});
+ _getDependencies(appsHash[name], appsHash, dependencies);
+ }
+ } else {
+ dependencies.push({
+ name: name,
+ version: version,
+ upgrade: false,
+ });
+ _getDependencies(appsHash[name], appsHash, dependencies);
+ }
+ });
+ return dependencies;
+ };
+ this.getDependencies = function (app, appsHash) {
+ return _getDependencies(app, appsHash, []);
+ };
- return modalInstance.result;
+ var _getDependents = function (app, appsHash, dependents) {
+ angular.forEach(app.store.installedApps.objects, function (installedApp) {
+ var currentApp = appsHash[installedApp.name];
+ // NOTE:this line will raise an error while uninstalling app
+ // It was working fine before this commit in gitlab f976590bd981b05f062f055f1aed3040b190f8e9
+ // I this our app market result for apps was changed without handle this change here
+ if (currentApp) {
+ if (
+ dependents.indexOf(currentApp) == -1 &&
+ currentApp.latest_version.dependencies[app.name]
+ ) {
+ dependents.push(currentApp);
+ _getDependents(currentApp, appsHash, dependents);
+ }
+ }
+ });
+ return dependents;
+ };
+ // get the apps that depend on this app.
+ // must be called before app uninstall
+ this.getDependents = function (app, appsHash) {
+ return _getDependents(app, appsHash, [app]);
+ };
+ this.install = function (app) {
+ var url = urls.BULK_INSTALL;
+ const data = {
+ apps: [
+ {
+ app_name: app.name,
+ version: app.latest_version.version,
+ store_id: app.store.id,
+ },
+ ],
+ restart: false,
+ };
+ return $http.post(url, data);
+ };
+ this.uninstall = function (app) {
+ var url = "../uninstall/" + app.store.id + "/" + app.name + "/";
+ return $http.post(url);
+ };
+ this.restart = function () {
+ var url = urls.RESTART_SERVER;
+ return $http.get(url);
+ };
+ this.pingServer = function () {
+ var url = "/";
+ return $http.get(url);
+ };
+ });
+ app.directive("alertsPanel", function () {
+ return {
+ restrict: "E",
+ transclude: true,
+ replace: true,
+ scope: {
+ messages: "=",
+ },
+ template: [
+ "
",
+ "
",
+ "{{msg.msg}}",
+ "
",
+ "
",
+ ].join(""),
+ controller: function ($scope) {
+ var classes = {
+ error: "alert-danger",
};
- });
- app.service("Alerts", function () {
- var service = this;
- this.alerts = [];
- this.addAlert = function (alert) {
- service.alerts.push(alert);
+ $scope.getCls = function (type) {
+ return "alert " + (classes[type] || "alert-warning");
};
+ },
+ };
+ });
+ app.directive("cartoviewAppInstaller", function () {
+ return {
+ restrict: "E",
+ transclude: true,
+ replace: true,
+ templateUrl: "app-installer.html",
+ controller: function (
+ $scope,
+ InstalledAppResource,
+ AppStoreResource,
+ AppStore,
+ AppInstaller,
+ Dialogs,
+ $timeout,
+ Alerts
+ ) {
+ $scope.selectedStoreId = null;
+ var appsHash = {};
+ $scope.loading = true;
+ $scope.appsErrors = [];
+ $scope.storeError = false;
+ $scope.busy = false;
+ $scope.compatible = function (cartoviewVersions) {
+ var compatible = false;
+ for (var i = 0; i < cartoviewVersions.length; i++) {
+ const version = cartoviewVersions[i].version;
+ const current_version_check = compareVersions(
+ version,
+ versionInfo.current_version
+ );
+ var backward_version_check = -1;
+ for (var j = 0; j < versionInfo.backward_versions.length; j++) {
+ const v = versionInfo.backward_versions[j];
- this.closeAlert = function (index) {
- service.alerts.splice(index, 1);
+ if (compareVersions(version, v) == 0) {
+ backward_version_check = 0;
+ break;
+ }
+ }
+ if (current_version_check === 0 || backward_version_check === 0) {
+ compatible = true;
+ break;
+ }
+ }
+ return compatible;
};
- this.closeAll = function () {
- service.alerts = [];
- }
- });
- app.service("AppInstaller", function ($http, urls) {
- var service = this;
- // get the apps required to install this app
- var _getDependencies = function (app, appsHash, dependencies) {
-
- angular.forEach(app.latest_version.dependencies, function (version, name) {
- if (appsHash[name] && appsHash[name].installedApp) {
-
- if (appsHash[name].installedApp.version < version) {
- dependencies.push({
- name: name,
- version: version,
- upgrade: true
- });
- _getDependencies(appsHash[name], appsHash, dependencies);
+ $scope.upgradable = function (currentVersion, storeVersion) {
+ var compatible = false;
+ if (compareVersions(currentVersion, storeVersion) === -1) {
+ compatible = true;
+ }
+ return compatible;
+ };
+ $scope.stores = AppStoreResource.query(function () {
+ $scope.stores.objects.forEach(function (store) {
+ if ($scope.stores.objects.length > 0) {
+ $scope.selectedStoreId = $scope.stores.objects[0].id;
+ }
+ store.update = function (callback, persist) {
+ var params = {
+ store_id: store.id,
+ t: new Date().getTime(), //to force server request
+ };
+ store.installedApps = InstalledAppResource.query(
+ params,
+ function () {
+ if (store._apps && store._apps.objects) {
+ store._apps.objects.forEach(function (app) {
+ delete app.installedApp;
+ });
+ }
+ store.installedApps.objects.forEach(function (installedApp) {
+ if (appsHash[installedApp.name]) {
+ appsHash[installedApp.name].installedApp = installedApp;
}
- } else {
- dependencies.push({
- name: name,
- version: version,
- upgrade: false
+ });
+ if (typeof callback == "function") {
+ callback();
+ }
+ },
+ function () {
+ //keep requesting until server responds
+ if (persist) {
+ $timeout(function () {
+ store.update(callback, persist);
+ }, 2000);
+ }
+ }
+ );
+ $scope.loading = false;
+ };
+ Object.defineProperty(store, "apps", {
+ configurable: true,
+ get: function () {
+ if (!this._apps) {
+ this._apps = AppStore.AppResource(this).query(function () {
+ store._apps.objects.forEach(function (app) {
+ appsHash[app.name] = app;
+ app.store = store;
});
- _getDependencies(appsHash[name], appsHash, dependencies);
+ store.update();
+ });
+ this._apps.$promise.catch(function (errorResponse) {
+ // console.error(errorResponse);
+ $scope.loading = false;
+ $scope.storeError = true;
+ });
}
+ return this._apps;
+ },
});
- return dependencies;
+ });
+ });
+ $scope.getSelectedStore = function () {
+ var selected;
+ if ($scope.selectedStoreId) {
+ $scope.stores.objects.forEach(function (store) {
+ if (store.id == $scope.selectedStoreId) {
+ selected = store;
+ return false;
+ }
+ });
+ }
+ return selected;
};
- this.getDependencies = function (app, appsHash) {
- return _getDependencies(app, appsHash, [])
+ //
+ var updateStore = function (store) {
+ $scope.restarting = true;
+ //wait for 5 seconds to insure that the server starts the restarting process
+ $timeout(function () {
+ store.update(function () {
+ $scope.restarting = false;
+ $scope.installing = null;
+ }, true);
+ }, 5000);
};
- var _getDependents = function (app, appsHash, dependents) {
- angular.forEach(app.store.installedApps.objects, function (installedApp) {
- var currentApp = appsHash[installedApp.name];
- // NOTE:this line will raise an error while uninstalling app
- // It was working fine before this commit in gitlab f976590bd981b05f062f055f1aed3040b190f8e9
- // I this our app market result for apps was changed without handle this change here
- if (dependents.indexOf(currentApp) == -1 && currentApp.latest_version.dependencies[app.name]) {
- dependents.push(currentApp)
- _getDependents(currentApp, appsHash, dependents)
+ function install(requiredApp) {
+ $scope.installing = requiredApp;
+ $scope.appsErrors = [];
+ AppInstaller.install(requiredApp)
+ .success(function (res) {
+ res.forEach(function (appResult) {
+ if (appResult.success) {
+ // updateStore(requiredApp.store);
+ // Just update the store without waiting for the server to restart
+ requiredApp.store.update(undefined, true);
+ $scope.installing = null;
+ } else {
+ const msgData = {
+ type: appResult.success ? "success" : "danger",
+ msg: appResult.app_name + ": " + appResult.message,
+ };
+ $scope.appsErrors.push(msgData);
}
+ }, this);
+ })
+ .error(function (res, status) {
+ $scope.installing = null;
+ if (status == -1) {
+ var error = "Cannot connect to the server";
+ app.messages.push({
+ type: "danger",
+ msg: error,
+ });
+ } else if (status >= 400) {
+ var error = "Cannot install app " + app.title;
+ app.messages.push({
+ type: "danger",
+ msg: error,
+ });
+ }
+ if (Array.isArray(res)) {
+ res.forEach(function (message) {
+ const msgData = {
+ type: message.success ? "success" : "danger",
+ msg: message.app_name + ": " + message.message,
+ };
+ $scope.appsErrors.push(msgData);
+ }, this);
+ }
+ if (res.error_message) {
+ const msgData = {
+ type: "danger",
+ msg: res.error_message,
+ };
+ $scope.appsErrors.push(msgData);
+ }
+ console.log($scope.appsErrors);
});
- return dependents;
- };
- // get the apps that depend on this app.
- // must be called before app uninstall
- this.getDependents = function (app, appsHash) {
- return _getDependents(app, appsHash, [app]);
+ }
+ $scope.install = function (app, upgrade) {
+ var dependencies = AppInstaller.getDependencies(app, appsHash);
+ if (dependencies.length > 0) {
+ Dialogs.confirm({
+ title: "App dependencies",
+ template: [
+ "This app requires the following apps to be installed
",
+ "- ",
+ "{{appsHash[d.name].title}} ",
+ "v{{d.version}}",
+ "(v{{appsHash[d.name].installedApp.version}} is installed)",
+ "
",
+ "Install Them?
",
+ ].join(""),
+ dependencies: dependencies,
+ appsHash: appsHash,
+ }).then(function (confirm) {
+ if (confirm) {
+ install(app);
+ }
+ });
+ } else {
+ install(app);
+ }
};
- this.install = function (app) {
- var url = urls.BULK_INSTALL;
- const data = {
- apps: [{
- app_name: app.name,
- version: app.latest_version.version,
- store_id: app.store.id
- }],
- restart: false,
- }
- return $http.post(url, data);
+ var uninstall = function (app) {
+ $scope.installing = app;
+ AppInstaller.uninstall(app)
+ .success(function (res) {
+ // updateStore(app.store);
+ // just update the store without waiting for the server to restart
+ app.store.update(undefined, true);
+ $scope.installing = null;
+ })
+ .error(function () {
+ $scope.installing = null;
+ app.error = "Unable to uninstall";
+ });
};
- this.uninstall = function (app) {
- var url = "../uninstall/" + app.store.id + "/" + app.name + "/";
- return $http.post(url);
- }
- this.restart = function () {
- var url = urls.RESTART_SERVER;
- return $http.get(url);
- }
- this.pingServer = function () {
- var url = '/';
- return $http.get(url);
- }
- });
- app.directive("alertsPanel", function () {
- return {
- restrict: 'E',
- transclude: true,
- replace: true,
- scope: {
- messages: '='
+
+ var setActive = function (app, active) {
+ var action = active ? "activate" : "suspend";
+ InstalledAppResource[action](
+ {
+ appId: app.installedApp.id,
},
- template: ["",
- "
",
- "{{msg.msg}}",
- "
",
- "
"
- ].join(""),
- controller: function ($scope) {
- var classes = {
- error: "alert-danger"
- };
- $scope.getCls = function (type) {
- return "alert " + (classes[type] || "alert-warning");
- }
+ function (res) {
+ if (res.success) {
+ app.installedApp.active = active;
+ }
}
- }
- });
- app.directive("cartoviewAppInstaller", function () {
- return {
- restrict: 'E',
- transclude: true,
- replace: true,
- templateUrl: "app-installer.html",
- controller: function ($scope, InstalledAppResource, AppStoreResource, AppStore,
- AppInstaller, Dialogs, $timeout, Alerts) {
- $scope.selectedStoreId = null;
- var appsHash = {};
- $scope.loading = true;
- $scope.appsErrors = [];
- $scope.storeError = false;
- $scope.busy = false;
- $scope.compatible = function (cartoviewVersions) {
- var compatible = false;
- for (var i = 0; i < cartoviewVersions.length; i++) {
- const version = cartoviewVersions[i].version
- const current_version_check = compareVersions(version, versionInfo.current_version)
- var backward_version_check = -1
- for (var j = 0; j < versionInfo.backward_versions.length; j++) {
- const v = versionInfo.backward_versions[j]
-
- if (compareVersions(version, v) == 0) {
- backward_version_check = 0
- break
- }
- }
- if (current_version_check === 0 || backward_version_check === 0) {
- compatible = true;
- break;
- }
- }
- return compatible
- }
- $scope.upgradable = function (currentVersion, storeVersion) {
- var compatible = false
- if (compareVersions(currentVersion, storeVersion) === -1) {
- compatible = true
- }
- return compatible
- }
- $scope.stores = AppStoreResource.query(function () {
- $scope.stores.objects.forEach(function (store) {
- if ($scope.stores.objects.length > 0) {
- $scope.selectedStoreId = $scope.stores.objects[0].id;
- }
- store.update = function (callback, persist) {
- var params = {
- store_id: store.id,
- t: new Date().getTime() //to force server request
- };
- store.installedApps = InstalledAppResource.query(params, function () {
- if (store._apps && store._apps.objects) {
- store._apps.objects.forEach(function (app) {
- delete app.installedApp;
- });
- }
- store.installedApps.objects.forEach(function (installedApp) {
- if (appsHash[installedApp.name]) {
- appsHash[installedApp.name].installedApp = installedApp;
- }
-
- });
- if (typeof callback == 'function') {
- callback();
- }
- }, function () {
- //keep requesting until server responds
- if (persist) {
- $timeout(function () {
- store.update(callback, persist)
- }, 2000);
- }
- });
- $scope.loading = false
- };
- Object.defineProperty(store, 'apps', {
- configurable: true,
- get: function () {
- if (!this._apps) {
- this._apps = AppStore.AppResource(this).query(function () {
- store._apps.objects.forEach(function (app) {
- appsHash[app.name] = app;
- app.store = store;
-
- });
- store.update()
- })
- this._apps.$promise.catch(function (errorResponse) {
- // console.error(errorResponse);
- $scope.loading = false;
- $scope.storeError = true
- });
-
- }
- return this._apps;
- }
- });
- });
- });
- $scope.getSelectedStore = function () {
- var selected;
- if ($scope.selectedStoreId) {
- $scope.stores.objects.forEach(function (store) {
- if (store.id == $scope.selectedStoreId) {
- selected = store;
- return false;
- }
- });
- }
- return selected;
- };
- //
- var updateStore = function (store) {
- $scope.restarting = true;
- //wait for 5 seconds to insure that the server starts the restarting process
- $timeout(function () {
- store.update(function () {
- $scope.restarting = false;
- $scope.installing = null;
- }, true);
- }, 5000);
- };
-
- function install(requiredApp) {
- $scope.installing = requiredApp;
- $scope.appsErrors = [];
- AppInstaller.install(requiredApp).success(function (res) {
- res.forEach(function (appResult) {
- if (appResult.success) {
- updateStore(requiredApp.store);
- } else {
- const msgData = {
- type: appResult.success ? "success" : "danger",
- msg: appResult.app_name + ": " + appResult.message
- }
- $scope.appsErrors.push(msgData)
- }
- }, this)
- }).error(function (res, status) {
- $scope.installing = null;
- if (status == -1) {
- var error = "Cannot connect to the server"
- app.messages.push({
- type: "danger",
- msg: error
- });
- } else if (status >= 400) {
- var error = "Cannot install app " + app.title;
- app.messages.push({
- type: "danger",
- msg: error
- });
- }
-
- if (Array.isArray(res)) {
- res.forEach(function (message) {
- const msgData = {
- type: message.success ? "success" : "danger",
- msg: message.app_name + ": " + message.message
- }
- $scope.appsErrors.push(msgData)
- }, this)
- }
- if (res.error_message) {
- const msgData = {
- type: "danger",
- msg: res.error_message
- }
- $scope.appsErrors.push(msgData)
- }
- console.log($scope.appsErrors);
-
- });
- }
- $scope.install = function (app, upgrade) {
- var dependencies = AppInstaller.getDependencies(app, appsHash);
- if (dependencies.length > 0) {
- Dialogs.confirm({
- title: "App dependencies",
- template: [
- "This app requires the following apps to be installed
",
- "- ",
- "{{appsHash[d.name].title}} ",
- "v{{d.version}}",
- "(v{{appsHash[d.name].installedApp.version}} is installed)",
- "
",
- "Install Them?
"
- ].join(""),
- dependencies: dependencies,
- appsHash: appsHash
- }).then(function (confirm) {
- if (confirm) {
- install(app);
- }
- })
- } else {
- install(app);
- }
- };
-
- var uninstall = function (app) {
- $scope.installing = app;
- AppInstaller.uninstall(app).success(function (res) {
- updateStore(app.store);
- }).error(function () {
- $scope.installing = null;
- app.error = "Unable to uninstall"
-
- });
- };
-
- var setActive = function (app, active) {
- var action = active ? 'activate' : 'suspend';
- InstalledAppResource[action]({
- appId: app.installedApp.id
- }, function (res) {
- if (res.success) {
- app.installedApp.active = active;
- }
- });
- };
- $scope.toggleActive = function (app) {
- setActive(app, !app.installedApp.active);
- };
-
- $scope.uninstall = function (app) {
-
- var dependents = AppInstaller.getDependents(app, appsHash);
- if (dependents.length > 0) {
- Dialogs.confirm({
- title: "Uninstall app",
- template: [
- "This will uninstall the following apps",
- "- ",
- "{{appsHash[d.name].title}} ",
- "v{{appsHash[d.name].installedApp.version}}",
-
- "
",
- "Do you want to proceed?
"
- ].join(""),
- dependents: dependents,
- appsHash: appsHash
- }).then(function (confirm) {
- if (confirm) {
- uninstall(app);
- }
- })
- } else {
- uninstall(app)
- }
- };
+ );
+ };
+ $scope.toggleActive = function (app) {
+ setActive(app, !app.installedApp.active);
+ };
- $scope.reorder = function () {
- var installedApps = $scope.getSelectedStore().installedApps.objects;
- Dialogs.confirm({
- okText: "Save Order",
- title: "Reorder Installed Apps",
- template: "",
- installedApps: installedApps
- }).then(function (confirm) {
- if (confirm) {
- var apps = [];
- installedApps.forEach(function (app) {
- apps.push(app.id);
- });
- var params = {
- apps: apps
- };
- InstalledAppResource.reorder(params, function (res) {
- console.debug(res)
- })
- }
- });
+ $scope.uninstall = function (app) {
+ var dependents = AppInstaller.getDependents(app, appsHash);
+ if (dependents.length > 0) {
+ Dialogs.confirm({
+ title: "Uninstall app",
+ template: [
+ "This will uninstall the following apps",
+ "- ",
+ "{{appsHash[d.name].title}} ",
+ "v{{appsHash[d.name].installedApp.version}}",
- }
- $scope.restart = function () {
- $scope.appsErrors = []
- $scope.restarting = true;
- var restarted = false
- AppInstaller.restart().error(function (res, status) {
- if (status == 500) {
- $scope.restarting = false;
- const msgData = {
- type: "danger",
- msg: "Failed to restart Server"
- }
- $scope.appsErrors.push(msgData)
- restarted = true
- }
- });
+ "
",
+ "Do you want to proceed?
",
+ ].join(""),
+ dependents: dependents,
+ appsHash: appsHash,
+ }).then(function (confirm) {
+ if (confirm) {
+ uninstall(app);
+ }
+ });
+ } else {
+ uninstall(app);
+ }
+ };
- function waitForRestart() {
- AppInstaller.pingServer().success(function (res) {
- restarted = true
- $scope.restarting = false;
- }).error(function (res, status) {
- if (status == 500) {
- $scope.restarting = false;
- const msgData = {
- type: "danger",
- msg: "Failed to restart Server"
- }
- $scope.appsErrors.push(msgData)
- restarted = true
- }
- });
- if (!restarted) {
- $timeout(function () {
- waitForRestart()
- }, 3000);
- }
- }
- $timeout(function () {
- waitForRestart()
- }, 2000);
+ $scope.reorder = function () {
+ var installedApps = $scope.getSelectedStore().installedApps.objects;
+ Dialogs.confirm({
+ okText: "Save Order",
+ title: "Reorder Installed Apps",
+ template:
+ "",
+ installedApps: installedApps,
+ }).then(function (confirm) {
+ if (confirm) {
+ var apps = [];
+ installedApps.forEach(function (app) {
+ apps.push(app.id);
+ });
+ var params = {
+ apps: apps,
+ };
+ InstalledAppResource.reorder(params, function (res) {
+ console.debug(res);
+ });
+ }
+ });
+ };
+ $scope.restart = function () {
+ $scope.appsErrors = [];
+ $scope.restarting = true;
+ var restarted = false;
+ AppInstaller.restart().error(function (res, status) {
+ if (status == 500) {
+ $scope.restarting = false;
+ const msgData = {
+ type: "danger",
+ msg: "Failed to restart Server",
+ };
+ $scope.appsErrors.push(msgData);
+ restarted = true;
+ }
+ });
+ function waitForRestart() {
+ AppInstaller.pingServer()
+ .success(function (res) {
+ restarted = true;
+ $scope.restarting = false;
+ location.reload()
+ })
+ .error(function (res, status) {
+ if (status == 500) {
+ $scope.restarting = false;
+ const msgData = {
+ type: "danger",
+ msg: "Failed to restart Server",
+ };
+ $scope.appsErrors.push(msgData);
+ restarted = true;
}
+ });
+ if (!restarted) {
+ $timeout(function () {
+ waitForRestart();
+ }, 10000);
}
- }
- });
-})();
\ No newline at end of file
+ }
+ $timeout(function () {
+ waitForRestart();
+ }, 10000);
+ };
+ $scope.showRestartPanel = function () {
+ var installedApps = $scope.getSelectedStore().installedApps.objects;
+ if(installedApps)
+ return installedApps.findIndex(function (app) {
+ return app.pending
+ }) !== -1
+ return false
+ };
+ },
+ };
+ });
+})();
diff --git a/cartoview/app_manager/templates/app_manager/apps.html b/cartoview/app_manager/templates/app_manager/apps.html
index 8ddc2d37..57bf9799 100644
--- a/cartoview/app_manager/templates/app_manager/apps.html
+++ b/cartoview/app_manager/templates/app_manager/apps.html
@@ -46,7 +46,7 @@ {% trans "Explore Apps" %}
{% for app in Apps %}
- {% if app.config.active and app.name != "cartoview_attachment_manager" %}
+ {% if not app.config.pending and app.config.active and app.name != "cartoview_attachment_manager" %}
diff --git a/cartoview/app_manager/templates/app_manager/manage.html b/cartoview/app_manager/templates/app_manager/manage.html
index 933c7147..02e36f72 100644
--- a/cartoview/app_manager/templates/app_manager/manage.html
+++ b/cartoview/app_manager/templates/app_manager/manage.html
@@ -34,10 +34,23 @@
{% verbatim %}{{options.title}}{% endverbatim %}