Workflow edit survey/show survey on launch

This commit is contained in:
Michael Abashian
2016-11-23 16:33:54 -05:00
parent df658e7f65
commit 639eec95e7
22 changed files with 206 additions and 142 deletions

View File

@@ -43,7 +43,7 @@ export default
}; };
scope.launchJobTemplate = function(jobTemplateId){ scope.launchJobTemplate = function(jobTemplateId){
InitiatePlaybookRun({ scope: scope, id: jobTemplateId }); InitiatePlaybookRun({ scope: scope, id: jobTemplateId, job_type: 'job_template' });
}; };
scope.editJobTemplate = function (jobTemplateId) { scope.editJobTemplate = function (jobTemplateId) {

View File

@@ -373,23 +373,6 @@ export default
}, },
buttons: { //for now always generates <button> tags buttons: { //for now always generates <button> tags
add_survey: {
ngClick: 'addSurvey()',
ngShow: 'job_type.value !== "scan" && !survey_exists && (job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)',
awFeature: 'surveys',
awToolTip: 'Surveys allow users to be prompted at job launch with a series of questions related to the job. This allows for variables to be defined that affect the playbook run at time of launch.',
dataPlacement: 'top'
},
edit_survey: {
ngClick: 'editSurvey()',
awFeature: 'surveys',
ngShow: 'job_type.value !== "scan" && survey_exists && (job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
},
view_survey: {
ngClick: 'editSurvey()',
awFeature: 'surveys',
ngShow: 'job_type.value !== "scan" && survey_exists && !(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
},
cancel: { cancel: {
ngClick: 'formCancel()', ngClick: 'formCancel()',
ngShow: '(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)' ngShow: '(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
@@ -459,6 +442,32 @@ export default
} }
}, },
relatedButtons: {
view_survey: {
ngClick: 'editSurvey()',
awFeature: 'surveys',
ngShow: '($state.is(\'templates.addJobTemplate\') || $state.is(\'templates.editJobTemplate\')) && job_type.value !== "scan" && survey_exists && !(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)',
label: i18n._('View Survey'),
class: 'Form-primaryButton'
},
add_survey: {
ngClick: 'addSurvey()',
ngShow: '($state.is(\'templates.addJobTemplate\') || $state.is(\'templates.editJobTemplate\')) && job_type.value !== "scan" && !survey_exists && (job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)',
awFeature: 'surveys',
awToolTip: 'Surveys allow users to be prompted at job launch with a series of questions related to the job. This allows for variables to be defined that affect the playbook run at time of launch.',
dataPlacement: 'top',
label: i18n._('Add Survey'),
class: 'Form-primaryButton'
},
edit_survey: {
ngClick: 'editSurvey()',
awFeature: 'surveys',
ngShow: '($state.is(\'templates.addJobTemplate\') || $state.is(\'templates.editJobTemplate\')) && job_type.value !== "scan" && survey_exists && (job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)',
label: i18n._('Edit Survey'),
class: 'Form-primaryButton'
}
},
relatedSets: function(urls) { relatedSets: function(urls) {
return { return {
completed_jobs: { completed_jobs: {

View File

@@ -26,6 +26,7 @@ export default
activeEditState: 'templates.editWorkflowJobTemplate', activeEditState: 'templates.editWorkflowJobTemplate',
tabs: true, tabs: true,
detailsClick: "$state.go('templates.editWorkflowJobTemplate')", detailsClick: "$state.go('templates.editWorkflowJobTemplate')",
include: ['/static/partials/survey-maker-modal.html'],
fields: { fields: {
name: { name: {
@@ -154,11 +155,18 @@ export default
}, },
relatedButtons: { relatedButtons: {
view_survey: {
ngClick: 'editSurvey()',
awFeature: 'surveys',
ngShow: '($state.is(\'templates.addWorkflowJobTemplate\') || $state.is(\'templates.editWorkflowJobTemplate\')) && survey_exists && !(workflow_job_template_obj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)',
label: i18n._('View Survey'),
class: 'Form-primaryButton'
},
add_survey: { add_survey: {
ngClick: 'addSurvey()', ngClick: 'addSurvey()',
ngShow: '!survey_exists', ngShow: '!survey_exists && ($state.is(\'templates.addWorkflowJobTemplate\') || $state.is(\'templates.editWorkflowJobTemplate\'))',
awFeature: 'surveys', awFeature: 'surveys',
awToolTip: i18n._('Please save before adding a survey'), awToolTip: 'Surveys allow users to be prompted at job launch with a series of questions related to the job. This allows for variables to be defined that affect the playbook run at time of launch.',
dataPlacement: 'top', dataPlacement: 'top',
label: i18n._('Add Survey'), label: i18n._('Add Survey'),
class: 'Form-primaryButton' class: 'Form-primaryButton'
@@ -166,12 +174,13 @@ export default
edit_survey: { edit_survey: {
ngClick: 'editSurvey()', ngClick: 'editSurvey()',
awFeature: 'surveys', awFeature: 'surveys',
ngShow: 'survey_exists', ngShow: 'survey_exists && ($state.is(\'templates.addWorkflowJobTemplate\') || $state.is(\'templates.editWorkflowJobTemplate\'))',
label: i18n._('Edit Survey'), label: i18n._('Edit Survey'),
class: 'Form-primaryButton' class: 'Form-primaryButton'
}, },
workflow_editor: { workflow_editor: {
ngClick: 'openWorkflowMaker()', ngClick: 'openWorkflowMaker()',
ngShow: '$state.is(\'templates.addWorkflowJobTemplate\') || $state.is(\'templates.editWorkflowJobTemplate\')',
awToolTip: i18n._('Please save before defining the workflow graph'), awToolTip: i18n._('Please save before defining the workflow graph'),
dataPlacement: 'top', dataPlacement: 'top',
label: i18n._('Workflow Editor'), label: i18n._('Workflow Editor'),

View File

@@ -156,7 +156,7 @@ angular.module('JobTemplatesHelper', ['Utilities'])
GetBasePath('job_templates') + id + '/callback/'); GetBasePath('job_templates') + id + '/callback/');
master.callback_url = scope.callback_url; master.callback_url = scope.callback_url;
scope.can_edit = data.summary_fields.can_edit; scope.can_edit = data.summary_fields.user_capabilities.edit;
if (scope.project === "" && scope.playbook === "") { if (scope.project === "" && scope.playbook === "") {

View File

@@ -7,8 +7,16 @@ export default
return function(params) { return function(params) {
var id= params.id, var id= params.id,
scope = params.scope, scope = params.scope,
submitJobType = params.submitJobType,
i, i,
survey_url = GetBasePath('job_templates') + id + '/survey_spec/'; survey_url;
if(submitJobType === 'job_template') {
survey_url = GetBasePath('job_templates') + id + '/survey_spec/';
}
else if(submitJobType === 'workflow_job_template') {
survey_url = GetBasePath('workflow_job_templates') + id + '/survey_spec/';
}
Rest.setUrl(survey_url); Rest.setUrl(survey_url);
Rest.get() Rest.get()

View File

@@ -10,10 +10,18 @@ export default
var scope = params.scope, var scope = params.scope,
job_launch_data = {}, job_launch_data = {},
url = params.url, url = params.url,
submitJobType = params.submitJobType,
vars_url = GetBasePath('job_templates')+scope.job_template_id + '/', vars_url = GetBasePath('job_templates')+scope.job_template_id + '/',
base = $location.path().replace(/^\//, '').split('/')[0], base = $location.path().replace(/^\//, '').split('/')[0],
extra_vars; extra_vars;
if(submitJobType === 'job_template') {
vars_url = GetBasePath('job_templates')+scope.job_template_id + '/';
}
else if(submitJobType === 'workflow_job_template') {
vars_url = GetBasePath('workflow_job_templates')+scope.workflow_job_template_id + '/';
}
//found it easier to assume that there will be extra vars, and then check for a blank object at the end //found it easier to assume that there will be extra vars, and then check for a blank object at the end
job_launch_data.extra_vars = {}; job_launch_data.extra_vars = {};

View File

@@ -121,7 +121,8 @@ export default
var launchJob = function() { var launchJob = function() {
LaunchJob({ LaunchJob({
scope: $scope, scope: $scope,
url: launch_url url: launch_url,
submitJobType: $scope.submitJobType
}); });
}; };
@@ -144,7 +145,12 @@ export default
} }
} }
else { else {
launch_url = GetBasePath('jobs') + $scope.submitJobId + '/relaunch/'; if($scope.submitJobType && $scope.submitJobType === 'workflow_job_template') {
launch_url = GetBasePath('workflow_jobs') + $scope.submitJobId + '/relaunch/';
}
else {
launch_url = GetBasePath('jobs') + $scope.submitJobId + '/relaunch/';
}
} }
// Get the job or job_template record // Get the job or job_template record
@@ -388,7 +394,8 @@ export default
if($scope.survey_enabled) { if($scope.survey_enabled) {
GetSurveyQuestions({ GetSurveyQuestions({
scope: $scope, scope: $scope,
id: $scope.submitJobId id: $scope.submitJobId,
submitJobType: $scope.submitJobType
}); });
} }

View File

@@ -2,7 +2,7 @@
<div class="JobSubmission-container"> <div class="JobSubmission-container">
<div class="JobSubmission-header"> <div class="JobSubmission-header">
<div class="JobSubmission-title"> <div class="JobSubmission-title">
<div class="JobSubmission-titleText">LAUNCH JOB<div class="JobSubmission-titleLockup"></div>{{job_template_data.name}}</div> <div class="JobSubmission-titleText">LAUNCH JOB<div class="JobSubmission-titleLockup"></div>{{job_template_data.name || workflow_job_template_data.name}}</div>
</div> </div>
<div class="JobSubmission-close"> <div class="JobSubmission-close">
<button class="JobSubmission-exit" ng-click="clearDialog()"><i class="fa fa-times-circle"></i></button> <button class="JobSubmission-exit" ng-click="clearDialog()"><i class="fa fa-times-circle"></i></button>
@@ -229,12 +229,12 @@
</div> </div>
<div class="JobSubmission-footerContainer"> <div class="JobSubmission-footerContainer">
<div class="JobSubmission-footerPreview"> <div class="JobSubmission-footerPreview">
<div class="JobSubmission-previewItem"> <div class="JobSubmission-previewItem" ng-show="submitJobType === 'job_template'">
<div class="JobSubmission-previewItemTitle">INVENTORY</div> <div class="JobSubmission-previewItemTitle">INVENTORY</div>
<div ng-show="selected_inventory" ng-bind="selected_inventory.name"></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">None selected</div>
</div> </div>
<div class="JobSubmission-previewItem"> <div class="JobSubmission-previewItem" ng-show="submitJobType === 'job_template'">
<div class="JobSubmission-previewItemTitle">CREDENTIAL</div> <div class="JobSubmission-previewItemTitle">CREDENTIAL</div>
<div ng-show="selected_credential" ng-bind="selected_credential.name"></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-previewItemNone" ng-show="!selected_credential">None selected</div>

View File

@@ -47,7 +47,7 @@ export default ['$scope', '$rootScope', '$location', '$log',
}; };
$scope.submitJob = function(id) { $scope.submitJob = function(id) {
InitiatePlaybookRun({ scope: $scope, id: id }); InitiatePlaybookRun({ scope: $scope, id: id, job_type: 'job_template' });
}; };
$scope.scheduleJob = function(id) { $scope.scheduleJob = function(id) {

View File

@@ -32,13 +32,13 @@
</div> </div>
</div> </div>
<div class="SurveyMaker-content"> <div class="SurveyMaker-content">
<div class="SurveyMaker-questionPanel" ng-show="(job_template_obj.summary_fields.user_capabilities.edit || canAdd)"> <div class="SurveyMaker-questionPanel" ng-show="(job_template_obj.summary_fields.user_capabilities.edit || workflow_job_template_obj.summary_fields.user_capabilities.edit || canAdd)">
<div id="survey_maker_question_form"></div> <div id="survey_maker_question_form"></div>
</div> </div>
<div class="SurveyMaker-separatorPanel" ng-show="(job_template_obj.summary_fields.user_capabilities.edit || canAdd)"> <div class="SurveyMaker-separatorPanel" ng-show="(job_template_obj.summary_fields.user_capabilities.edit || workflow_job_template_obj.summary_fields.user_capabilities.edit || canAdd)">
<div class="SurveyMaker-contentSeparator"></div> <div class="SurveyMaker-contentSeparator"></div>
</div> </div>
<div class="SurveyMaker-previewPanel" ng-class="{'SurveyMaker-previewPanel--viewOnly': !(job_template_obj.summary_fields.user_capabilities.edit || canAdd)}"> <div class="SurveyMaker-previewPanel" ng-class="{'SurveyMaker-previewPanel--viewOnly': !(job_template_obj.summary_fields.user_capabilities.edit || workflow_job_template_obj.summary_fields.user_capabilities.edit || canAdd)}">
<div style="display: flex; flex-direction: column; width: 100%;"> <div style="display: flex; flex-direction: column; width: 100%;">
<div class="SurveyMaker-panelHeader">PREVIEW</div> <div class="SurveyMaker-panelHeader">PREVIEW</div>
<div class="SurveyMaker-panelBody"> <div class="SurveyMaker-panelBody">
@@ -56,13 +56,13 @@
<i>{{question.question_description}}</i> <i>{{question.question_description}}</i>
</div> </div>
<div class="SurveyMaker-previewInputRow"> <div class="SurveyMaker-previewInputRow">
<span dnd-handle class="SurveyMaker-reorderButton" data-placement="top" aw-tool-tip="Drag to reorder question" data-original-title="" title="" ng-show="(job_template_obj.summary_fields.user_capabilities.edit || canAdd)"> <span dnd-handle class="SurveyMaker-reorderButton" data-placement="top" aw-tool-tip="Drag to reorder question" data-original-title="" title="" ng-show="(job_template_obj.summary_fields.user_capabilities.edit || workflow_job_template_obj.summary_fields.user_capabilities.edit || canAdd)">
<i class="fa fa-ellipsis-v"></i> <i class="fa fa-ellipsis-v"></i>
<span>&nbsp;</span> <span>&nbsp;</span>
<i class="fa fa-ellipsis-v"></i> <i class="fa fa-ellipsis-v"></i>
</span> </span>
<survey-question class="SurveyMaker-previewInput" preview="true" question="question" ng-required="question.required" ng-disabled=true></survey-question> <survey-question class="SurveyMaker-previewInput" preview="true" question="question" ng-required="question.required" ng-disabled=true></survey-question>
<div class="SurveyMaker-previewActions" ng-show="(job_template_obj.summary_fields.user_capabilities.edit || canAdd)"> <div class="SurveyMaker-previewActions" ng-show="(job_template_obj.summary_fields.user_capabilities.edit || workflow_job_template_obj.summary_fields.user_capabilities.edit || canAdd)">
<button class="List-actionButton" data-placement="top" ng-class="{'SurveyMaker-previewActions--selected' : editQuestionIndex == $index}" ng-click="editQuestion($index)" aw-tool-tip="Edit question" data-original-title="" title=""> <button class="List-actionButton" data-placement="top" ng-class="{'SurveyMaker-previewActions--selected' : editQuestionIndex == $index}" ng-click="editQuestion($index)" aw-tool-tip="Edit question" data-original-title="" title="">
<i class="fa fa-pencil"></i> <i class="fa fa-pencil"></i>
</button> </button>
@@ -80,10 +80,10 @@
</div> </div>
<div class="SurveyMaker-panelFooter"> <div class="SurveyMaker-panelFooter">
<div class="Form-buttons"> <div class="Form-buttons">
<button id="survey-delete-button" class="btn btn-sm SurveyMaker-deleteButton" ng-show="survey_exists && (job_template_obj.summary_fields.user_capabilities.edit || canAdd)" ng-click="showDeleteOverlay('survey')">DELETE SURVEY</button> <button id="survey-delete-button" class="btn btn-sm SurveyMaker-deleteButton" ng-show="survey_exists && (job_template_obj.summary_fields.user_capabilities.edit || workflow_job_template_obj.summary_fields.user_capabilities.edit || canAdd)" ng-click="showDeleteOverlay('survey')">DELETE SURVEY</button>
<button id="survey-close-button" class="btn btn-sm Form-buttonDefault" ng-click="closeSurvey('survey-modal-dialog')" ng-show="(job_template_obj.summary_fields.user_capabilities.edit || canAdd)">CANCEL</button> <button id="survey-close-button" class="btn btn-sm Form-buttonDefault" ng-click="closeSurvey('survey-modal-dialog')" ng-show="(job_template_obj.summary_fields.user_capabilities.edit || workflow_job_template_obj.summary_fields.user_capabilities.edit || canAdd)">CANCEL</button>
<button id="survey-close-button" class="btn btn-sm Form-buttonDefault" ng-click="closeSurvey('survey-modal-dialog')" ng-show="!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)">CLOSE</button> <button id="survey-close-button" class="btn btn-sm Form-buttonDefault" ng-click="closeSurvey('survey-modal-dialog')" ng-show="!(job_template_obj.summary_fields.user_capabilities.edit || workflow_job_template_obj.summary_fields.user_capabilities.edit || canAdd)">CLOSE</button>
<button id="survey-save-button" class="btn btn-sm Form-saveButton" ng-click="saveSurvey()" ng-disabled="survey_questions.length < 1 || !can_edit || editQuestionIndex !== null" ng-show="(job_template_obj.summary_fields.user_capabilities.edit || canAdd)">SAVE</button> <button id="survey-save-button" class="btn btn-sm Form-saveButton" ng-click="saveSurvey()" ng-disabled="survey_questions.length < 1 || !can_edit || editQuestionIndex !== null" ng-show="(job_template_obj.summary_fields.user_capabilities.edit || workflow_job_template_obj.summary_fields.user_capabilities.edit || canAdd)">SAVE</button>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -18,7 +18,7 @@ export function PortalModeJobTemplatesController($scope, PortalJobTemplateList,
} }
$scope.submitJob = function(id) { $scope.submitJob = function(id) {
InitiatePlaybookRun({ scope: $scope, id: id }); InitiatePlaybookRun({ scope: $scope, id: id, job_type: 'job_template' });
}; };
} }

View File

@@ -268,7 +268,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
// this.addListeners(); // this.addListeners();
// } // }
if (options.mode === 'add') { if (options.mode === 'add') {
this.applyDefaults(); this.applyDefaults(form, this.scope);
} }
} }
@@ -282,21 +282,21 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
$(this).remove(); $(this).remove();
}); });
// Prepend an asterisk to required field label // // Prepend an asterisk to required field label
$('.form-control[required], input[type="radio"][required]').each(function () { // $('.form-control[required], input[type="radio"][required]').each(function () {
var label, span; // var label, span;
if (Empty($(this).attr('aw-required-when'))) { // if (Empty($(this).attr('aw-required-when'))) {
label = $(this).closest('.form-group').find('label').first(); // label = $(this).closest('.form-group').find('label').first();
if (label.length > 0) { // if (label.length > 0) {
span = label.children('span'); // span = label.children('span');
if (span.length > 0 && !span.first().hasClass('prepend-asterisk')) { // if (span.length > 0 && !span.first().hasClass('prepend-asterisk')) {
span.first().addClass('prepend-asterisk'); // span.first().addClass('prepend-asterisk');
} else if (span.length <= 0 && !label.first().hasClass('prepend-asterisk')) { // } else if (span.length <= 0 && !label.first().hasClass('prepend-asterisk')) {
label.first().addClass('prepend-asterisk'); // label.first().addClass('prepend-asterisk');
} // }
} // }
} // }
}); // });
try { try {
$('#help-modal').empty().dialog('destroy'); $('#help-modal').empty().dialog('destroy');
@@ -476,7 +476,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
} }
} }
if (this.mode === 'add') { if (this.mode === 'add') {
this.applyDefaults(); this.applyDefaults(form, scope);
} }
}, },

View File

@@ -8,13 +8,13 @@
[ '$filter', '$scope', '$rootScope', '$compile', '$location', '$log', [ '$filter', '$scope', '$rootScope', '$compile', '$location', '$log',
'$stateParams', 'JobTemplateForm', 'GenerateForm', 'Rest', 'Alert', '$stateParams', 'JobTemplateForm', 'GenerateForm', 'Rest', 'Alert',
'ProcessErrors', 'ClearScope', 'GetBasePath', 'md5Setup', 'ParseTypeChange', 'Wait', 'ProcessErrors', 'ClearScope', 'GetBasePath', 'md5Setup', 'ParseTypeChange', 'Wait',
'Empty', 'ToJSON', 'CallbackHelpInit', 'initSurvey', 'Prompt', 'GetChoices', '$state', 'Empty', 'ToJSON', 'CallbackHelpInit', 'Prompt', 'GetChoices', '$state',
'CreateSelect2', '$q', 'CreateSelect2', '$q',
function( function(
$filter, $scope, $rootScope, $compile, $filter, $scope, $rootScope, $compile,
$location, $log, $stateParams, JobTemplateForm, GenerateForm, Rest, Alert, $location, $log, $stateParams, JobTemplateForm, GenerateForm, Rest, Alert,
ProcessErrors, ClearScope, GetBasePath, md5Setup, ParseTypeChange, Wait, ProcessErrors, ClearScope, GetBasePath, md5Setup, ParseTypeChange, Wait,
Empty, ToJSON, CallbackHelpInit, SurveyControllerInit, Prompt, GetChoices, Empty, ToJSON, CallbackHelpInit, Prompt, GetChoices,
$state, CreateSelect2, $q $state, CreateSelect2, $q
) { ) {
@@ -54,10 +54,6 @@
default_val: false default_val: false
}); });
CallbackHelpInit({ scope: $scope }); CallbackHelpInit({ scope: $scope });
SurveyControllerInit({
scope: $scope,
parent_scope: $scope
});
} }
callback = function() { callback = function() {

View File

@@ -56,7 +56,8 @@ export default
SurveyControllerInit({ SurveyControllerInit({
scope: $scope, scope: $scope,
parent_scope: $scope, parent_scope: $scope,
id: id id: id,
templateType: 'job_template'
}); });
} }
@@ -287,7 +288,7 @@ export default
Wait('start'); Wait('start');
if ($scope.removeSurveySaved) { if ($scope.removeSurveySaved) {
$scope.rmoveSurveySaved(); $scope.removeSurveySaved();
} }
$scope.removeSurveySaved = $scope.$on('SurveySaved', function() { $scope.removeSurveySaved = $scope.$on('SurveySaved', function() {
Wait('stop'); Wait('stop');
@@ -662,7 +663,8 @@ export default
InitiatePlaybookRun({ InitiatePlaybookRun({
scope: $scope, scope: $scope,
id: id id: id,
job_type: 'job_template'
}); });
} }
}; };

