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', ' + + ); + })} + + + + ) + } + + /* + * initialization + */ + + render() { + const isEditingExistingHook = Boolean(this.state.hookUid); + + if (this.state.isLoadingHook) { + return ( + + + + {t('loading...')} + + + ); + } else { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +