diff --git a/awx/ui/client/legacy-styles/ansible-ui.less b/awx/ui/client/legacy-styles/ansible-ui.less index cfee86535e..81ca7aa147 100644 --- a/awx/ui/client/legacy-styles/ansible-ui.less +++ b/awx/ui/client/legacy-styles/ansible-ui.less @@ -896,10 +896,6 @@ select.field-mini-height { font-size: 10.5px; } -.ask-checkbox { - margin-left: 10px; -} - .no-padding { padding: 0; margin: 0; diff --git a/awx/ui/client/legacy-styles/forms.less b/awx/ui/client/legacy-styles/forms.less index 4f65172302..1afc218913 100644 --- a/awx/ui/client/legacy-styles/forms.less +++ b/awx/ui/client/legacy-styles/forms.less @@ -455,6 +455,12 @@ input[type='radio']:checked:before { padding-right: 0px; } +.Form-subCheckbox { + margin-top: 5px; + font-size: small; + color: @default-interface-txt; +} + @media only screen and (max-width: 650px) { .Form-formGroup { flex: 1 0 auto; diff --git a/awx/ui/client/src/forms/Credentials.js b/awx/ui/client/src/forms/Credentials.js index d96ef6d594..00853520bd 100644 --- a/awx/ui/client/src/forms/Credentials.js +++ b/awx/ui/client/src/forms/Credentials.js @@ -119,7 +119,10 @@ export default init: false }, autocomplete: false, - ask: false, + subCheckbox: { + variable: 'secret_key_ask', + text: 'Ask at runtime?' + }, clear: false, hasShowInputButton: true, apiField: 'password', @@ -207,7 +210,6 @@ export default init: false }, autocomplete: false, - ask: false, hasShowInputButton: true, clear: false, subForm: 'credentialSubForm' @@ -216,7 +218,6 @@ export default labelBind: 'passwordLabel', type: 'sensitive', ngShow: "kind.value == 'scm' || kind.value == 'vmware' || kind.value == 'openstack'|| kind.value == 'foreman'|| kind.value == 'cloudforms'|| kind.value == 'net' || kind.value == 'azure_rm'", - ask: false, clear: false, autocomplete: false, hasShowInputButton: true, @@ -232,7 +233,10 @@ export default ngShow: "kind.value == 'ssh'", addRequired: false, editRequired: false, - ask: true, + subCheckbox: { + variable: 'ssh_password_ask', + text: 'Ask at runtime?' + }, hasShowInputButton: true, autocomplete: false, subForm: 'credentialSubForm' @@ -266,9 +270,12 @@ export default addRequired: false, editRequired: false, ngDisabled: "keyEntered === false", - ask: true, + subCheckbox: { + variable: 'ssh_key_unlock_ask', + ngShow: "kind.value == 'ssh'", + text: 'Ask at runtime?' + }, hasShowInputButton: true, - askShow: "kind.value == 'ssh'", // Only allow ask for machine credentials subForm: 'credentialSubForm' }, "become_method": { @@ -300,7 +307,10 @@ export default ngShow: "(kind.value == 'ssh' && (become_method && become_method.value)) ", addRequired: false, editRequired: false, - ask: true, + subCheckbox: { + variable: 'become_password_ask', + text: 'Ask at runtime?' + }, hasShowInputButton: true, autocomplete: false, subForm: 'credentialSubForm' @@ -391,7 +401,10 @@ export default ngShow: "kind.value == 'ssh'", addRequired: false, editRequired: false, - ask: true, + subCheckbox: { + variable: 'vault_password_ask', + text: 'Ask at runtime?' + }, hasShowInputButton: true, autocomplete: false, subForm: 'credentialSubForm' diff --git a/awx/ui/client/src/forms/JobTemplates.js b/awx/ui/client/src/forms/JobTemplates.js index 058db203d6..9185d73e90 100644 --- a/awx/ui/client/src/forms/JobTemplates.js +++ b/awx/ui/client/src/forms/JobTemplates.js @@ -50,7 +50,12 @@ export default " syntax, test environment setup and report problems.
", dataTitle: 'Job Type', dataPlacement: 'right', - dataContainer: "body" + dataContainer: "body", + subCheckbox: { + variable: 'ask_job_type_on_launch', + ngShow: "!job_type.value || job_type.value !== 'scan'", + text: 'Prompt on launch' + } }, inventory: { label: 'Inventory', @@ -59,14 +64,20 @@ export default sourceField: 'name', ngClick: 'lookUpInventory()', awRequiredWhen: { - reqExpression: "inventoryrequired", - init: "true" + reqExpression: '!ask_inventory_on_launch', + alwaysShowAsterisk: true }, + requiredErrorMsg: "Please select an Inventory or check the Prompt on launch option.", column: 1, awPopOver: "Select the inventory containing the hosts you want this job to manage.
", dataTitle: 'Inventory', dataPlacement: 'right', - dataContainer: "body" + dataContainer: "body", + subCheckbox: { + variable: 'ask_inventory_on_launch', + ngShow: "!job_type.value || job_type.value !== 'scan'", + text: 'Prompt on launch' + } }, project: { label: 'Project', @@ -90,7 +101,7 @@ export default ngOptions: 'book for book in playbook_options track by book', id: 'playbook-select', awRequiredWhen: { - reqExpression: "playbookrequired", + reqExpression: "playbookrequired", init: "true" }, column: 1, @@ -111,14 +122,21 @@ export default sourceModel: 'credential', sourceField: 'name', ngClick: 'lookUpCredential()', - addRequired: false, - editRequired: false, + awRequiredWhen: { + reqExpression: '!ask_credential_on_launch', + alwaysShowAsterisk: true + }, + requiredErrorMsg: "Please select a Machine Credential or check the Prompt on launch option.", column: 1, awPopOver: "Select the credential you want the job to use when accessing the remote hosts. Choose the credential containing " + " the username and SSH key or password that Ansible will need to log into the remote hosts.
", dataTitle: 'Credential', dataPlacement: 'right', - dataContainer: "body" + dataContainer: "body", + subCheckbox: { + variable: 'ask_credential_on_launch', + text: 'Prompt on launch' + } }, cloud_credential: { label: 'Cloud Credential', @@ -165,7 +183,11 @@ export default "the Patterns topic at docs.ansible.com.", dataTitle: 'Limit', dataPlacement: 'right', - dataContainer: "body" + dataContainer: "body", + subCheckbox: { + variable: 'ask_limit_on_launch', + text: 'Prompt on launch' + } }, verbosity: { label: 'Verbosity', @@ -196,7 +218,11 @@ export default "in the Job Tags field:\nconfiguration,packages\n", dataTitle: "Job Tags", dataPlacement: "right", - dataContainer: "body" + dataContainer: "body", + subCheckbox: { + variable: 'ask_tags_on_launch', + text: 'Prompt on launch' + } }, labels: { label: 'Labels', @@ -227,20 +253,11 @@ export default "
---\n", dataTitle: 'Extra Variables', dataPlacement: 'right', - dataContainer: "body" - }, - ask_variables_on_launch: { - label: 'Prompt for Extra Variables', - type: 'checkbox', - addRequired: false, - editRequird: false, - trueValue: 'true', - falseValue: 'false', - column: 2, - awPopOver: "
somevar: somevalue
password: magic
If checked, user will be prompted at job launch with a dialog allowing override of the extra variables setting.
", - dataPlacement: 'right', - dataTitle: 'Prompt for Extra Variables', - dataContainer: "body" + dataContainer: "body", + subCheckbox: { + variable: 'ask_variables_on_launch', + text: 'Prompt on launch' + } }, become_enabled: { label: 'Enable Privilege Escalation', diff --git a/awx/ui/client/src/helpers/JobTemplates.js b/awx/ui/client/src/helpers/JobTemplates.js index 1f504c6951..90317a41a8 100644 --- a/awx/ui/client/src/helpers/JobTemplates.js +++ b/awx/ui/client/src/helpers/JobTemplates.js @@ -115,9 +115,24 @@ angular.module('JobTemplatesHelper', ['Utilities']) scope.survey_enabled = data.survey_enabled; - scope.ask_variables_on_launch = (data.ask_variables_on_launch) ? 'true' : 'false'; + scope.ask_variables_on_launch = (data.ask_variables_on_launch) ? true : false; master.ask_variables_on_launch = scope.ask_variables_on_launch; + scope.ask_limit_on_launch = (data.ask_limit_on_launch) ? true : false; + master.ask_limit_on_launch = scope.ask_limit_on_launch; + + scope.ask_tags_on_launch = (data.ask_tags_on_launch) ? true : false; + master.ask_tags_on_launch = scope.ask_tags_on_launch; + + scope.ask_job_type_on_launch = (data.ask_job_type_on_launch) ? true : false; + master.ask_job_type_on_launch = scope.ask_job_type_on_launch; + + scope.ask_inventory_on_launch = (data.ask_inventory_on_launch) ? true : false; + master.ask_inventory_on_launch = scope.ask_inventory_on_launch; + + scope.ask_credential_on_launch = (data.ask_credential_on_launch) ? true : false; + master.ask_credential_on_launch = scope.ask_credential_on_launch; + relatedSets = form.relatedSets(data.related); if (data.host_config_key) { diff --git a/awx/ui/client/src/job-templates/add/job-templates-add.controller.js b/awx/ui/client/src/job-templates/add/job-templates-add.controller.js index 01b80551c6..44879c05a5 100644 --- a/awx/ui/client/src/job-templates/add/job-templates-add.controller.js +++ b/awx/ui/client/src/job-templates/add/job-templates-add.controller.js @@ -230,6 +230,10 @@ $scope.jobTypeChange = function(){ if($scope.job_type){ if($scope.job_type.value === 'scan'){ + // If the job_type is 'scan' then we don't want the user to be + // able to prompt for job type or inventory + $scope.ask_job_type_on_launch = false; + $scope.ask_inventory_on_launch = false; $scope.toggleScanInfo(); } else if($scope.project_name === "Default"){ @@ -478,6 +482,14 @@ } } } + + data.ask_tags_on_launch = $scope.ask_tags_on_launch ? $scope.ask_tags_on_launch : false; + data.ask_limit_on_launch = $scope.ask_limit_on_launch ? $scope.ask_limit_on_launch : false; + data.ask_job_type_on_launch = $scope.ask_job_type_on_launch ? $scope.ask_job_type_on_launch : false; + data.ask_inventory_on_launch = $scope.ask_inventory_on_launch ? $scope.ask_inventory_on_launch : false; + data.ask_variables_on_launch = $scope.ask_variables_on_launch ? $scope.ask_variables_on_launch : false; + data.ask_credential_on_launch = $scope.ask_credential_on_launch ? $scope.ask_credential_on_launch : false; + data.extra_vars = ToJSON($scope.parseType, $scope.variables, true); if(data.job_type === 'scan' && diff --git a/awx/ui/client/src/job-templates/edit/job-templates-edit.controller.js b/awx/ui/client/src/job-templates/edit/job-templates-edit.controller.js index 04cdfb80e5..2b1412f113 100644 --- a/awx/ui/client/src/job-templates/edit/job-templates-edit.controller.js +++ b/awx/ui/client/src/job-templates/edit/job-templates-edit.controller.js @@ -117,6 +117,10 @@ export default $scope.jobTypeChange = function(){ if($scope.job_type){ if($scope.job_type.value === 'scan'){ + // If the job_type is 'scan' then we don't want the user to be + // able to prompt for job type or inventory + $scope.ask_job_type_on_launch = false; + $scope.ask_inventory_on_launch = false; $scope.toggleScanInfo(); } else if($scope.project_name === "Default"){ @@ -549,6 +553,14 @@ export default } } } + + data.ask_tags_on_launch = $scope.ask_tags_on_launch ? $scope.ask_tags_on_launch : false; + data.ask_limit_on_launch = $scope.ask_limit_on_launch ? $scope.ask_limit_on_launch : false; + data.ask_job_type_on_launch = $scope.ask_job_type_on_launch ? $scope.ask_job_type_on_launch : false; + data.ask_inventory_on_launch = $scope.ask_inventory_on_launch ? $scope.ask_inventory_on_launch : false; + data.ask_variables_on_launch = $scope.ask_variables_on_launch ? $scope.ask_variables_on_launch : false; + data.ask_credential_on_launch = $scope.ask_credential_on_launch ? $scope.ask_credential_on_launch : false; + data.extra_vars = ToJSON($scope.parseType, $scope.variables, true); if(data.job_type === 'scan' && diff --git a/awx/ui/client/src/shared/directives.js b/awx/ui/client/src/shared/directives.js index 70085d78cd..b6dac10c89 100644 --- a/awx/ui/client/src/shared/directives.js +++ b/awx/ui/client/src/shared/directives.js @@ -343,13 +343,16 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'JobsHelper']) var viewValue = elm.val(), label, validity = true; label = $(elm).closest('.form-group').find('label').first(); + if ( isRequired && (elm.attr('required') === null || elm.attr('required') === undefined) ) { $(elm).attr('required','required'); - $(label).addClass('prepend-asterisk'); + $(label).removeClass('prepend-asterisk').addClass('prepend-asterisk'); } else if (!isRequired) { elm.removeAttr('required'); - $(label).removeClass('prepend-asterisk'); + if(!attrs.awrequiredAlwaysShowAsterisk) { + $(label).removeClass('prepend-asterisk'); + } } if (isRequired && (viewValue === undefined || viewValue === null || viewValue === '')) { validity = false; diff --git a/awx/ui/client/src/shared/form-generator.js b/awx/ui/client/src/shared/form-generator.js index f4a0e26bfb..30a6d39fd8 100644 --- a/awx/ui/client/src/shared/form-generator.js +++ b/awx/ui/client/src/shared/form-generator.js @@ -438,8 +438,8 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat if (f.awPassMatch && scope[form.name + '_form'][fld]) { scope[form.name + '_form'][fld].$setValidity('awpassmatch', true); } - if (f.ask) { - scope[fld + '_ask'] = false; + if (f.subCheckbox) { + scope[f.subCheckbox.variable] = false; } } @@ -786,14 +786,15 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat html += (field.awPassMatch) ? "awpassmatch=\"" + field.associated + "\" " : ""; html += (field.capitalize) ? "capitalize " : ""; html += (field.awSurveyQuestion) ? "aw-survey-question" : "" ; - html += (field.ask) ? "ng-disabled=\"" + fld + "_ask\" " : ""; + html += (field.subCheckbox) ? "ng-disabled=\"" + field.subCheckbox.variable + "\" " : ""; html += (field.autocomplete !== undefined) ? this.attr(field, 'autocomplete') : ""; if(field.awRequiredWhen) { html += field.awRequiredWhen.init ? "data-awrequired-init=\"" + field.awRequiredWhen.init + "\" " : ""; html += field.awRequiredWhen.reqExpression ? "aw-required-when=\"" + field.awRequiredWhen.reqExpression + "\" " : ""; + html += field.awRequiredWhen.alwaysShowAsterisk ? "data-awrequired-always-show-asterisk=true " : ""; } html += (field.awValidUrl) ? "aw-valid-url " : ""; - html += (field.associated && this.form.fields[field.associated].ask) ? "ng-disabled=\"" + field.associated + "_ask\" " : ""; + html += (field.associated && this.form.fields[field.associated].subCheckbox) ? "ng-disabled=\"" + this.form.fields[field.associated].subCheckbox.variable + "\" " : ""; html += ">\n"; } @@ -802,18 +803,9 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat html += "id=\"" + this.form.name + "_" + fld + "_clear_btn\" "; html += "class=\"btn btn-default\" ng-click=\"clear('" + fld + "','" + field.associated + "')\" " + "aw-tool-tip=\"Clear " + field.label + "\" id=\"" + fld + "-clear-btn\" "; - html += (field.ask) ? "ng-disabled=\"" + fld + "_ask\" " : ""; + html += (field.subCheckbox) ? "ng-disabled=\"" + field.subCheckbox.variable + "\" " : ""; html += " >\n"; html += "\n\n"; - if (field.ask) { - html += ""; - } } if (field.genMD5) { @@ -822,11 +814,23 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat "\n\n"; } + if (field.subCheckbox) { + html += ""; + } + // Add error messages if ((options.mode === 'add' && field.addRequired) || (options.mode === 'edit' && field.editRequired) || field.awRequiredWhen) { html += "