mirror of
https://github.com/ansible/awx.git
synced 2024-11-02 09:51:09 +03:00
Merge pull request #6466 from mabashian/launch-job-multiple-credentials
Updated launch modal to accommodate extra credential prompting
This commit is contained in:
commit
e1d2edb954
@ -2334,7 +2334,7 @@ html input[disabled] {
|
||||
}
|
||||
|
||||
.btn.disabled,.btn[disabled],fieldset[disabled] .bt {
|
||||
opacity: 1;
|
||||
opacity: 0.65;
|
||||
}
|
||||
|
||||
.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled {
|
||||
|
@ -26,7 +26,7 @@ export default ['i18n', function(i18n) {
|
||||
key: true,
|
||||
label: i18n._('Name'),
|
||||
columnClass: 'col-md-3 col-sm-9 col-xs-9',
|
||||
modalColumnClass: 'col-md-11',
|
||||
modalColumnClass: 'col-md-12',
|
||||
awToolTip: '{{credential.description}}',
|
||||
dataPlacement: 'top'
|
||||
},
|
||||
|
@ -24,11 +24,11 @@
|
||||
|
||||
init();
|
||||
|
||||
$scope.toggle_row = function(id){
|
||||
$scope.toggle_row = function(selectedRow){
|
||||
// toggle off anything else currently selected
|
||||
_.forEach($scope.groups, (item) => {return item.id === id ? item.checked = 1 : item.checked = null;});
|
||||
_.forEach($scope.groups, (item) => {return item.id === selectedRow.id ? item.checked = 1 : item.checked = null;});
|
||||
// yoink the currently selected thing
|
||||
$scope.selected = _.find($scope.groups, (item) => {return item.id === id;});
|
||||
$scope.selected = _.find($scope.groups, (item) => {return item.id === selectedRow.id;});
|
||||
};
|
||||
|
||||
$scope.formCancel = function(){
|
||||
@ -62,7 +62,7 @@
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$scope.toggleTargetRootGroup = function(){
|
||||
$scope.selected = !$scope.selected;
|
||||
// cannot perform copy operations to root group level
|
||||
|
@ -22,11 +22,11 @@
|
||||
|
||||
init();
|
||||
|
||||
$scope.toggle_row = function(id){
|
||||
$scope.toggle_row = function(selectedRow){
|
||||
// toggle off anything else currently selected
|
||||
_.forEach($scope.groups, (item) => {return item.id === id ? item.checked = 1 : item.checked = null;});
|
||||
_.forEach($scope.groups, (item) => {return item.id === selectedRow.id ? item.checked = 1 : item.checked = null;});
|
||||
// yoink the currently selected thing
|
||||
$scope.selected = _.find($scope.groups, (item) => {return item.id === id;});
|
||||
$scope.selected = _.find($scope.groups, (item) => {return item.id === selectedRow.id;});
|
||||
};
|
||||
$scope.formCancel = function(){
|
||||
$state.go('^');
|
||||
|
@ -45,7 +45,7 @@ export default ['i18n', function(i18n) {
|
||||
key: true,
|
||||
label: i18n._('Name'),
|
||||
columnClass: 'col-md-4 col-sm-3 col-xs-6 List-staticColumnAdjacent',
|
||||
modalColumnClass: 'col-md-11',
|
||||
modalColumnClass: 'col-md-12',
|
||||
awToolTip: "{{ inventory.description }}",
|
||||
awTipPlacement: "top",
|
||||
ngClick: 'editInventory(inventory)'
|
||||
|
@ -1,5 +1,12 @@
|
||||
export default ['jobData', 'jobDataOptions', 'jobLabels', 'jobFinished', 'count', '$scope', 'ParseTypeChange', 'ParseVariableString', 'jobResultsService', 'eventQueue', '$compile', '$log', 'Dataset', '$q', 'QuerySet', '$rootScope', 'moment', '$stateParams', 'i18n', 'fieldChoices', 'fieldLabels', 'workflowResultsService', 'statusSocket', 'GetBasePath',
|
||||
function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTypeChange, ParseVariableString, jobResultsService, eventQueue, $compile, $log, Dataset, $q, QuerySet, $rootScope, moment, $stateParams, i18n, fieldChoices, fieldLabels, workflowResultsService, statusSocket, GetBasePath) {
|
||||
export default ['jobData', 'jobDataOptions', 'jobLabels', 'jobFinished', 'count', '$scope', 'ParseTypeChange',
|
||||
'ParseVariableString', 'jobResultsService', 'eventQueue', '$compile', '$log', 'Dataset', '$q',
|
||||
'QuerySet', '$rootScope', 'moment', '$stateParams', 'i18n', 'fieldChoices', 'fieldLabels',
|
||||
'workflowResultsService', 'statusSocket', 'GetBasePath', '$state', 'jobExtraCredentials',
|
||||
function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTypeChange,
|
||||
ParseVariableString, jobResultsService, eventQueue, $compile, $log, Dataset, $q,
|
||||
QuerySet, $rootScope, moment, $stateParams, i18n, fieldChoices, fieldLabels,
|
||||
workflowResultsService, statusSocket, GetBasePath, $state, jobExtraCredentials) {
|
||||
|
||||
var toDestroy = [];
|
||||
var cancelRequests = false;
|
||||
var runTimeElapsedTimer = null;
|
||||
@ -45,6 +52,8 @@ function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTy
|
||||
// used for tag search
|
||||
$scope.job_events = $scope.job_event_dataset.results;
|
||||
|
||||
$scope.jobExtraCredentials = jobExtraCredentials;
|
||||
|
||||
var getTowerLinks = function() {
|
||||
var getTowerLink = function(key) {
|
||||
if(key === 'schedule') {
|
||||
|
@ -278,6 +278,22 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- EXTRA CREDENTIALS DETAIL -->
|
||||
<div class="JobResults-resultRow"
|
||||
ng-show="jobExtraCredentials.length > 0">
|
||||
<label class="JobResults-resultRowLabel">
|
||||
Extra Credentials
|
||||
</label>
|
||||
<div class="JobResults-resultRowText">
|
||||
<span ng-repeat="extraCredential in jobExtraCredentials">
|
||||
<a ui-sref="credentials.edit({credential_id: extraCredential.id})" aw-tool-tip="Edit the credential" data-placement="top">
|
||||
{{ extraCredential.name }}
|
||||
</a>
|
||||
{{$last ? '' : ', '}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CLOUD CREDENTIAL DETAIL -->
|
||||
<div class="JobResults-resultRow"
|
||||
ng-show="job.summary_fields.cloud_credential.name">
|
||||
|
@ -170,6 +170,17 @@ export default {
|
||||
});
|
||||
return val.promise;
|
||||
}],
|
||||
jobExtraCredentials: ['Rest', 'GetBasePath', '$stateParams', '$q', function(Rest, GetBasePath, $stateParams, $q) {
|
||||
Rest.setUrl(GetBasePath('jobs') + $stateParams.id + '/extra_credentials');
|
||||
var val = $q.defer();
|
||||
Rest.get()
|
||||
.then(function(res) {
|
||||
val.resolve(res.data.results);
|
||||
}, function(res) {
|
||||
val.reject(res);
|
||||
});
|
||||
return val.promise;
|
||||
}]
|
||||
},
|
||||
templateUrl: templateUrl('job-results/job-results'),
|
||||
controller: 'jobResultsController'
|
||||
|
@ -107,8 +107,15 @@ export default
|
||||
}
|
||||
|
||||
// include the credential used if the user was prompted to choose a cred
|
||||
if(scope.ask_credential_on_launch && !Empty(scope.selected_credential)){
|
||||
job_launch_data.credential_id = scope.selected_credential.id;
|
||||
if(scope.ask_credential_on_launch && !Empty(scope.selected_credentials.machine)){
|
||||
job_launch_data.credential_id = scope.selected_credentials.machine.id;
|
||||
}
|
||||
|
||||
if(scope.ask_extra_credentials_on_launch){
|
||||
job_launch_data.extra_credentials = [];
|
||||
scope.selected_credentials.extra.forEach((extraCredential) => {
|
||||
job_launch_data.extra_credentials.push(extraCredential.id);
|
||||
});
|
||||
}
|
||||
|
||||
// If the extra_vars dict is empty, we don't want to include it if we didn't prompt for anything.
|
||||
|
@ -140,7 +140,7 @@
|
||||
font-weight: normal;
|
||||
font-size: small;
|
||||
}
|
||||
.JobSubmission-previewItemTitle {
|
||||
.JobSubmission-previewItemTitle, .JobSubmission-previewItemSubTitle, .JobSubmission-selectedItemInfoSubTitle {
|
||||
color: @default-interface-txt;
|
||||
}
|
||||
.JobSubmission-previewItemNone {
|
||||
@ -189,13 +189,18 @@
|
||||
}
|
||||
.JobSubmission-selectedItemInfo {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
flex: 0 0 100%;
|
||||
}
|
||||
.JobSubmission-selectedItemRevert {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
.JobSubmission-selectedItemLabel {
|
||||
.JobSubmission-credentialSubSection {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.JobSubmission-label {
|
||||
color: @default-interface-txt;
|
||||
margin-right: 10px;
|
||||
}
|
||||
@ -214,3 +219,9 @@
|
||||
.JobSubmission-passwordButton {
|
||||
padding: 5px 13px!important;
|
||||
}
|
||||
.JobSubmission .List-noItems {
|
||||
margin-top: auto;
|
||||
}
|
||||
.JobSubmission-selectedItemLabel {
|
||||
flex: 0 0 165px;
|
||||
}
|
||||
|
@ -64,10 +64,8 @@
|
||||
export default
|
||||
[ '$scope', 'GetBasePath', 'Wait', 'Rest', 'ProcessErrors',
|
||||
'LaunchJob', '$state', 'InventoryList', 'CredentialList', 'ParseTypeChange',
|
||||
'GetSurveyQuestions',
|
||||
function($scope, GetBasePath, Wait, Rest, ProcessErrors,
|
||||
LaunchJob, $state, InventoryList, CredentialList, ParseTypeChange,
|
||||
GetSurveyQuestions) {
|
||||
LaunchJob, $state, InventoryList, CredentialList, ParseTypeChange) {
|
||||
|
||||
var launch_url;
|
||||
|
||||
@ -84,8 +82,8 @@ export default
|
||||
};
|
||||
|
||||
var updateRequiredPasswords = function() {
|
||||
if($scope.selected_credential) {
|
||||
if($scope.selected_credential.id === $scope.defaults.credential.id) {
|
||||
if($scope.selected_credentials.machine) {
|
||||
if($scope.selected_credentials.machine.id === $scope.defaults.credential.id) {
|
||||
clearRequiredPasswords();
|
||||
for(var i=0; i<$scope.passwords_needed_to_start.length; i++) {
|
||||
var password = $scope.passwords_needed_to_start[i];
|
||||
@ -106,11 +104,11 @@ export default
|
||||
}
|
||||
}
|
||||
else {
|
||||
if($scope.selected_credential.kind === "ssh"){
|
||||
$scope.ssh_password_required = ($scope.selected_credential.password === "ASK") ? true : false;
|
||||
$scope.ssh_key_unlock_required = ($scope.selected_credential.ssh_key_unlock === "ASK") ? true : false;
|
||||
$scope.become_password_required = ($scope.selected_credential.become_password === "ASK") ? true : false;
|
||||
$scope.vault_password_required = ($scope.selected_credential.vault_password === "ASK") ? true : false;
|
||||
if($scope.selected_credentials.machine.kind === "ssh"){
|
||||
$scope.ssh_password_required = ($scope.selected_credentials.machine.password === "ASK") ? true : false;
|
||||
$scope.ssh_key_unlock_required = ($scope.selected_credentials.machine.ssh_key_unlock === "ASK") ? true : false;
|
||||
$scope.become_password_required = ($scope.selected_credentials.machine.become_password === "ASK") ? true : false;
|
||||
$scope.vault_password_required = ($scope.selected_credentials.machine.vault_password === "ASK") ? true : false;
|
||||
}
|
||||
else {
|
||||
clearRequiredPasswords();
|
||||
@ -133,6 +131,10 @@ export default
|
||||
$scope.init = function() {
|
||||
$scope.forms = {};
|
||||
$scope.passwords = {};
|
||||
$scope.selected_credentials = {
|
||||
machine: null,
|
||||
extra: []
|
||||
};
|
||||
|
||||
// As of 3.0, the only place the user can relaunch a
|
||||
// playbook is on jobTemplates.edit (completed_jobs tab),
|
||||
@ -155,6 +157,10 @@ export default
|
||||
}
|
||||
}
|
||||
|
||||
$scope.$watch('selected_credentials.machine', function(){
|
||||
updateRequiredPasswords();
|
||||
});
|
||||
|
||||
// Get the job or job_template record
|
||||
Wait('start');
|
||||
Rest.setUrl(launch_url);
|
||||
@ -170,6 +176,7 @@ export default
|
||||
$scope.password_needed = data.passwords_needed_to_start && data.passwords_needed_to_start.length > 0;
|
||||
$scope.has_default_inventory = data.defaults && data.defaults.inventory && data.defaults.inventory.id;
|
||||
$scope.has_default_credential = data.defaults && data.defaults.credential && data.defaults.credential.id;
|
||||
$scope.has_default_extra_credentials = data.defaults && data.defaults.extra_credentials && data.defaults.extra_credentials.length > 0;
|
||||
|
||||
$scope.other_prompt_data = {};
|
||||
|
||||
@ -200,11 +207,33 @@ export default
|
||||
}
|
||||
|
||||
if($scope.has_default_credential) {
|
||||
$scope.selected_credential = angular.copy($scope.defaults.credential);
|
||||
updateRequiredPasswords();
|
||||
$scope.selected_credentials.machine = angular.copy($scope.defaults.credential);
|
||||
}
|
||||
|
||||
if( ($scope.submitJobType === 'workflow_job_template' && !$scope.survey_enabled) || ($scope.submitJobRelaunch && !$scope.password_needed) || (!$scope.submitJobRelaunch && $scope.can_start_without_user_input && !$scope.ask_inventory_on_launch && !$scope.ask_credential_on_launch && !$scope.has_other_prompts && !$scope.survey_enabled)) {
|
||||
if($scope.ask_extra_credentials_on_launch) {
|
||||
// Go out and get the credential types
|
||||
Rest.setUrl(GetBasePath('credential_types'));
|
||||
Rest.get()
|
||||
.success(function (credentialTypeData) {
|
||||
let credential_types = {};
|
||||
$scope.credentialKindOptions = [];
|
||||
credentialTypeData.results.forEach((credentialType => {
|
||||
credential_types[credentialType.id] = credentialType;
|
||||
if(($scope.ask_credential_on_launch || (!$scope.ask_credential_on_launch && credentialType.id !== 1)) && credentialType.kind.match(/^(cloud|network|ssh)$/)) {
|
||||
$scope.credentialKindOptions.push({
|
||||
name: credentialType.name,
|
||||
value: credentialType.id
|
||||
});
|
||||
}
|
||||
}));
|
||||
$scope.credential_types = credential_types;
|
||||
if($scope.has_default_extra_credentials) {
|
||||
$scope.selected_credentials.extra = angular.copy($scope.defaults.extra_credentials);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if( ($scope.submitJobType === 'workflow_job_template' && !$scope.survey_enabled) || ($scope.submitJobRelaunch && !$scope.password_needed) || (!$scope.submitJobRelaunch && $scope.can_start_without_user_input && !$scope.ask_inventory_on_launch && !$scope.ask_credential_on_launch && !$scope.ask_extra_credentials_on_launch && !$scope.has_other_prompts && !$scope.survey_enabled)) {
|
||||
// The job can be launched if
|
||||
// a) It's a relaunch and no passwords are needed
|
||||
// or
|
||||
@ -219,7 +248,7 @@ export default
|
||||
if($scope.ask_inventory_on_launch) {
|
||||
$scope.setStep("inventory", true);
|
||||
}
|
||||
else if($scope.ask_credential_on_launch || $scope.password_needed) {
|
||||
else if($scope.ask_credential_on_launch || $scope.ask_extra_credentials_on_launch || $scope.password_needed) {
|
||||
$scope.setStep("credential", true);
|
||||
}
|
||||
else if($scope.has_other_prompts) {
|
||||
@ -247,8 +276,7 @@ export default
|
||||
}
|
||||
if(jobResultData.summary_fields.credential) {
|
||||
$scope.defaults.credential = angular.copy(jobResultData.summary_fields.credential);
|
||||
$scope.selected_credential = angular.copy(jobResultData.summary_fields.credential);
|
||||
updateRequiredPasswords();
|
||||
$scope.selected_credentials.machine = angular.copy(jobResultData.summary_fields.credential);
|
||||
}
|
||||
initiateModal();
|
||||
})
|
||||
@ -296,33 +324,24 @@ export default
|
||||
|
||||
};
|
||||
|
||||
$scope.getListsAndSurvey = function() {
|
||||
if($scope.ask_inventory_on_launch) {
|
||||
$scope.includeInventoryList = true;
|
||||
}
|
||||
if($scope.ask_credential_on_launch) {
|
||||
$scope.includeCredentialList = true;
|
||||
}
|
||||
if($scope.survey_enabled) {
|
||||
GetSurveyQuestions({
|
||||
scope: $scope,
|
||||
id: $scope.submitJobId,
|
||||
submitJobType: $scope.submitJobType
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
$scope.revertToDefaultInventory = function() {
|
||||
if($scope.has_default_inventory) {
|
||||
$scope.selected_inventory = angular.copy($scope.defaults.inventory);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.revertToDefaultCredential = function() {
|
||||
$scope.revertToDefaultCredentials = function() {
|
||||
if($scope.has_default_credential) {
|
||||
$scope.selected_credential = angular.copy($scope.defaults.credential);
|
||||
updateRequiredPasswords();
|
||||
$scope.selected_credentials.machine = angular.copy($scope.defaults.credential);
|
||||
}
|
||||
else {
|
||||
$scope.selected_credentials.machine = null;
|
||||
}
|
||||
if($scope.has_default_extra_credentials) {
|
||||
$scope.selected_credentials.extra = angular.copy($scope.defaults.extra_credentials);
|
||||
}
|
||||
else {
|
||||
$scope.selected_credentials.extra = [];
|
||||
}
|
||||
};
|
||||
|
||||
@ -340,8 +359,7 @@ export default
|
||||
$scope.toggle_credential = function(id) {
|
||||
$scope.credentials.forEach(function(row, i) {
|
||||
if (row.id === id) {
|
||||
$scope.selected_credential = angular.copy(row);
|
||||
updateRequiredPasswords();
|
||||
$scope.selected_credentials.machine = angular.copy(row);
|
||||
$scope.credentials[i].checked = 1;
|
||||
} else {
|
||||
$scope.credentials[i].checked = 0;
|
||||
@ -351,7 +369,7 @@ export default
|
||||
|
||||
$scope.getActionButtonText = function() {
|
||||
if($scope.step === "inventory") {
|
||||
return ($scope.ask_credential_on_launch || $scope.password_needed || $scope.has_other_prompts || $scope.survey_enabled) ? "NEXT" : "LAUNCH";
|
||||
return ($scope.ask_credential_on_launch || $scope.ask_extra_credentials_on_launch || $scope.password_needed || $scope.has_other_prompts || $scope.survey_enabled) ? "NEXT" : "LAUNCH";
|
||||
}
|
||||
else if($scope.step === "credential") {
|
||||
return ($scope.has_other_prompts || $scope.survey_enabled) ? "NEXT" : "LAUNCH";
|
||||
@ -377,7 +395,7 @@ export default
|
||||
}
|
||||
}
|
||||
else if($scope.step === "credential") {
|
||||
if($scope.selected_credential && $scope.forms.credentialpasswords && $scope.forms.credentialpasswords.$valid) {
|
||||
if($scope.selected_credentials.machine && $scope.forms.credentialpasswords && $scope.forms.credentialpasswords.$valid) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
@ -409,7 +427,7 @@ export default
|
||||
$scope.takeAction = function() {
|
||||
if($scope.step === "inventory") {
|
||||
// Check to see if there's another step after this one
|
||||
if($scope.ask_credential_on_launch || $scope.password_needed) {
|
||||
if($scope.ask_credential_on_launch || $scope.ask_extra_credentials_on_launch || $scope.password_needed) {
|
||||
$scope.setStep("credential");
|
||||
}
|
||||
else if($scope.has_other_prompts) {
|
||||
@ -456,14 +474,57 @@ export default
|
||||
$scope.parseTypeChange('parseType', 'jobLaunchVariables');
|
||||
};
|
||||
|
||||
$scope.showRevertCredentials = function(){
|
||||
let machineCredentialMatches = true;
|
||||
let extraCredentialsMatch = true;
|
||||
|
||||
if($scope.defaults.credential && $scope.defaults.credential.id) {
|
||||
if(!$scope.selected_credentials.machine || ($scope.selected_credentials.machine && $scope.selected_credentials.machine.id !== $scope.defaults.credential.id)) {
|
||||
machineCredentialMatches = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if($scope.selected_credentials.machine && $scope.selected_credentials.machine.id) {
|
||||
machineCredentialMatches = false;
|
||||
}
|
||||
}
|
||||
|
||||
if($scope.defaults.extra_credentials && $scope.defaults.extra_credentials.length > 0) {
|
||||
if($scope.selected_credentials.extra && $scope.selected_credentials.extra.length > 0) {
|
||||
if($scope.defaults.extra_credentials.length !== $scope.selected_credentials.extra.length) {
|
||||
extraCredentialsMatch = false;
|
||||
}
|
||||
else {
|
||||
$scope.defaults.extra_credentials.forEach((defaultExtraCredential) =>{
|
||||
let matchesSelected = false;
|
||||
$scope.selected_credentials.extra.forEach((selectedExtraCredential) =>{
|
||||
if(defaultExtraCredential.id === selectedExtraCredential.id) {
|
||||
matchesSelected = true;
|
||||
}
|
||||
});
|
||||
if(!matchesSelected) {
|
||||
extraCredentialsMatch = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
extraCredentialsMatch = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if($scope.selected_credentials.extra && $scope.selected_credentials.extra.length > 0) {
|
||||
extraCredentialsMatch = false;
|
||||
}
|
||||
}
|
||||
|
||||
return machineCredentialMatches && extraCredentialsMatch ? false : true;
|
||||
};
|
||||
|
||||
$scope.$on('inventorySelected', function(evt, selectedRow){
|
||||
$scope.selected_inventory = _.cloneDeep(selectedRow);
|
||||
});
|
||||
|
||||
$scope.$on('credentialSelected', function(evt, selectedRow){
|
||||
$scope.selected_credential = _.cloneDeep(selectedRow);
|
||||
updateRequiredPasswords();
|
||||
});
|
||||
|
||||
}
|
||||
];
|
||||
|
@ -6,8 +6,8 @@
|
||||
|
||||
import jobSubmissionController from './job-submission.controller';
|
||||
|
||||
export default [ 'templateUrl', 'CreateDialog', 'Wait', 'CreateSelect2', 'ParseTypeChange',
|
||||
function(templateUrl, CreateDialog, Wait, CreateSelect2, ParseTypeChange) {
|
||||
export default [ 'templateUrl', 'CreateDialog', 'Wait', 'CreateSelect2', 'ParseTypeChange', 'GetSurveyQuestions',
|
||||
function(templateUrl, CreateDialog, Wait, CreateSelect2, ParseTypeChange, GetSurveyQuestions) {
|
||||
return {
|
||||
scope: {
|
||||
submitJobId: '=',
|
||||
@ -25,7 +25,22 @@ export default [ 'templateUrl', 'CreateDialog', 'Wait', 'CreateSelect2', 'ParseT
|
||||
}
|
||||
scope.removeLaunchJobModalReady = scope.$on('LaunchJobModalReady', function() {
|
||||
// Go get the list/survey data that we need from the server
|
||||
scope.getListsAndSurvey();
|
||||
if(scope.ask_inventory_on_launch) {
|
||||
scope.includeInventoryList = true;
|
||||
}
|
||||
if(scope.ask_credential_on_launch || scope.ask_extra_credentials_on_launch) {
|
||||
scope.credentialKind = (scope.ask_credential_on_launch) ? "1" : "5";
|
||||
|
||||
scope.includeCredentialList = true;
|
||||
}
|
||||
if(scope.survey_enabled) {
|
||||
GetSurveyQuestions({
|
||||
scope: scope,
|
||||
id: scope.submitJobId,
|
||||
submitJobType: scope.submitJobType
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
$('#job-launch-modal').dialog('open');
|
||||
|
||||
|
@ -1,8 +1,12 @@
|
||||
<div id="job-launch-modal" class="JobSubmission">
|
||||
<div id="job-launch-modal" class="JobSubmission modal">
|
||||
<div class="JobSubmission-container">
|
||||
<div class="JobSubmission-header">
|
||||
<div class="JobSubmission-title">
|
||||
<div class="JobSubmission-titleText">LAUNCH JOB<div class="JobSubmission-titleLockup"></div>{{job_template_data.name || workflow_job_template_data.name}}</div>
|
||||
<div class="JobSubmission-titleText">
|
||||
<span translate>LAUNCH JOB</span>
|
||||
<div class="JobSubmission-titleLockup"></div>
|
||||
<span>{{job_template_data.name || workflow_job_template_data.name}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="JobSubmission-close">
|
||||
<button class="JobSubmission-exit" ng-click="clearDialog()"><i class="fa fa-times-circle"></i></button>
|
||||
@ -10,10 +14,10 @@
|
||||
</div>
|
||||
<div class="JobSubmission-stepsContainer">
|
||||
<div class="JobSubmission-steps">
|
||||
<div class="JobSubmission-step" ng-class="{'JobSubmission-step--active': step==='inventory'}" ng-if="ask_inventory_on_launch" ng-click="setStep('inventory')">Inventory</div>
|
||||
<div class="JobSubmission-step" ng-class="{'JobSubmission-step--active': step==='credential', 'JobSubmission-step--disabled': !credentialTabEnabled}" ng-if="ask_credential_on_launch || password_needed" ng-click="!credentialTabEnabled || setStep('credential')">Credential</div>
|
||||
<div class="JobSubmission-step" ng-class="{'JobSubmission-step--active': step==='otherprompts', 'JobSubmission-step--disabled': !otherPromptsTabEnabled}" ng-if="has_other_prompts" ng-click="!otherPromptsTabEnabled || setStep('otherprompts')">Other Prompts</div>
|
||||
<div class="JobSubmission-step" ng-class="{'JobSubmission-step--active': step==='survey', 'JobSubmission-step--disabled': !surveyTabEnabled}" ng-if="survey_enabled" ng-click="!surveyTabEnabled || setStep('survey')">Survey</div>
|
||||
<div class="JobSubmission-step" ng-class="{'JobSubmission-step--active': step==='inventory'}" ng-if="ask_inventory_on_launch" ng-click="setStep('inventory')" translate>Inventory</div>
|
||||
<div class="JobSubmission-step" ng-class="{'JobSubmission-step--active': step==='credential', 'JobSubmission-step--disabled': !credentialTabEnabled}" ng-if="ask_credential_on_launch || ask_extra_credentials_on_launch || password_needed" ng-click="!credentialTabEnabled || setStep('credential')" translate>Credential</div>
|
||||
<div class="JobSubmission-step" ng-class="{'JobSubmission-step--active': step==='otherprompts', 'JobSubmission-step--disabled': !otherPromptsTabEnabled}" ng-if="has_other_prompts" ng-click="!otherPromptsTabEnabled || setStep('otherprompts')" translate>Other Prompts</div>
|
||||
<div class="JobSubmission-step" ng-class="{'JobSubmission-step--active': step==='survey', 'JobSubmission-step--disabled': !surveyTabEnabled}" ng-if="survey_enabled" ng-click="!surveyTabEnabled || setStep('survey')" translate>Survey</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="JobSubmission-formContainer">
|
||||
@ -21,83 +25,100 @@
|
||||
<div class="JobSubmission-selectedItemContainer">
|
||||
<div class="JobSubmission-selectedItem">
|
||||
<div class="JobSubmission-selectedItemInfo">
|
||||
<span class="JobSubmission-selectedItemLabel">SELECTED INVENTORY:</span>
|
||||
<span class="JobSubmission-label" translate>SELECTED INVENTORY:</span>
|
||||
<span ng-show="selected_inventory" ng-bind="selected_inventory.name"></span>
|
||||
<span class="JobSubmission-selectedItemNone" ng-show="!selected_inventory">None selected</span>
|
||||
<span class="JobSubmission-selectedItemNone" ng-show="!selected_inventory" translate>None selected</span>
|
||||
</div>
|
||||
<div class="JobSubmission-selectedItemRevert" ng-if="ask_inventory_on_launch && has_default_inventory">
|
||||
<a class="Form-labelAction JobSubmission-revertLink" href="" ng-hide="selected_inventory.id === defaults.inventory.id" ng-click="revertToDefaultInventory()">REVERT</a>
|
||||
<a class="Form-labelAction JobSubmission-revertLink" href="" ng-hide="selected_inventory.id === defaults.inventory.id" ng-click="revertToDefaultInventory()" translate>REVERT</a>
|
||||
</div>
|
||||
</div>
|
||||
<job-sub-inv-list ng-if="includeInventoryList" selected-inventory="$parent.selected_inventory"></job-sub-inv-list>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-if="ask_credential_on_launch || password_needed" ng-show="step === 'credential'" class="JobSubmission-form">
|
||||
<div ng-if="ask_credential_on_launch || ask_extra_credentials_on_launch || password_needed" ng-show="step === 'credential'" class="JobSubmission-form">
|
||||
<div class="JobSubmission-selectedItemContainer">
|
||||
<div class="JobSubmission-selectedItem">
|
||||
<div class="JobSubmission-selectedItemInfo">
|
||||
<span class="JobSubmission-selectedItemLabel">SELECTED CREDENTIAL:</span>
|
||||
<span ng-show="selected_inventory" ng-bind="selected_credential.name"></span>
|
||||
<span class="JobSubmission-selectedItemNone" ng-show="!selected_credential">None selected</span>
|
||||
</div>
|
||||
<div class="JobSubmission-selectedItemRevert" ng-if="ask_credential_on_launch && has_default_credential">
|
||||
<a class="Form-labelAction JobSubmission-revertLink" href="" ng-hide="selected_credential.id === defaults.credential.id" ng-click="revertToDefaultCredential()">REVERT</a>
|
||||
<div class="JobSubmission-selectedItemLabel">
|
||||
<span class="JobSubmission-label" translate>SELECTED CREDENTIAL</span>
|
||||
</div>
|
||||
<div>
|
||||
<span ng-show="selected_credentials.machine" class="JobSubmission-selectedItemInfoSubTitle"><span translate>Machine:</span> </span>
|
||||
<span ng-show="selected_credentials.machine">{{selected_credentials.machine.name}}</span>
|
||||
<span ng-show="selected_credentials.machine && selected_credentials.extra.length > 0">, </span>
|
||||
<span ng-repeat="extraCredential in selected_credentials.extra">
|
||||
<span class="JobSubmission-previewItemSubTitle">{{credential_types[extraCredential.credential_type].name}}: </span>
|
||||
<span>{{extraCredential.name}}{{$last ? '' : ', '}}</span>
|
||||
</span>
|
||||
<span class="JobSubmission-selectedItemNone" ng-show="!selected_credentials.machine && selected_credentials.extra.length === 0" translate>None selected</span>
|
||||
<span ng-if="ask_credential_on_launch || ask_extra_credentials_on_launch">
|
||||
<a class="JobSubmission-revertLink" href="" ng-show="showRevertCredentials()" ng-click="revertToDefaultCredentials()" translate>REVERT</a>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<job-sub-cred-list ng-if="includeCredentialList" selected-credential="$parent.selected_credential"></job-sub-cred-list>
|
||||
<div class="JobSubmission-credentialSubSection" ng-show="ask_extra_credentials_on_launch">
|
||||
<span class="JobSubmission-label" translate>CREDENTIAL TYPE:</span>
|
||||
<select ng-model="credentialKind">
|
||||
<option ng-repeat="option in credentialKindOptions" value="{{option.value}}">{{option.name}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<job-sub-cred-list ng-if="includeCredentialList" selected-credentials="selected_credentials" credential-types="::credential_types" credential-kind="credentialKind"></job-sub-cred-list>
|
||||
<div ng-show="ssh_password_required || ssh_key_unlock_required || become_password_required || vault_password_required">
|
||||
<div class="JobSubmission-instructions">Launching this job requires the passwords listed below. Enter and confirm each password before continuing.</div>
|
||||
<div class="JobSubmission-instructions" translate>Launching this job requires the passwords listed below. Enter and confirm each password before continuing.</div>
|
||||
<form name="forms.credentialpasswords" autocomplete="off" novalidate>
|
||||
<div class="form-group Form-formGroup Form-formGroup--singleColumn" ng-if="ssh_password_required">
|
||||
<label for="ssh_password">
|
||||
<span class="Form-inputLabel prepend-asterisk"> Password</span>
|
||||
<span class="Form-inputLabel prepend-asterisk" translate> Password</span>
|
||||
</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn">
|
||||
<button type="button" class="btn btn-default show_input_button JobSubmission-passwordButton" id="job-submission-ssh-password_show_input_button" aw-tool-tip="Toggle the display of plaintext." aw-tip-placement="top" ng-click="togglePassword('#job-submission-ssh-password')" data-original-title="" title="">Show</button>
|
||||
<button type="button" class="btn btn-default show_input_button JobSubmission-passwordButton" id="job-submission-ssh-password_show_input_button" aw-tool-tip="Toggle the display of plaintext." aw-tip-placement="top" ng-click="togglePassword('#job-submission-ssh-password')" data-original-title="" title="" translate>Show</button>
|
||||
</span>
|
||||
<input id="job-submission-ssh-password" type="password" ng-model="passwords.ssh_password" name="ssh_password" class="password-field form-control input-sm Form-textInput" required>
|
||||
</div>
|
||||
<div class="error" ng-show="forms.credentialpasswords.ssh_password.$dirty && forms.credentialpasswords.ssh_password.$error.required">Please enter a password.</div>
|
||||
<div class="error" ng-show="forms.credentialpasswords.ssh_password.$dirty && forms.credentialpasswords.ssh_password.$error.required" translate>Please enter a password.</div>
|
||||
<div class="error api-error" ng-bind="ssh_password_api_error"></div>
|
||||
</div>
|
||||
<div class="form-group Form-formGroup Form-formGroup--singleColumn" ng-if="ssh_key_unlock_required">
|
||||
<label for="ssh_key_unlock">
|
||||
<span class="Form-inputLabel prepend-asterisk"> Private Key Passphrase</span>
|
||||
<span class="Form-inputLabel prepend-asterisk" translate> Private Key Passphrase</span>
|
||||
</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn">
|
||||
<button type="button" class="btn btn-default show_input_button JobSubmission-passwordButton" id="job-submission-ssh-key-unlock_show_input_button" aw-tool-tip="Toggle the display of plaintext." aw-tip-placement="top" ng-click="togglePassword('#job-submission-ssh-key-unlock')" data-original-title="" title="">Show</button>
|
||||
<button type="button" class="btn btn-default show_input_button JobSubmission-passwordButton" id="job-submission-ssh-key-unlock_show_input_button" aw-tool-tip="Toggle the display of plaintext." aw-tip-placement="top" ng-click="togglePassword('#job-submission-ssh-key-unlock')" data-original-title="" title="" translate>Show</button>
|
||||
</span>
|
||||
<input id="job-submission-ssh-key-unlock" type="password" ng-model="passwords.ssh_key_unlock" name="ssh_key_unlock" class="password-field form-control input-sm Form-textInput" required>
|
||||
</div>
|
||||
<div class="error" ng-show="forms.credentialpasswords.ssh_key_unlock.$dirty && forms.credentialpasswords.ssh_key_unlock.$error.required">Please enter a password.</div>
|
||||
<div class="error" ng-show="forms.credentialpasswords.ssh_key_unlock.$dirty && forms.credentialpasswords.ssh_key_unlock.$error.required" translate>Please enter a password.</div>
|
||||
<div class="error api-error" ng-bind="ssh_key_unlock_api_error"></div>
|
||||
</div>
|
||||
<div class="form-group Form-formGroup Form-formGroup--singleColumn" ng-if="become_password_required">
|
||||
<label for="become_password">
|
||||
<span class="Form-inputLabel prepend-asterisk"> Privilege Escalation Password</span>
|
||||
<span class="Form-inputLabel prepend-asterisk" translate> Privilege Escalation Password</span>
|
||||
</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn">
|
||||
<button type="button" class="btn btn-default show_input_button JobSubmission-passwordButton" id="job-submission-become-password_show_input_button" aw-tool-tip="Toggle the display of plaintext." aw-tip-placement="top" ng-click="togglePassword('#job-submission-become-password')" data-original-title="" title="">Show</button>
|
||||
<button type="button" class="btn btn-default show_input_button JobSubmission-passwordButton" id="job-submission-become-password_show_input_button" aw-tool-tip="Toggle the display of plaintext." aw-tip-placement="top" ng-click="togglePassword('#job-submission-become-password')" data-original-title="" title="" translate>Show</button>
|
||||
</span>
|
||||
<input id="job-submission-become-password" type="password" ng-model="passwords.become_password" name="become_password" class="password-field form-control input-sm Form-textInput" required>
|
||||
</div>
|
||||
<div class="error" ng-show="forms.credentialpasswords.become_password.$dirty && forms.credentialpasswords.become_password.$error.required">Please enter a password.</div>
|
||||
<div class="error" ng-show="forms.credentialpasswords.become_password.$dirty && forms.credentialpasswords.become_password.$error.required" translate>Please enter a password.</div>
|
||||
<div class="error api-error" ng-bind="become_password_api_error"></div>
|
||||
</div>
|
||||
<div class="form-group Form-formGroup Form-formGroup--singleColumn" ng-if="vault_password_required">
|
||||
<label for="vault_password">
|
||||
<span class="Form-inputLabel prepend-asterisk"> Vault Password</span>
|
||||
<span class="Form-inputLabel prepend-asterisk" translate> Vault Password</span>
|
||||
</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn">
|
||||
<button type="button" class="btn btn-default show_input_button JobSubmission-passwordButton" id="job-submission-vault-password_show_input_button" aw-tool-tip="Toggle the display of plaintext." aw-tip-placement="top" ng-click="togglePassword('#job-submission-vault-password')" data-original-title="" title="">Show</button>
|
||||
<button type="button" class="btn btn-default show_input_button JobSubmission-passwordButton" id="job-submission-vault-password_show_input_button" aw-tool-tip="Toggle the display of plaintext." aw-tip-placement="top" ng-click="togglePassword('#job-submission-vault-password')" data-original-title="" title="" translate>Show</button>
|
||||
</span>
|
||||
<input id="job-submission-vault-password" type="password" ng-model="passwords.vault_password" name="vault_password" class="password-field form-control input-sm Form-textInput" required>
|
||||
</div>
|
||||
<div class="error" ng-show="forms.credentialpasswords.vault_password.$dirty && forms.credentialpasswords.vault_password.$error.required">Please enter a password.</div>
|
||||
<div class="error" ng-show="forms.credentialpasswords.vault_password.$dirty && forms.credentialpasswords.vault_password.$error.required" translate>Please enter a password.</div>
|
||||
<div class="error api-error" ng-bind="vault_password_api_error"></div>
|
||||
</div>
|
||||
</form>
|
||||
@ -108,15 +129,15 @@
|
||||
<form name="forms.otherprompts" autocomplete="off" novalidate>
|
||||
<div class="form-group Form-formGroup Form-formGroup--singleColumn" ng-if="ask_variables_on_launch">
|
||||
<label for="variables">
|
||||
<span class="Form-inputLabel">Extra Variables</span>
|
||||
<span class="Form-inputLabel" translate>Extra Variables</span>
|
||||
<a id="awp-variables" href="" aw-pop-over="<p>Pass extra command line variables to the playbook. This is the -e or --extra-vars command line parameter for ansible-playbook. Provide key/value pairs using either YAML or JSON.</p>JSON:<br /><blockquote>{<br />"somevar": "somevalue",<br />"password": "magic"<br /> }</blockquote>YAML:<br /><blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>" data-placement="right" data-container="body" over-title="Extra Variables" class="help-link" data-original-title="" title="" tabindex="-1">
|
||||
<i class="fa fa-question-circle"></i>
|
||||
</a>
|
||||
<div class="parse-selection" id="job_launch_variables_parse_type">
|
||||
<input type="radio" ng-model="other_prompt_data.parseType" value="yaml" ng-change="updateParseType()">
|
||||
<span class="parse-label">YAML</span>
|
||||
<span class="parse-label" translate>YAML</span>
|
||||
<input type="radio" ng-model="other_prompt_data.parseType" value="json" ng-change="updateParseType()">
|
||||
<span class="parse-label">JSON</span>
|
||||
<span class="parse-label" translate>JSON</span>
|
||||
</div>
|
||||
</label>
|
||||
<div>
|
||||
@ -125,19 +146,19 @@
|
||||
</div>
|
||||
<div class="form-group Form-formGroup Form-formGroup--singleColumn" ng-if="ask_job_type_on_launch">
|
||||
<label for="job_type">
|
||||
<span class="Form-inputLabel prepend-asterisk"> Job Type</span>
|
||||
<span class="Form-inputLabel prepend-asterisk" translate> Job Type</span>
|
||||
</label>
|
||||
<div>
|
||||
<select ng-model="other_prompt_data.job_type" name="job_type" class="form-control Form-dropDown" id="job_launch_job_type" tabindex="-1" aria-hidden="true" required>
|
||||
<option value="" class="" selected="selected">Choose a job type</option>
|
||||
<option label="Run" value="run" selected="selected">Run</option>
|
||||
<option label="Check" value="check">Check</option>
|
||||
<option value="" class="" selected="selected" translate>Choose a job type</option>
|
||||
<option label="Run" value="run" selected="selected" translate>Run</option>
|
||||
<option label="Check" value="check" translate>Check</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group Form-formGroup Form-formGroup--singleColumn" ng-if="ask_limit_on_launch">
|
||||
<label for="limit">
|
||||
<span class="Form-inputLabel">Limit</span>
|
||||
<span class="Form-inputLabel" translate>Limit</span>
|
||||
</label>
|
||||
<div>
|
||||
<input type="text" ng-model="other_prompt_data.limit" name="limit" class="form-control Form-textInput">
|
||||
@ -145,7 +166,7 @@
|
||||
</div>
|
||||
<div class="form-group Form-formGroup Form-formGroup--singleColumn" ng-if="ask_tags_on_launch">
|
||||
<label for="tags">
|
||||
<span class="Form-inputLabel">Job Tags</span>
|
||||
<span class="Form-inputLabel" translate>Job Tags</span>
|
||||
</label>
|
||||
<div>
|
||||
<textarea rows="5" ng-model="other_prompt_data.job_tags" name="tags" class="form-control Form-textArea Form-textInput"></textarea>
|
||||
@ -153,7 +174,7 @@
|
||||
</div>
|
||||
<div class="form-group Form-formGroup Form-formGroup--singleColumn" ng-if="ask_skip_tags_on_launch">
|
||||
<label for="skip_tags">
|
||||
<span class="Form-inputLabel">Skip Tags</span>
|
||||
<span class="Form-inputLabel" translate>Skip Tags</span>
|
||||
</label>
|
||||
<div>
|
||||
<textarea rows="5" ng-model="other_prompt_data.skip_tags" name="skip_tags" class="form-control Form-textArea Form-textInput"></textarea>
|
||||
@ -173,36 +194,36 @@
|
||||
</div>
|
||||
<div ng-if="question.type === 'text'">
|
||||
<input type="text" id="survey_question_{{$index}}" ng-model="question.model" name="survey_question_{{$index}}" ng-minlength="question.minlength" ng-maxlength="question.maxlength" class="form-control Form-textInput" ng-required="question.required">
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$dirty && forms.survey.survey_question_{{$index}}.$error.required">Please enter an answer.</div>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$error.minlength || forms.survey.survey_question_{{$index}}.$error.maxlength">Please enter an answer between {{question.minlength}} to {{question.maxlength}} characters long.</div>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$dirty && forms.survey.survey_question_{{$index}}.$error.required" translate>Please enter an answer.</div>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$error.minlength || forms.survey.survey_question_{{$index}}.$error.maxlength"><span translate>Please enter an answer between</span> {{question.minlength}} <span translate>to</span> {{question.maxlength}} <span translate>characters long.</span></div>
|
||||
</div>
|
||||
<div ng-if="question.type === 'textarea'">
|
||||
<textarea id="survey_question_{{$index}}" name="survey_question_{{$index}}" ng-model="question.model" ng-minlength="question.minlength" ng-maxlength="question.maxlength" class="form-control final Form-textArea" ng-required="question.required" rows="3"></textarea>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$dirty && forms.survey.survey_question_{{$index}}.$error.required">Please enter an answer.</div>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$error.minlength || forms.survey.survey_question_{{$index}}.$error.maxlength">Please enter an answer between {{question.minlength}} to {{question.maxlength}} characters long.</div>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$dirty && forms.survey.survey_question_{{$index}}.$error.required" translate>Please enter an answer.</div>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$error.minlength || forms.survey.survey_question_{{$index}}.$error.maxlength"><span translate>Please enter an answer between</span> {{question.minlength}} <span translate>to</span> {{question.maxlength}} <span translate>characters long.</span></div>
|
||||
</div>
|
||||
<div ng-if="question.type === 'password'">
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn">
|
||||
<button type="button" class="btn btn-default show_input_button JobSubmission-passwordButton" id="survey_question_{{$index}}_show_input_button" aw-tool-tip="Toggle the display of plaintext." aw-tip-placement="top" ng-click="togglePassword('#survey_question_' + $index)" data-original-title="" title="">Show</button>
|
||||
<button type="button" class="btn btn-default show_input_button JobSubmission-passwordButton" id="survey_question_{{$index}}_show_input_button" aw-tool-tip="Toggle the display of plaintext." aw-tip-placement="top" ng-click="togglePassword('#survey_question_' + $index)" data-original-title="" title="" translate>Show</button>
|
||||
</span>
|
||||
<input id="survey_question_{{$index}}" ng-if="!question.default" type="password" ng-model="question.model" name="survey_question_{{$index}}" ng-required="question.required" ng-minlength="question.minlength" ng-maxlength="question.maxlength" class="form-control Form-textInput" autocomplete="false">
|
||||
<input id="survey_question_{{$index}}" ng-if="question.default" type="password" ng-model="question.model" name="survey_question_{{$index}}" ng-required="question.required" aw-password-min="question.minlength" aw-password-max="question.maxlength" class="form-control Form-textInput" autocomplete="false">
|
||||
</div>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$dirty && forms.survey.survey_question_{{$index}}.$error.required">Please enter an answer.</div>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$error.awPasswordMin || forms.survey.survey_question_{{$index}}.$error.awPasswordMax || forms.survey.survey_question_{{$index}}.$error.minlength || forms.survey.survey_question_{{$index}}.$error.maxlength">Please enter an answer between {{question.minlength}} to {{question.maxlength}} characters long.</div>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$dirty && forms.survey.survey_question_{{$index}}.$error.required" translate>Please enter an answer.</div>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$error.awPasswordMin || forms.survey.survey_question_{{$index}}.$error.awPasswordMax || forms.survey.survey_question_{{$index}}.$error.minlength || forms.survey.survey_question_{{$index}}.$error.maxlength"><span translate>Please enter an answer between</span> {{question.minlength}} <span translate>to</span> {{question.maxlength}} <span translate>characters long.</span></div>
|
||||
</div>
|
||||
<div ng-if="question.type === 'integer'">
|
||||
<input type="number" id="survey_question_{{$index}}" ng-model="question.model" class="form-control Form-textInput" name="survey_question_{{$index}}" ng-required="question.required" integer aw-min="question.minValue" aw-max="question.maxValue"/>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$dirty && forms.survey.survey_question_{{$index}}.$error.required">Please enter an answer.</div>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$error.number || forms.survey.survey_question_{{$index}}.$error.integer" >Please enter an answer that is a valid integer.</div>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$error.awMin || forms.survey.survey_question_{{$index}}.$error.awMax">Please enter an answer between {{question.minValue}} and {{question.maxValue}}.</div>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$dirty && forms.survey.survey_question_{{$index}}.$error.required" translate>Please enter an answer.</div>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$error.number || forms.survey.survey_question_{{$index}}.$error.integer" translate>Please enter an answer that is a valid integer.</div>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$error.awMin || forms.survey.survey_question_{{$index}}.$error.awMax"><span translate>Please enter an answer between</span> {{question.minValue}} <span>and</span> {{question.maxValue}}.</div>
|
||||
</div>
|
||||
<div ng-if="question.type === 'float'">
|
||||
<input type="number" id="survey_question_{{$index}}" ng-model="question.model" class="form-control Form-textInput" name="survey_question_{{$index}}" ng-required="question.required" smart-float aw-min="question.minValue" aw-max="question.maxValue"/>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$dirty && forms.survey.survey_question_{{$index}}.$error.required">Please enter an answer.</div>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$error.number || forms.survey.survey_question_{{$index}}.$error.float">Please enter an answer that is a decimal number.</div>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$error.awMin || forms.survey.survey_question_{{$index}}.$error.awMax">Please enter an answer between {{question.minValue}} and {{question.maxValue}}.</div>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$dirty && forms.survey.survey_question_{{$index}}.$error.required" translate>Please enter an answer.</div>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$error.number || forms.survey.survey_question_{{$index}}.$error.float" translate>Please enter an answer that is a decimal number.</div>
|
||||
<div class="error survey_error" ng-show="forms.survey.survey_question_{{$index}}.$error.awMin || forms.survey.survey_question_{{$index}}.$error.awMax"><span translate>Please enter an answer between</span> {{question.minValue}} <span translate>and</span> {{question.maxValue}}.</div>
|
||||
</div>
|
||||
<div ng-if="question.type === 'multiplechoice'">
|
||||
<div class="survey_taker_input">
|
||||
@ -231,18 +252,27 @@
|
||||
<div class="JobSubmission-footerContainer">
|
||||
<div class="JobSubmission-footerPreview">
|
||||
<div class="JobSubmission-previewItem" ng-show="submitJobType === 'job_template'">
|
||||
<div class="JobSubmission-previewItemTitle">INVENTORY</div>
|
||||
<div class="JobSubmission-previewItemTitle" translate>INVENTORY</div>
|
||||
<div ng-show="selected_inventory" ng-bind="selected_inventory.name"></div>
|
||||
<div class="JobSubmission-previewItemNone" ng-show="!selected_inventory">None selected</div>
|
||||
<div class="JobSubmission-previewItemNone" ng-show="!selected_inventory" translate>None selected</div>
|
||||
</div>
|
||||
<div class="JobSubmission-previewItem" ng-show="submitJobType === 'job_template'">
|
||||
<div class="JobSubmission-previewItemTitle">CREDENTIAL</div>
|
||||
<div ng-show="selected_credential" ng-bind="selected_credential.name"></div>
|
||||
<div class="JobSubmission-previewItemNone" ng-show="!selected_credential">None selected</div>
|
||||
<div class="JobSubmission-previewItemTitle" translate>CREDENTIAL</div>
|
||||
<div>
|
||||
<span ng-show="!selected_credentials.machine && selected_credentials.extra.length === 0" class="JobSubmission-selectedItemNone" translate>None selected</span>
|
||||
</div>
|
||||
<div>
|
||||
<span ng-show="selected_credentials.machine" class="JobSubmission-previewItemSubTitle"><span translate>Machine</span>: </span>
|
||||
<span ng-show="selected_credentials.machine">{{selected_credentials.machine.name}}</span>
|
||||
</div>
|
||||
<div ng-repeat="extraCredential in selected_credentials.extra">
|
||||
<span class="JobSubmission-previewItemSubTitle">{{credential_types[extraCredential.credential_type].name}}: </span>
|
||||
<span>{{extraCredential.name}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="JobSubmission-footerButtons">
|
||||
<button id="job-submission-close-button" class="btn btn-sm JobSubmission-defaultButton" ng-click="clearDialog()">CANCEL</button>
|
||||
<button id="job-submission-close-button" class="btn btn-sm JobSubmission-defaultButton" ng-click="clearDialog()" translate>CANCEL</button>
|
||||
<button id="job-submission-action-button" class="btn btn-sm JobSubmission-actionButton" ng-click="takeAction()" ng-disabled="actionButtonDisabled()">{{getActionButtonText()}}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -5,28 +5,131 @@
|
||||
*************************************************/
|
||||
|
||||
export default
|
||||
[ '$scope',
|
||||
function($scope) {
|
||||
$scope.toggle_row = function(rowId) {
|
||||
let list = $scope.list;
|
||||
let count = 0;
|
||||
$scope[list.name].forEach(function(row) {
|
||||
if (row.id === rowId) {
|
||||
if (row.checked) {
|
||||
row.success_class = 'success';
|
||||
} else {
|
||||
row.checked = true;
|
||||
row.success_class = '';
|
||||
[ '$scope', 'CredentialList', 'i18n', 'QuerySet', 'GetBasePath',
|
||||
function($scope, CredentialList, i18n, qs, GetBasePath) {
|
||||
|
||||
let updateExtraCredentialsList = function() {
|
||||
$scope.credentials.forEach((row, i) => {
|
||||
$scope.credentials[i].checked = 0;
|
||||
$scope.selectedCredentials.extra.forEach((extraCredential, j) => {
|
||||
if (row.id === $scope.selectedCredentials.extra[j].id) {
|
||||
$scope.credentials[i].checked = 1;
|
||||
}
|
||||
$scope.$emit('credentialSelected', row);
|
||||
} else {
|
||||
row.checked = 0;
|
||||
row.success_class = '';
|
||||
}
|
||||
if (row.checked) {
|
||||
count++;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
let updateMachineCredentialList = function() {
|
||||
$scope.credentials.forEach((row, i) => {
|
||||
$scope.credentials[i].checked = 0;
|
||||
if (row.id === $scope.selectedCredentials.machine.id) {
|
||||
$scope.credentials[i].checked = 1;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
let uncheckAllCredentials = function() {
|
||||
$scope.credentials.forEach((row, i) => {
|
||||
$scope.credentials[i].checked = 0;
|
||||
});
|
||||
};
|
||||
|
||||
let init = function() {
|
||||
$scope.credential_dataset = [];
|
||||
$scope.credentials = [];
|
||||
$scope.listRendered = false;
|
||||
|
||||
let credList = _.cloneDeep(CredentialList);
|
||||
credList.emptyListText = i18n._('No Credentials Matching This Type Have Been Created');
|
||||
$scope.list = credList;
|
||||
|
||||
$scope.credential_default_params = {
|
||||
order_by: 'name',
|
||||
page_size: 5
|
||||
};
|
||||
|
||||
$scope.credential_queryset = {
|
||||
order_by: 'name',
|
||||
page_size: 5
|
||||
};
|
||||
|
||||
$scope.$watch('credentialKind', function(){
|
||||
$scope.credential_default_params.credential_type = $scope.credential_queryset.credential_type = parseInt($scope.credentialKind);
|
||||
|
||||
qs.search(GetBasePath('credentials'), $scope.credential_default_params)
|
||||
.then(res => {
|
||||
$scope.credential_dataset = res.data;
|
||||
$scope.credentials = $scope.credential_dataset.results;
|
||||
if(!$scope.listRendered) {
|
||||
$scope.generateCredentialList();
|
||||
$scope.listRendered = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$scope.$watchCollection('selectedCredentials.extra', () => {
|
||||
if($scope.credentials && $scope.credentials.length > 0) {
|
||||
if($scope.selectedCredentials.extra && $scope.selectedCredentials.extra.length > 0 && parseInt($scope.credentialKind) !== 1) {
|
||||
updateExtraCredentialsList();
|
||||
}
|
||||
else {
|
||||
uncheckAllCredentials();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$watch('selectedCredentials.machine', () => {
|
||||
if($scope.credentials && $scope.credentials.length > 0) {
|
||||
if($scope.selectedCredentials.machine && parseInt($scope.credentialKind) === 1) {
|
||||
updateMachineCredentialList();
|
||||
}
|
||||
else {
|
||||
uncheckAllCredentials();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$watchGroup(['credentials', 'selectedCredentials.machine'], () => {
|
||||
if($scope.credentials && $scope.credentials.length > 0) {
|
||||
if($scope.selectedCredentials.machine && parseInt($scope.credentialKind) === 1) {
|
||||
updateMachineCredentialList();
|
||||
}
|
||||
else if($scope.selectedCredentials.extra && $scope.selectedCredentials.extra.length > 0 && parseInt($scope.credentialKind) !== 1) {
|
||||
updateExtraCredentialsList();
|
||||
}
|
||||
else {
|
||||
uncheckAllCredentials();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.toggle_row = function(selectedRow) {
|
||||
if(parseInt($scope.credentialKind) === 1) {
|
||||
if($scope.selectedCredentials.machine && $scope.selectedCredentials.machine.id === selectedRow.id) {
|
||||
$scope.selectedCredentials.machine = null;
|
||||
}
|
||||
else {
|
||||
$scope.selectedCredentials.machine = _.cloneDeep(selectedRow);
|
||||
}
|
||||
}
|
||||
else {
|
||||
let rowDeselected = false;
|
||||
for (let i = $scope.selectedCredentials.extra.length - 1; i >= 0; i--) {
|
||||
if($scope.selectedCredentials.extra[i].id === selectedRow.id) {
|
||||
$scope.selectedCredentials.extra.splice(i, 1);
|
||||
rowDeselected = true;
|
||||
}
|
||||
else if(selectedRow.credential_type === $scope.selectedCredentials.extra[i].credential_type) {
|
||||
$scope.selectedCredentials.extra.splice(i, 1);
|
||||
}
|
||||
}
|
||||
if(!rowDeselected) {
|
||||
$scope.selectedCredentials.extra.push(_.cloneDeep(selectedRow));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
init();
|
||||
}
|
||||
];
|
||||
|
@ -6,63 +6,26 @@
|
||||
|
||||
import jobSubCredListController from './job-sub-cred-list.controller';
|
||||
|
||||
export default [ 'templateUrl', 'QuerySet', 'GetBasePath', 'generateList', '$compile', 'CredentialList',
|
||||
(templateUrl, qs, GetBasePath, GenerateList, $compile, CredentialList) => {
|
||||
export default [ 'templateUrl', '$compile', 'generateList',
|
||||
(templateUrl, $compile, GenerateList) => {
|
||||
return {
|
||||
scope: {
|
||||
selectedCredential: '='
|
||||
selectedCredentials: '=',
|
||||
credentialKind: '=',
|
||||
credentialTypes: '='
|
||||
},
|
||||
templateUrl: templateUrl('job-submission/lists/credential/job-sub-cred-list'),
|
||||
controller: jobSubCredListController,
|
||||
restrict: 'E',
|
||||
link: scope => {
|
||||
let toDestroy = [];
|
||||
|
||||
scope.credential_default_params = {
|
||||
order_by: 'name',
|
||||
page_size: 5,
|
||||
kind: 'ssh'
|
||||
};
|
||||
|
||||
scope.credential_queryset = {
|
||||
order_by: 'name',
|
||||
page_size: 5,
|
||||
kind: 'ssh'
|
||||
};
|
||||
|
||||
// Fire off the initial search
|
||||
qs.search(GetBasePath('credentials'), scope.credential_default_params)
|
||||
.then(res => {
|
||||
scope.credential_dataset = res.data;
|
||||
scope.credentials = scope.credential_dataset.results;
|
||||
|
||||
let credList = _.cloneDeep(CredentialList);
|
||||
let html = GenerateList.build({
|
||||
list: credList,
|
||||
input_type: 'radio',
|
||||
mode: 'lookup'
|
||||
});
|
||||
|
||||
scope.list = credList;
|
||||
|
||||
$('#job-submission-credential-lookup').append($compile(html)(scope));
|
||||
|
||||
toDestroy.push(scope.$watchCollection('selectedCredential', () => {
|
||||
if(scope.selectedCredential) {
|
||||
// Loop across the inventories and see if one of them should be "checked"
|
||||
scope.credentials.forEach((row, i) => {
|
||||
if (row.id === scope.selectedCredential.id) {
|
||||
scope.credentials[i].checked = 1;
|
||||
}
|
||||
else {
|
||||
scope.credentials[i].checked = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
}));
|
||||
scope.generateCredentialList = function() {
|
||||
let html = GenerateList.build({
|
||||
list: scope.list,
|
||||
input_type: 'radio',
|
||||
mode: 'lookup'
|
||||
});
|
||||
|
||||
scope.$on('$destroy', () => toDestroy.forEach(watcher => watcher()));
|
||||
$('#job-submission-credential-lookup').append($compile(html)(scope));
|
||||
};
|
||||
}
|
||||
};
|
||||
}];
|
||||
|
@ -7,11 +7,11 @@
|
||||
export default
|
||||
[ '$scope',
|
||||
function($scope) {
|
||||
$scope.toggle_row = function(rowId) {
|
||||
$scope.toggle_row = function(selectedRow) {
|
||||
let list = $scope.list;
|
||||
let count = 0;
|
||||
$scope[list.name].forEach(function(row) {
|
||||
if (row.id === rowId) {
|
||||
if (row.id === selectedRow.id) {
|
||||
if (row.checked) {
|
||||
row.success_class = 'success';
|
||||
} else {
|
||||
|
@ -548,7 +548,7 @@ angular.module('GeneratorHelpers', [systemStatus.name])
|
||||
}
|
||||
html += "\" ";
|
||||
html += field.columnNgClass ? " ng-class=\"" + field.columnNgClass + "\"": "";
|
||||
html += (options.mode === 'lookup' || options.mode === 'select') ? " ng-click=\"toggle_row(" + list.iterator + ".id)\"" : "";
|
||||
html += (options.mode === 'lookup' || options.mode === 'select') ? " ng-click=\"toggle_row(" + list.iterator + ")\"" : "";
|
||||
html += (field.columnShow) ? Attr(field, 'columnShow') : "";
|
||||
html += (field.ngBindHtml) ? "ng-bind-html=\"" + field.ngBindHtml + "\" " : "";
|
||||
html += (field.columnClick) ? "ng-click=\"" + field.columnClick + "\" " : "";
|
||||
|
@ -317,7 +317,7 @@ export default ['$compile', 'Attr', 'Icon',
|
||||
// Change layout if a lookup list, place radio buttons before labels
|
||||
if (options.mode === 'lookup') {
|
||||
if (options.input_type === "radio") { //added by JT so that lookup forms can be either radio inputs or check box inputs
|
||||
innerTable += `<td class="List-tableCell"> <input type="radio" ng-model="${list.iterator}.checked" ng-value="1" ng-false-value="0" name="check_${list.iterator}_{{${list.iterator}.id}}" ng-click="toggle_row(${list.iterator}.id)"></td>`;
|
||||
innerTable += `<td class="List-tableCell"> <input type="radio" ng-model="${list.iterator}.checked" ng-value="1" ng-false-value="0" name="check_${list.iterator}_{{${list.iterator}.id}}" ng-click="toggle_row(${list.iterator})"></td>`;
|
||||
}
|
||||
else { // its assumed that options.input_type = checkbox
|
||||
innerTable += "<td class=\"List-tableCell select-column List-staticColumn--smallStatus\"><input type=\"checkbox\" ng-model=\"" + list.iterator + ".checked\" name=\"check_{{" +
|
||||
|
@ -63,11 +63,11 @@ export default ['templateUrl', function(templateUrl) {
|
||||
$state.go('^');
|
||||
};
|
||||
|
||||
$scope.toggle_row = function(rowId) {
|
||||
$scope.toggle_row = function(selectedRow) {
|
||||
let list = $scope.list;
|
||||
let count = 0;
|
||||
$scope[list.name].forEach(function(row) {
|
||||
if (row.id === rowId) {
|
||||
if (row.id === selectedRow.id) {
|
||||
if (row.checked) {
|
||||
row.success_class = 'success';
|
||||
} else {
|
||||
|
@ -210,10 +210,10 @@ angular.module('templates', [surveyMaker.name, templatesList.name, jobTemplatesA
|
||||
});
|
||||
}
|
||||
|
||||
$scope.toggle_row = function(id) {
|
||||
$scope.toggle_row = function(selectedRow) {
|
||||
|
||||
$scope.job_templates.forEach(function(row, i) {
|
||||
if (row.id === id) {
|
||||
if (row.id === selectedRow.id) {
|
||||
$scope.job_templates[i].checked = 1;
|
||||
$scope.selection[list.iterator] = {
|
||||
id: row.id,
|
||||
@ -288,10 +288,10 @@ angular.module('templates', [surveyMaker.name, templatesList.name, jobTemplatesA
|
||||
});
|
||||
}
|
||||
|
||||
$scope.toggle_row = function(id) {
|
||||
$scope.toggle_row = function(selectedRow) {
|
||||
|
||||
$scope.workflow_inventory_sources.forEach(function(row, i) {
|
||||
if (row.id === id) {
|
||||
if (row.id === selectedRow.id) {
|
||||
$scope.workflow_inventory_sources[i].checked = 1;
|
||||
$scope.selection[list.iterator] = {
|
||||
id: row.id,
|
||||
@ -366,10 +366,10 @@ angular.module('templates', [surveyMaker.name, templatesList.name, jobTemplatesA
|
||||
});
|
||||
}
|
||||
|
||||
$scope.toggle_row = function(id) {
|
||||
$scope.toggle_row = function(selectedRow) {
|
||||
|
||||
$scope.projects.forEach(function(row, i) {
|
||||
if (row.id === id) {
|
||||
if (row.id === selectedRow.id) {
|
||||
$scope.projects[i].checked = 1;
|
||||
$scope.selection[list.iterator] = {
|
||||
id: row.id,
|
||||
|
@ -5,7 +5,7 @@ describe('Controller: jobResultsController', () => {
|
||||
// Setup
|
||||
let jobResultsController;
|
||||
|
||||
let jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTypeChange, ParseVariableString, jobResultsService, eventQueue, $compile, eventResolve, populateResolve, $rScope, q, $log, Dataset, Rest, $state, QuerySet, i18n,fieldChoices, fieldLabels, $interval, workflowResultsService, statusSocket;
|
||||
let jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTypeChange, ParseVariableString, jobResultsService, eventQueue, $compile, eventResolve, populateResolve, $rScope, q, $log, Dataset, Rest, $state, QuerySet, i18n,fieldChoices, fieldLabels, $interval, workflowResultsService, statusSocket, jobExtraCredentials;
|
||||
|
||||
statusSocket = function() {
|
||||
var fn = function() {};
|
||||
@ -98,6 +98,7 @@ describe('Controller: jobResultsController', () => {
|
||||
$provide.value('i18n', i18n);
|
||||
$provide.value('fieldChoices', fieldChoices);
|
||||
$provide.value('fieldLabels', fieldLabels);
|
||||
$provide.value('jobExtraCredentials', jobExtraCredentials);
|
||||
});
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user