diff --git a/.eslintrc b/.eslintrc
index a09fe38bc0..f6ba717a45 100755
--- a/.eslintrc
+++ b/.eslintrc
@@ -10,12 +10,12 @@
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
- },
+ }
},
"rules": {
"strict": 0,
"curly": 0,
- "quotes": ["warn", "single"],
+ "quotes": ["warn", "single", {"avoidEscape": true}],
"no-underscore-dangle": 0,
"camelcase": [0],
"new-cap": 0,
diff --git a/dependencies/pip/dev_requirements.txt b/dependencies/pip/dev_requirements.txt
index 4cdac616c0..c7a90683f3 100644
--- a/dependencies/pip/dev_requirements.txt
+++ b/dependencies/pip/dev_requirements.txt
@@ -21,6 +21,7 @@ cookies==2.2.1 # via responses
cryptography==2.2.2 # via paramiko, pyopenssl
cssselect==1.0.3 # via pyquery
cyordereddict==1.0.0
+defusedxml==0.5.0 # via djangorestframework-xml
dj-database-url==0.4.2
dj-static==0.0.6
django-braces==1.11.0
@@ -44,6 +45,7 @@ django-taggit==0.22.0
django-toolbelt==0.0.1
django-webpack-loader==0.4.1
django==1.8.17
+djangorestframework-xml==1.3.0
djangorestframework==3.5.4
docutils==0.13.1 # via botocore, statistics
drf-extensions==0.3.1
diff --git a/dependencies/pip/external_services.txt b/dependencies/pip/external_services.txt
index 8cce303e54..f305b6a835 100644
--- a/dependencies/pip/external_services.txt
+++ b/dependencies/pip/external_services.txt
@@ -22,6 +22,7 @@ cookies==2.2.1 # via responses
cryptography==2.2.2 # via pyopenssl
cssselect==1.0.3 # via pyquery
cyordereddict==1.0.0
+defusedxml==0.5.0 # via djangorestframework-xml
dj-database-url==0.4.1
dj-static==0.0.6
django-braces==1.8.1
@@ -45,6 +46,7 @@ django-taggit==0.22.0
django-toolbelt==0.0.1
django-webpack-loader==0.3.0
django==1.8.13
+djangorestframework-xml==1.3.0
djangorestframework==3.3.3
docutils==0.12 # via botocore, statistics
drf-extensions==0.3.1
diff --git a/dependencies/pip/requirements.in b/dependencies/pip/requirements.in
index e47e23d16b..f66865a7b4 100644
--- a/dependencies/pip/requirements.in
+++ b/dependencies/pip/requirements.in
@@ -43,6 +43,7 @@ django-taggit
django-storages
django-private-storage
djangorestframework
+djangorestframework-xml
drf-extensions
gunicorn
jsonfield
diff --git a/dependencies/pip/requirements.txt b/dependencies/pip/requirements.txt
index 3d5b9804a0..7b5997acf1 100644
--- a/dependencies/pip/requirements.txt
+++ b/dependencies/pip/requirements.txt
@@ -21,6 +21,7 @@ cookies==2.2.1 # via responses
cryptography==2.2.2 # via pyopenssl
cssselect==1.0.3 # via pyquery
cyordereddict==1.0.0
+defusedxml==0.5.0 # via djangorestframework-xml
dj-database-url==0.4.1
dj-static==0.0.6
django-braces==1.8.1
@@ -44,6 +45,7 @@ django-taggit==0.22.0
django-toolbelt==0.0.1
django-webpack-loader==0.3.0
django==1.8.13
+djangorestframework-xml==1.3.0
djangorestframework==3.3.3
docutils==0.12 # via botocore, statistics
drf-extensions==0.3.1
diff --git a/jsapp/js/actions.es6 b/jsapp/js/actions.es6
index 570e0dce5a..462b40da6f 100644
--- a/jsapp/js/actions.es6
+++ b/jsapp/js/actions.es6
@@ -221,6 +221,16 @@ actions.permissions = Reflux.createActions({
},
});
+actions.hooks = Reflux.createActions({
+ getAll: {children: ['completed', 'failed']},
+ add: {children: ['completed', 'failed']},
+ update: {children: ['completed', 'failed']},
+ delete: {children: ['completed', 'failed']},
+ getLogs: {children: ['completed', 'failed']},
+ retryLog: {children: ['completed', 'failed']},
+ retryLogs: {children: ['completed', 'failed']},
+});
+
actions.misc = Reflux.createActions({
checkUsername: {
asyncResult: true,
@@ -695,4 +705,151 @@ actions.resources.updateSubmissionValidationStatus.listen(function(uid, sid, dat
});
});
+actions.hooks.getAll.listen((assetUid, callbacks = {}) => {
+ dataInterface.getHooks(assetUid)
+ .done((...args) => {
+ actions.hooks.getAll.completed(...args);
+ if (typeof callbacks.onComplete === 'function') {
+ callbacks.onComplete(...args);
+ }
+ })
+ .fail((...args) => {
+ actions.hooks.getAll.failed(...args);
+ if (typeof callbacks.onFail === 'function') {
+ callbacks.onFail(...args);
+ }
+ });
+});
+
+actions.hooks.add.listen((assetUid, data, callbacks = {}) => {
+ dataInterface.addExternalService(assetUid, data)
+ .done((...args) => {
+ actions.hooks.getAll(assetUid);
+ actions.hooks.add.completed(...args);
+ if (typeof callbacks.onComplete === 'function') {
+ callbacks.onComplete(...args);
+ }
+ })
+ .fail((...args) => {
+ actions.hooks.add.failed(...args);
+ if (typeof callbacks.onFail === 'function') {
+ callbacks.onFail(...args);
+ }
+ });
+});
+actions.hooks.add.completed.listen((response) => {
+ notify(t('REST Service added successfully'));
+});
+actions.hooks.add.failed.listen((response) => {
+ notify(t('Failed adding REST Service'), 'error');
+});
+
+actions.hooks.update.listen((assetUid, hookUid, data, callbacks = {}) => {
+ dataInterface.updateExternalService(assetUid, hookUid, data)
+ .done((...args) => {
+ actions.hooks.getAll(assetUid);
+ actions.hooks.update.completed(...args);
+ if (typeof callbacks.onComplete === 'function') {
+ callbacks.onComplete(...args);
+ }
+ })
+ .fail((...args) => {
+ actions.hooks.update.failed(...args);
+ if (typeof callbacks.onFail === 'function') {
+ callbacks.onFail(...args);
+ }
+ });
+});
+actions.hooks.update.completed.listen((response) => {
+ notify(t('REST Service updated successfully'));
+});
+actions.hooks.update.failed.listen((response) => {
+ notify(t('Failed saving REST Service'), 'error');
+});
+
+actions.hooks.delete.listen((assetUid, hookUid, callbacks = {}) => {
+ dataInterface.deleteExternalService(assetUid, hookUid)
+ .done((...args) => {
+ actions.hooks.getAll(assetUid);
+ actions.hooks.delete.completed(...args);
+ if (typeof callbacks.onComplete === 'function') {
+ callbacks.onComplete(...args);
+ }
+ })
+ .fail((...args) => {
+ actions.hooks.delete.failed(...args);
+ if (typeof callbacks.onFail === 'function') {
+ callbacks.onFail(...args);
+ }
+ });
+});
+actions.hooks.delete.completed.listen((response) => {
+ notify(t('REST Service deleted permanently'));
+});
+actions.hooks.delete.failed.listen((response) => {
+ notify(t('Could not delete REST Service'), 'error');
+});
+
+actions.hooks.getLogs.listen((assetUid, hookUid, callbacks = {}) => {
+ dataInterface.getHookLogs(assetUid, hookUid)
+ .done((...args) => {
+ actions.hooks.getLogs.completed(...args);
+ if (typeof callbacks.onComplete === 'function') {
+ callbacks.onComplete(...args);
+ }
+ })
+ .fail((...args) => {
+ actions.hooks.getLogs.failed(...args);
+ if (typeof callbacks.onFail === 'function') {
+ callbacks.onFail(...args);
+ }
+ });
+});
+
+actions.hooks.retryLog.listen((assetUid, hookUid, lid, callbacks = {}) => {
+ dataInterface.retryExternalServiceLog(assetUid, hookUid, lid)
+ .done((...args) => {
+ actions.hooks.getLogs(assetUid, hookUid);
+ actions.hooks.retryLog.completed(...args);
+ if (typeof callbacks.onComplete === 'function') {
+ callbacks.onComplete(...args);
+ }
+ })
+ .fail((...args) => {
+ actions.hooks.retryLog.failed(...args);
+ if (typeof callbacks.onFail === 'function') {
+ callbacks.onFail(...args);
+ }
+ });
+});
+actions.hooks.retryLog.completed.listen((response) => {
+ notify(t('Submission retried successfully'));
+});
+actions.hooks.retryLog.failed.listen((response) => {
+ notify(t('Retrying submission failed'), 'error');
+});
+
+actions.hooks.retryLogs.listen((assetUid, hookUid, callbacks = {}) => {
+ dataInterface.retryExternalServiceLogs(assetUid, hookUid)
+ .done((...args) => {
+ actions.hooks.retryLogs.completed(...args);
+ if (typeof callbacks.onComplete === 'function') {
+ callbacks.onComplete(...args);
+ }
+ })
+ .fail((...args) => {
+ actions.hooks.getLogs(assetUid, hookUid);
+ actions.hooks.retryLogs.failed(...args);
+ if (typeof callbacks.onFail === 'function') {
+ callbacks.onFail(...args);
+ }
+ });
+});
+actions.hooks.retryLogs.completed.listen((response) => {
+ notify(t(response.detail), 'warning');
+});
+actions.hooks.retryLogs.failed.listen((response) => {
+ notify(t('Retrying all submissions failed'), 'error');
+});
+
module.exports = actions;
diff --git a/jsapp/js/app.es6 b/jsapp/js/app.es6
index 422baddfc5..3777df3bb0 100644
--- a/jsapp/js/app.es6
+++ b/jsapp/js/app.es6
@@ -317,8 +317,11 @@ export var routes = (
-
+
+
+
+
{/* used to force refresh form screens */}
diff --git a/jsapp/js/bem.es6 b/jsapp/js/bem.es6
index 0943a9af22..5783cbc27c 100644
--- a/jsapp/js/bem.es6
+++ b/jsapp/js/bem.es6
@@ -11,6 +11,12 @@ bem.Loading = BEM('loading');
bem.Loading__inner = bem.Loading.__('inner');
bem.Loading__msg = bem.Loading.__('msg');
+bem.EmptyContent = BEM('empty-content', '');
+bem.EmptyContent__icon = bem.EmptyContent.__('icon', '');
+bem.EmptyContent__title = bem.EmptyContent.__('title', '');
+bem.EmptyContent__message = bem.EmptyContent.__('message', '
');
+bem.EmptyContent__button = bem.EmptyContent.__('button', '