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 20166f3b85..beb295fc98 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 @@ -136,7 +136,6 @@ export default [ }, ]; var forms = _.pluck(authForms, 'formDef'); - _.each(forms, function(form) { var keys = _.keys(form.fields); _.each(keys, function(key) { @@ -154,6 +153,8 @@ export default [ } addFieldInfo(form, key); }); + // Disable the save button for non-superusers + form.buttons.save.disabled = 'vm.updateProhibited'; }); function addFieldInfo(form, key) { @@ -165,7 +166,7 @@ export default [ dataPlacement: 'top', placeholder: ConfigurationUtils.formatPlaceholder($scope.$parent.configDataResolve[key].placeholder, key) || null, dataTitle: $scope.$parent.configDataResolve[key].label, - required: $scope.$parent.configDataResolve[key].required + required: $scope.$parent.configDataResolve[key].required, }); } diff --git a/awx/ui/client/src/configuration/configuration.block.less b/awx/ui/client/src/configuration/configuration.block.less index edf80e01a8..de4dae2e2c 100644 --- a/awx/ui/client/src/configuration/configuration.block.less +++ b/awx/ui/client/src/configuration/configuration.block.less @@ -1,4 +1,5 @@ @import "./client/src/shared/branding/colors.default.less"; +@import "../shared/branding/colors.less"; .Form-resetValue, .Form-resetFile { text-transform: uppercase; @@ -49,3 +50,24 @@ input#filePickerText { border-radius: 0 5px 5px 0; background-color: #fff; } + +// Messagebar for system auditor role notifications +.Section-messageBar { + width: 120%; + margin-left: -20px; + padding: 10px; + color: @white; + background-color: @default-link; +} + +.Section-messageBar--close { + position: absolute; + right: 0; + background: none; + border: none; + color: @info-close; +} + +.Section-messageBar--close:hover { + color: @white; +} diff --git a/awx/ui/client/src/configuration/configuration.controller.js b/awx/ui/client/src/configuration/configuration.controller.js index fd5ddcc017..b769ffc8c4 100644 --- a/awx/ui/client/src/configuration/configuration.controller.js +++ b/awx/ui/client/src/configuration/configuration.controller.js @@ -425,16 +425,58 @@ export default [ triggerModal(msg, title, buttons); }; + var show_auditor_bar; + if($rootScope.user_is_system_auditor && Store('show_auditor_bar') !== false) { + show_auditor_bar = true; + } else { + show_auditor_bar = false; + } + + var updateMessageBarPrefs = function() { + vm.show_auditor_bar = false; + Store('show_auditor_bar', vm.show_auditor_bar); + }; + + var closeMessageBar = function() { + var msg = 'Are you sure you want to hide the notification bar?'; + var title = 'Warning: Closing notification bar'; + var buttons = [{ + label: "Cancel", + "class": "btn Form-cancelButton", + "id": "formmodal-cancel-button", + onClick: function() { + $('#FormModal-dialog').dialog('close'); + } + }, { + label: "OK", + onClick: function() { + $('#FormModal-dialog').dialog('close'); + updateMessageBarPrefs(); + }, + "class": "btn btn-primary", + "id": "formmodal-save-button" + }]; + triggerModal(msg, title, buttons); + }; + + var updateProhibited = true; + if($rootScope.user_is_superuser) { + updateProhibited = false; + } + angular.extend(vm, { activeTab: activeTab, activeTabCheck: activeTabCheck, + closeMessageBar: closeMessageBar, currentForm: currentForm, formCancel: formCancel, formTracker: formTracker, formSave: formSave, populateFromApi: populateFromApi, resetAllConfirm: resetAllConfirm, - triggerModal: triggerModal + show_auditor_bar: show_auditor_bar, + triggerModal: triggerModal, + updateProhibited: updateProhibited }); } ]; diff --git a/awx/ui/client/src/configuration/configuration.partial.html b/awx/ui/client/src/configuration/configuration.partial.html index 31a14d9e51..42beab808c 100644 --- a/awx/ui/client/src/configuration/configuration.partial.html +++ b/awx/ui/client/src/configuration/configuration.partial.html @@ -1,3 +1,9 @@ +
+Edit Tower's configuration. diff --git a/awx/ui/client/src/shared/branding/colors.less b/awx/ui/client/src/shared/branding/colors.less index 044ba75db7..cb8a4cc098 100644 --- a/awx/ui/client/src/shared/branding/colors.less +++ b/awx/ui/client/src/shared/branding/colors.less @@ -11,6 +11,7 @@ @info: #d9edf7; /* alert info background color */ @info-border: #bce8f1; /* alert info border color */ @info-color: #3a87ad; +@info-close: #ccdeed; @unreachable: #FF0000; @changed: #FF9900; // Ansible Changed @skipped: #2dbaba; // Ansible Skipped diff --git a/awx/ui/client/src/shared/form-generator.js b/awx/ui/client/src/shared/form-generator.js index 5866a464ba..defdc6f5dc 100644 --- a/awx/ui/client/src/shared/form-generator.js +++ b/awx/ui/client/src/shared/form-generator.js @@ -1733,15 +1733,26 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat if (btn !== 'reset') { //html += "ng-disabled=\"" + this.form.name + "_form.$pristine || " + this.form.name + "_form.$invalid"; - html += "ng-disabled=\"" + ngDisabled; - //html += (this.form.allowReadonly) ? " || " + this.form.name + "ReadOnly == true" : ""; - html += "\" "; + if (button.disabled && button.disable !== true) { + // Allow disabled to overrule ng-disabled. Used for permissions. + // Example: system auditor can view but not update. Form validity + // is no longer a concern but ng-disabled will update disabled + // status on render so we stop applying it here. + } else { + html += "ng-disabled=\"" + ngDisabled; + //html += (this.form.allowReadonly) ? " || " + this.form.name + "ReadOnly == true" : ""; + html += "\" "; + } + } else { //html += "ng-disabled=\"" + this.form.name + "_form.$pristine"; //html += (this.form.allowReadonly) ? " || " + this.form.name + "ReadOnly == true" : ""; //html += "\" "; } } + if (button.disabled && button.disable !== true) { + html += ` disabled="disabled" `; + } if(button.awToolTip) { html += " aw-tool-tip='" + button.awToolTip + "' data-placement='" + button.dataPlacement + "' data-tip-watch='" + button.dataTipWatch + "'"; }