diff --git a/awx/ui/client/legacy/styles/ansible-ui.less b/awx/ui/client/legacy/styles/ansible-ui.less
index 6349dfbd61..1717e2a7a6 100644
--- a/awx/ui/client/legacy/styles/ansible-ui.less
+++ b/awx/ui/client/legacy/styles/ansible-ui.less
@@ -1256,6 +1256,10 @@ input[type="checkbox"].checkbox-no-label {
color:@red;
}
+ .error-border {
+ border-color:@red;
+ }
+
.connecting-color {
color: @warning;
}
diff --git a/awx/ui/client/src/configuration/auth-form/configuration-auth.controller.js b/awx/ui/client/src/configuration/auth-form/configuration-auth.controller.js
index 66d2f8818d..75235a3984 100644
--- a/awx/ui/client/src/configuration/auth-form/configuration-auth.controller.js
+++ b/awx/ui/client/src/configuration/auth-form/configuration-auth.controller.js
@@ -110,6 +110,9 @@ export default [
authVm.activeAuthForm = getActiveAuthForm();
formTracker.setCurrentAuth(authVm.activeAuthForm);
$('#FormModal-dialog').dialog('close');
+ }).catch(() => {
+ event.preventDefault();
+ $('#FormModal-dialog').dialog('close');
});
},
"class": "btn btn-primary",
diff --git a/awx/ui/client/src/configuration/configuration.block.less b/awx/ui/client/src/configuration/configuration.block.less
index 8b10cf6f87..8d85b6bcea 100644
--- a/awx/ui/client/src/configuration/configuration.block.less
+++ b/awx/ui/client/src/configuration/configuration.block.less
@@ -186,3 +186,8 @@ input#filePickerText {
hr {
height: 1px;
}
+
+.ConfigureTower-errorIcon{
+ margin-right:5px;
+ color:@red;
+}
diff --git a/awx/ui/client/src/configuration/configuration.controller.js b/awx/ui/client/src/configuration/configuration.controller.js
index 0f65097f71..f34aecb70b 100644
--- a/awx/ui/client/src/configuration/configuration.controller.js
+++ b/awx/ui/client/src/configuration/configuration.controller.js
@@ -8,7 +8,7 @@ import defaultStrings from '~assets/default.strings.json';
export default [
'$scope', '$rootScope', '$state', '$stateParams', '$timeout', '$q', 'Alert',
'ConfigurationService', 'ConfigurationUtils', 'CreateDialog', 'CreateSelect2', 'i18n', 'ParseTypeChange', 'ProcessErrors', 'Store',
- 'Wait', 'configDataResolve', 'ToJSON', 'ConfigService',
+ 'Wait', 'configDataResolve', 'ToJSON', 'ConfigService', 'ngToast',
//Form definitions
'configurationAzureForm',
'configurationGithubForm',
@@ -32,7 +32,7 @@ export default [
function(
$scope, $rootScope, $state, $stateParams, $timeout, $q, Alert,
ConfigurationService, ConfigurationUtils, CreateDialog, CreateSelect2, i18n, ParseTypeChange, ProcessErrors, Store,
- Wait, configDataResolve, ToJSON, ConfigService,
+ Wait, configDataResolve, ToJSON, ConfigService, ngToast,
//Form definitions
configurationAzureForm,
configurationGithubForm,
@@ -241,10 +241,15 @@ export default [
}, {
label: i18n._("Save changes"),
onClick: function() {
- vm.formSave();
- $scope[formTracker.currentFormName()].$setPristine();
- $('#FormModal-dialog').dialog('close');
- active(setForm);
+ vm.formSave().then(() => {
+ $scope[formTracker.currentFormName()].$setPristine();
+ $('#FormModal-dialog').dialog('close');
+ active(setForm);
+ }).catch(()=> {
+ event.preventDefault();
+ $('#FormModal-dialog').dialog('close');
+ });
+
},
"class": "btn btn-primary",
"id": "formmodal-save-button"
@@ -396,11 +401,12 @@ export default [
}
loginUpdate();
})
- .catch(function(error) {
- ProcessErrors($scope, error, status, formDefs[formTracker.getCurrent()],
+ .catch(function(data) {
+ ProcessErrors($scope, data.error, data.status, formDefs[formTracker.getCurrent()],
{
- hdr: i18n._('Error!'),
- msg: i18n._('There was an error resetting value. Returned status: ') + error.detail
+ hdr: `
+ ${ i18n._('Error!')} `,
+ msg: i18n._('There was an error resetting value. Returned status: ') + data.error.detail
});
})
@@ -495,14 +501,23 @@ export default [
saveDeferred.resolve(data);
$scope[formTracker.currentFormName()].$setPristine();
+ ngToast.success({
+ timeout: 2000,
+ dismissButton: false,
+ dismissOnTimeout: true,
+ content: `` +
+ i18n._('Save Complete')
+ });
})
- .catch(function(error, status) {
- ProcessErrors($scope, error, status, formDefs[formTracker.getCurrent()],
+ .catch(function(data) {
+ ProcessErrors($scope, data.data, data.status, formDefs[formTracker.getCurrent()],
{
- hdr: i18n._('Error!'),
- msg: i18n._('Failed to save settings. Returned status: ') + status
+ hdr: `
+ ${ i18n._('Error!')} `,
+ msg: i18n._('Failed to save settings. Returned status: ') + data.status
});
- saveDeferred.reject(error);
+ saveDeferred.reject(data);
})
.finally(function() {
Wait('stop');
@@ -528,13 +543,14 @@ export default [
.then(function() {
//TODO consider updating form values with returned data here
})
- .catch(function(error, status) {
+ .catch(function(data) {
//Change back on unsuccessful update
$scope[key] = !$scope[key];
- ProcessErrors($scope, error, status, formDefs[formTracker.getCurrent()],
+ ProcessErrors($scope, data.data, data.status, formDefs[formTracker.getCurrent()],
{
- hdr: i18n._('Error!'),
- msg: i18n._('Failed to save toggle settings. Returned status: ') + error.detail
+ hdr: `
+ ${ i18n._('Error!')} `,
+ msg: i18n._('Failed to save toggle settings. Returned status: ') + data.status
});
})
.finally(function() {
@@ -577,11 +593,12 @@ export default [
});
})
- .catch(function(error) {
- ProcessErrors($scope, error, status, formDefs[formTracker.getCurrent()],
+ .catch(function(data) {
+ ProcessErrors($scope, data.error, data.status, formDefs[formTracker.getCurrent()],
{
- hdr: i18n._('Error!'),
- msg: i18n._('There was an error resetting values. Returned status: ') + error.detail
+ hdr: `
+ ${ i18n._('Error!')} `,
+ msg: i18n._('There was an error resetting values. Returned status: ') + data.error.detail
});
})
.finally(function() {
diff --git a/awx/ui/client/src/configuration/configuration.service.js b/awx/ui/client/src/configuration/configuration.service.js
index bd25d7179c..1d437dc2cd 100644
--- a/awx/ui/client/src/configuration/configuration.service.js
+++ b/awx/ui/client/src/configuration/configuration.service.js
@@ -50,7 +50,7 @@ export default ['$rootScope', 'GetBasePath', 'ProcessErrors', '$q', '$http', 'Re
.then(({data}) => {
deferred.resolve(data);
})
- .catch(({error}) => {
+ .catch((error) => {
deferred.reject(error);
});
@@ -64,7 +64,7 @@ export default ['$rootScope', 'GetBasePath', 'ProcessErrors', '$q', '$http', 'Re
.then(({data}) => {
deferred.resolve(data);
})
- .catch(({error}) => {
+ .catch((error) => {
deferred.reject(error);
});
diff --git a/awx/ui/client/src/shared/Utilities.js b/awx/ui/client/src/shared/Utilities.js
index 301a7eae9d..b0f273c320 100644
--- a/awx/ui/client/src/shared/Utilities.js
+++ b/awx/ui/client/src/shared/Utilities.js
@@ -209,14 +209,17 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
} else {
if (data[field]) {
scope[field + '_api_error'] = data[field][0];
- //scope[form.name + '_form'][field].$setValidity('apiError', false);
$('[name="' + field + '"]').addClass('ng-invalid');
+ $('label[for="' + field + '"] span').addClass('error-color');
$('html, body').animate({scrollTop: $('[name="' + field + '"]').offset().top}, 0);
fieldErrors = true;
+ if(form.fields[field].codeMirror){
+ $(`#cm-${field}-container .CodeMirror`).addClass('error-border');
+ }
}
}
}
- if ((!fieldErrors) && defaultMsg) {
+ if (defaultMsg) {
Alert(defaultMsg.hdr, defaultMsg.msg);
}
} else if (typeof data === 'object' && data !== null) {