View File

@@ -82,7 +82,7 @@ export default
} }
scope.removeGenerateForm = scope.$on('GenerateForm', function() { scope.removeGenerateForm = scope.$on('GenerateForm', function() {
tmpVar = scope.mode; tmpVar = scope.mode;
GenerateForm.inject(form, { id: 'survey_maker_question_form', mode: 'edit', related: false, scope:scope }); GenerateForm.inject(form, { id: 'survey_maker_question_form', mode: 'edit', related: false, scope:scope, noPanel: true });
scope.mode = tmpVar; scope.mode = tmpVar;
scope.$emit('FillQuestionForm'); scope.$emit('FillQuestionForm');
}); });

View File

@@ -43,7 +43,7 @@ export default
variable: { variable: {
realName: 'variable', realName: 'variable',
type: 'custom', type: 'custom',
control:'<label for="variable"><span class="Form-inputLabel prepend-asterisk"> ANSWER VARIABLE NAME</span>'+ control:'<label class="prepend-asterisk" for="variable"><span class="Form-inputLabel"> ANSWER VARIABLE NAME</span>'+
'<a id="awp-variable" href="" aw-pop-over="<p>The suggested format for variable names is lowercase and underscore-separated. Also note that this field cannot accept variable names with spaces.</p><p>For example: <br>foo_bar<br>'+ '<a id="awp-variable" href="" aw-pop-over="<p>The suggested format for variable names is lowercase and underscore-separated. Also note that this field cannot accept variable names with spaces.</p><p>For example: <br>foo_bar<br>'+
'user_id<br>host_name<br><div class=&quot;popover-footer&quot;><span class=&quot;key&quot;>esc</span> or click to close</div>" '+ 'user_id<br>host_name<br><div class=&quot;popover-footer&quot;><span class=&quot;key&quot;>esc</span> or click to close</div>" '+
'data-placement="right" data-container="body" popover-title="Answer Variable Name" class="help-link" data-original-title="" title="" tabindex="-1"><i class="fa fa-question-circle"></i></a> </label>'+ 'data-placement="right" data-container="body" popover-title="Answer Variable Name" class="help-link" data-original-title="" title="" tabindex="-1"><i class="fa fa-question-circle"></i></a> </label>'+

View File

@@ -3,7 +3,15 @@ export default
return function(params) { return function(params) {
var scope = params.scope, var scope = params.scope,
id = params.id, id = params.id,
templateType = params.templateType,
url;
if(templateType === 'job_template'){
url = GetBasePath('job_templates') + id + '/survey_spec/'; url = GetBasePath('job_templates') + id + '/survey_spec/';
}
else if(templateType === 'workflow_job_template') {
url = GetBasePath('workflow_job_templates') + id + '/survey_spec/';
}
if (scope.removeDialogReady) { if (scope.removeDialogReady) {
scope.removeDialogReady(); scope.removeDialogReady();

View File

@@ -5,7 +5,8 @@ export default
var scope = params.scope, var scope = params.scope,
id = params.id, id = params.id,
form = SurveyQuestionForm, form = SurveyQuestionForm,
sce = params.sce; sce = params.sce,
templateType = params.templateType;
scope.sce = sce; scope.sce = sce;
scope.survey_questions = []; scope.survey_questions = [];
scope.answer_types=[ scope.answer_types=[
@@ -36,7 +37,8 @@ export default
// Goes out and fetches the existing survey and populates the preview // Goes out and fetches the existing survey and populates the preview
EditSurvey({ EditSurvey({
scope: scope, scope: scope,
id: id id: id,
templateType: templateType
}); });
}; };
@@ -58,79 +60,63 @@ export default
// goes out and cleans up the survey_questions on scope before destroying // goes out and cleans up the survey_questions on scope before destroying
// the modal. // the modal.
scope.closeSurvey = function(id) { scope.closeSurvey = function(id) {
if(scope.mode === 'add') { // Clear out the whole array, this data gets pulled in each time the modal is opened
// Clear out any "unsaved" survey questions scope.survey_questions = [];
for (var i = scope.survey_questions.length - 1; i >= 0; i--) {
if (scope.survey_questions[i].new_question) {
scope.survey_questions.splice(i, 1);
}
}
}
else {
// Clear out the whole array, this data gets pulled in each time the modal is opened
scope.survey_questions = [];
}
$('#' + id).dialog('destroy'); $('#' + id).dialog('destroy');
}; };
// Gets called when a user actually hits the save button. Functionality differs
// based on the mode. scope.mode="add" cleans up scope.survey_questions and
// destroys the modal, holding the survey questions in memory. scope.mode="edit"
// actually fires off the necessary server call(s) to add/update a survey.
scope.saveSurvey = function() { scope.saveSurvey = function() {
Wait('start'); Wait('start');
if(scope.mode ==="add"){
// Loop across the survey questions and remove any new_question flags
angular.forEach(scope.survey_questions, function(question) {
delete question.new_question;
});
$('#survey-modal-dialog').dialog('destroy'); scope.survey_name = "";
scope.survey_name = ""; scope.survey_description = "";
scope.survey_description = "";
scope.$emit('SurveySaved');
}
else {
scope.survey_name = ""; var updateSurveyQuestions = function() {
scope.survey_description = ""; if(templateType === 'job_template') {
var updateSurveyQuestions = function() {
Rest.setUrl(GetBasePath('job_templates') + id + '/survey_spec/'); Rest.setUrl(GetBasePath('job_templates') + id + '/survey_spec/');
return Rest.post({name: scope.survey_name, description: scope.survey_description, spec: scope.survey_questions }) }
.success(function () { else if(templateType === 'workflow_job_template') {
Rest.setUrl(GetBasePath('workflow_job_templates') + id + '/survey_spec/');
}
return Rest.post({name: scope.survey_name, description: scope.survey_description, spec: scope.survey_questions })
.success(function () {
})
.error(function (data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed to add new survey. POST returned status: ' + status });
});
};
var updateSurveyEnabled = function() {
Rest.setUrl(GetBasePath('job_templates') + id+ '/');
return Rest.patch({"survey_enabled": scope.survey_enabled})
.success(function () {
})
.error(function (data, status) {
ProcessErrors(scope, data, status, form, {
hdr: 'Error!',
msg: 'Failed to save survey_enabled: GET status: ' + status
});
});
};
updateSurveyQuestions()
.then(function() {
return updateSurveyEnabled();
}) })
.then(function() { .error(function (data, status) {
scope.closeSurvey('survey-modal-dialog'); ProcessErrors(scope, data, status, null, { hdr: 'Error!',
scope.$emit('SurveySaved'); msg: 'Failed to add new survey. POST returned status: ' + status });
}); });
};
var updateSurveyEnabled = function() {
if(templateType === 'job_template') {
Rest.setUrl(GetBasePath('job_templates') + id+ '/');
}
else if(templateType === 'workflow_job_template') {
Rest.setUrl(GetBasePath('workflow_job_templates') + id+ '/');
}
return Rest.patch({"survey_enabled": scope.survey_enabled})
.success(function () {
})
.error(function (data, status) {
ProcessErrors(scope, data, status, form, {
hdr: 'Error!',
msg: 'Failed to save survey_enabled: GET status: ' + status
});
});
};
updateSurveyQuestions()
.then(function() {
return updateSurveyEnabled();
})
.then(function() {
scope.closeSurvey('survey-modal-dialog');
scope.$emit('SurveySaved');
});
}
}; };
// Gets called when the user clicks the on/off toggle beside the survey modal title. // Gets called when the user clicks the on/off toggle beside the survey modal title.
@@ -149,7 +135,7 @@ export default
// modal we need to make sure that scope.mode is still 'edit' after the Add Question form is injected. // modal we need to make sure that scope.mode is still 'edit' after the Add Question form is injected.
// To avoid having to do this we'd need to track the job template mode in a variable other than scope.mode. // To avoid having to do this we'd need to track the job template mode in a variable other than scope.mode.
var tmpMode = scope.mode; var tmpMode = scope.mode;
GenerateForm.inject(form, { id:'survey_maker_question_form', mode: 'add' , scope: scope, related: false}); GenerateForm.inject(form, { id:'survey_maker_question_form', mode: 'add' , scope: scope, related: false, noPanel: true});
scope.mode = tmpMode; scope.mode = tmpMode;
scope.clearQuestion(); scope.clearQuestion();
}; };

View File

@@ -33,9 +33,6 @@
$scope.parseType = 'yaml'; $scope.parseType = 'yaml';
$scope.includeWorkflowMaker = false; $scope.includeWorkflowMaker = false;
// What is this used for? Permissions?
$scope.can_edit = true;
$scope.editRequests = []; $scope.editRequests = [];
$scope.associateRequests = []; $scope.associateRequests = [];
$scope.disassociateRequests = []; $scope.disassociateRequests = [];
@@ -49,6 +46,13 @@
addNew: true addNew: true
}); });
SurveyControllerInit({
scope: $scope,
parent_scope: $scope,
id: id,
templateType: 'workflow_job_template'
});
Rest.setUrl('api/v1/labels'); Rest.setUrl('api/v1/labels');
Wait("start"); Wait("start");
Rest.get() Rest.get()
@@ -140,6 +144,7 @@
let workflowJobTemplateData = data.data; let workflowJobTemplateData = data.data;
$scope.workflow_job_template_obj = workflowJobTemplateData; $scope.workflow_job_template_obj = workflowJobTemplateData;
$scope.name = workflowJobTemplateData.name; $scope.name = workflowJobTemplateData.name;
$scope.can_edit = workflowJobTemplateData.summary_fields.user_capabilities.edit;
let fld, i; let fld, i;
for (fld in form.fields) { for (fld in form.fields) {
if (fld !== 'variables' && fld !== 'survey' && workflowJobTemplateData[fld] !== null && workflowJobTemplateData[fld] !== undefined) { if (fld !== 'variables' && fld !== 'survey' && workflowJobTemplateData[fld] !== null && workflowJobTemplateData[fld] !== undefined) {
@@ -356,12 +361,21 @@
Wait('start'); Wait('start');
try { try {
for (fld in form.fields) { for (fld in form.fields) {
data[fld] = $scope[fld]; data[fld] = $scope[fld];
} }
data.extra_vars = ToJSON($scope.parseType, data.extra_vars = ToJSON($scope.parseType,
$scope.variables, true); $scope.variables, true);
// We only want to set the survey_enabled flag to
// true for this job template if a survey exists
// and it's been enabled. By default,
// survey_enabled is explicitly set to true but
// if no survey is created then we don't want
// it enabled.
data.survey_enabled = ($scope.survey_enabled &&
$scope.survey_exists) ? $scope.survey_enabled : false;
// The idea here is that we want to find the new option elements that also have a label that exists in the dom // The idea here is that we want to find the new option elements that also have a label that exists in the dom
$("#workflow_job_template_labels > option").filter("[data-select2-tag=true]").each(function(optionIndex, option) { $("#workflow_job_template_labels > option").filter("[data-select2-tag=true]").each(function(optionIndex, option) {
@@ -601,7 +615,6 @@
}); });
}); });
}); });
//$state.go('templates.editWorkflowJobTemplate', {id: id}, {reload: true});
}); });
} }
@@ -633,6 +646,15 @@
}); });
}; };
if ($scope.removeSurveySaved) {
$scope.removeSurveySaved();
}
$scope.removeSurveySaved = $scope.$on('SurveySaved', function() {
Wait('stop');
$scope.survey_exists = true;
$scope.invalid_survey = false;
});
init(); init();
} }
]; ];

View File

@@ -101,7 +101,7 @@ export default ['$q', 'Prompt', '$filter', 'Wait', 'Rest', '$state', 'ProcessErr
}, },
relaunchJob: function(scope) { relaunchJob: function(scope) {
InitiatePlaybookRun({ scope: scope, id: scope.workflow.id, InitiatePlaybookRun({ scope: scope, id: scope.workflow.id,
relaunch: true }); relaunch: true, job_type: 'workflow_job_template' });
} }
}; };
return val; return val;

View File

@@ -66,6 +66,10 @@ describe('Controller: jobResultsController', () => {
.indexOf("/static/") !== -1)) .indexOf("/static/") !== -1))
.respond(''); .respond('');
$httpBackend
.whenGET('/api/')
.respond(200, '');
$scope = $rootScope.$new(); $scope = $rootScope.$new();
$rScope = $rootScope; $rScope = $rootScope;
q = $q; q = $q;

View File

@@ -20,6 +20,7 @@ describe('Controller: WorkflowAdd', () => {
ToJSON; ToJSON;
beforeEach(angular.mock.module('Tower')); beforeEach(angular.mock.module('Tower'));
beforeEach(angular.mock.module('RestServices'));
beforeEach(angular.mock.module('templates', ($provide) => { beforeEach(angular.mock.module('templates', ($provide) => {
state = jasmine.createSpyObj('state', [ state = jasmine.createSpyObj('state', [
@@ -79,6 +80,10 @@ describe('Controller: WorkflowAdd', () => {
ParseTypeChange = _ParseTypeChange_; ParseTypeChange = _ParseTypeChange_;
ToJSON = _ToJSON_; ToJSON = _ToJSON_;
httpBackend
.whenGET('/api/')
.respond(200, '');
TemplatesService.getLabelOptions = jasmine.createSpy('getLabelOptions').and.returnValue(getLabelsDeferred.promise); TemplatesService.getLabelOptions = jasmine.createSpy('getLabelOptions').and.returnValue(getLabelsDeferred.promise);
TemplatesService.createWorkflowJobTemplate = jasmine.createSpy('createWorkflowJobTemplate').and.returnValue(createWorkflowJobTemplateDeferred.promise); TemplatesService.createWorkflowJobTemplate = jasmine.createSpy('createWorkflowJobTemplate').and.returnValue(createWorkflowJobTemplateDeferred.promise);