Implemented workflow node prompting

This commit is contained in:
mabashian
2018-03-08 18:42:29 -05:00
parent 8a25342ce5
commit c98e7f6ecd
8 changed files with 745 additions and 605 deletions

View File

@@ -37,7 +37,7 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
.config(['$stateProvider', 'stateDefinitionsProvider', '$stateExtenderProvider', .config(['$stateProvider', 'stateDefinitionsProvider', '$stateExtenderProvider',
function($stateProvider, stateDefinitionsProvider, $stateExtenderProvider) { function($stateProvider, stateDefinitionsProvider, $stateExtenderProvider) {
let stateTree, addJobTemplate, editJobTemplate, addWorkflow, editWorkflow, let stateTree, addJobTemplate, editJobTemplate, addWorkflow, editWorkflow,
workflowMaker, inventoryLookup, credentialLookup, workflowMaker,
stateDefinitions = stateDefinitionsProvider.$get(), stateDefinitions = stateDefinitionsProvider.$get(),
stateExtender = $stateExtenderProvider.$get(); stateExtender = $stateExtenderProvider.$get();
@@ -401,8 +401,7 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
job_template_search: { job_template_search: {
value: { value: {
page_size: '5', page_size: '5',
order_by: 'name', order_by: 'name'
inventory__isnull: false
}, },
squash: false, squash: false,
dynamic: true dynamic: true
@@ -474,30 +473,29 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
name: row.name name: row.name
}; };
$scope.templateSelected(row); $scope.templateManuallySelected(row);
} }
}); });
}; };
$scope.$on('templateSelected', function(e, options) { $scope.$watch('selectedTemplate', () => {
if(options.activeTab !== 'jobs') { $scope.job_templates.forEach(function(row, i) {
if(_.has($scope, 'selectedTemplate.id') && row.id === $scope.selectedTemplate.id) {
$scope.job_templates[i].checked = 1;
}
else {
$scope.job_templates[i].checked = 0;
}
});
});
$scope.$watch('activeTab', () => {
if(!$scope.activeTab || $scope.activeTab !== "jobs") {
$scope.job_templates.forEach(function(row, i) { $scope.job_templates.forEach(function(row, i) {
$scope.job_templates[i].checked = 0; $scope.job_templates[i].checked = 0;
}); });
} }
else {
if($scope.selectedTemplate){
$scope.job_templates.forEach(function(row, i) {
if(row.id === $scope.selectedTemplate.id) {
$scope.job_templates[i].checked = 1;
}
else {
$scope.job_templates[i].checked = 0;
}
});
}
}
}); });
$scope.$on('clearWorkflowLists', function() { $scope.$on('clearWorkflowLists', function() {
@@ -552,30 +550,29 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
name: row.name name: row.name
}; };
$scope.templateSelected(row); $scope.templateManuallySelected(row);
} }
}); });
}; };
$scope.$on('templateSelected', function(e, options) { $scope.$watch('selectedTemplate', () => {
if(options.activeTab !== 'inventory_sync') { $scope.workflow_inventory_sources.forEach(function(row, i) {
if(_.has($scope, 'selectedTemplate.id') && row.id === $scope.selectedTemplate.id) {
$scope.workflow_inventory_sources[i].checked = 1;
}
else {
$scope.workflow_inventory_sources[i].checked = 0;
}
});
});
$scope.$watch('activeTab', () => {
if(!$scope.activeTab || $scope.activeTab !== "inventory_sync") {
$scope.workflow_inventory_sources.forEach(function(row, i) { $scope.workflow_inventory_sources.forEach(function(row, i) {
$scope.workflow_inventory_sources[i].checked = 0; $scope.workflow_inventory_sources[i].checked = 0;
}); });
} }
else {
if($scope.selectedTemplate){
$scope.workflow_inventory_sources.forEach(function(row, i) {
if(row.id === $scope.selectedTemplate.id) {
$scope.workflow_inventory_sources[i].checked = 1;
}
else {
$scope.workflow_inventory_sources[i].checked = 0;
}
});
}
}
}); });
$scope.$on('clearWorkflowLists', function() { $scope.$on('clearWorkflowLists', function() {
@@ -630,30 +627,29 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
name: row.name name: row.name
}; };
$scope.templateSelected(row); $scope.templateManuallySelected(row);
} }
}); });
}; };
$scope.$on('templateSelected', function(e, options) { $scope.$watch('selectedTemplate', () => {
if(options.activeTab !== 'project_sync') { $scope.projects.forEach(function(row, i) {
if(_.has($scope, 'selectedTemplate.id') && row.id === $scope.selectedTemplate.id) {
$scope.projects[i].checked = 1;
}
else {
$scope.projects[i].checked = 0;
}
});
});
$scope.$watch('activeTab', () => {
if(!$scope.activeTab || $scope.activeTab !== "project_sync") {
$scope.projects.forEach(function(row, i) { $scope.projects.forEach(function(row, i) {
$scope.projects[i].checked = 0; $scope.projects[i].checked = 0;
}); });
} }
else {
if($scope.selectedTemplate){
$scope.projects.forEach(function(row, i) {
if(row.id === $scope.selectedTemplate.id) {
$scope.projects[i].checked = 1;
}
else {
$scope.projects[i].checked = 0;
}
});
}
}
}); });
$scope.$on('clearWorkflowLists', function() { $scope.$on('clearWorkflowLists', function() {
@@ -663,69 +659,6 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
}); });
} }
] ]
},
'workflowForm@templates.editWorkflowJobTemplate.workflowMaker': {
templateProvider: function(WorkflowMakerForm, GenerateForm) {
let form = WorkflowMakerForm();
let html = GenerateForm.buildHTML(form, {
mode: 'add',
related: false,
noPanel: true
});
return html;
},
controller: ['$scope', '$timeout', 'CreateSelect2',
function($scope, $timeout, CreateSelect2) {
function resetPromptFields() {
$scope.credential = null;
$scope.credential_name = null;
$scope.inventory = null;
$scope.inventory_name = null;
$scope.job_type = null;
$scope.limit = null;
$scope.job_tags = null;
$scope.skip_tags = null;
}
$scope.saveNodeForm = function(){
// Gather up all of our form data - then let the main scope know what
// the new data is
$scope.confirmNodeForm({
skip_tags: $scope.skip_tags,
job_tags: $scope.job_tags,
limit: $scope.limit,
credential: $scope.credential,
credential_name: $scope.credential_name,
inventory: $scope.inventory,
inventory_name: $scope.inventory_name,
edgeType: $scope.edgeType,
job_type: $scope.job_type
});
};
$scope.$on('templateSelected', function(e, options) {
resetPromptFields();
// Loop across the preset values and attach them to scope
_.forOwn(options.presetValues, function(value, key) {
$scope[key] = value;
});
// The default needs to be in place before we can select2-ify the dropdown
$timeout(function() {
CreateSelect2({
element: '#workflow_maker_job_type',
multiple: false
});
});
});
$scope.$on('setEdgeType', function(e, edgeType) {
$scope.edgeType = edgeType;
});
}
]
} }
}, },
resolve: { resolve: {
@@ -798,114 +731,114 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
} }
}; };
inventoryLookup = { // inventoryLookup = {
searchPrefix: 'inventory', // searchPrefix: 'inventory',
name: 'templates.editWorkflowJobTemplate.workflowMaker.inventory', // name: 'templates.editWorkflowJobTemplate.workflowMaker.inventory',
url: '/inventory', // url: '/inventory',
data: { // data: {
formChildState: true // formChildState: true
}, // },
params: { // params: {
inventory_search: { // inventory_search: {
value: { // value: {
page_size: '5' // page_size: '5'
}, // },
squash: true, // squash: true,
dynamic: true // dynamic: true
} // }
}, // },
ncyBreadcrumb: { // ncyBreadcrumb: {
skip: true // skip: true
}, // },
views: { // views: {
'related': { // 'related': {
templateProvider: function(ListDefinition, generateList) { // templateProvider: function(ListDefinition, generateList) {
let list_html = generateList.build({ // let list_html = generateList.build({
mode: 'lookup', // mode: 'lookup',
list: ListDefinition, // list: ListDefinition,
input_type: 'radio' // input_type: 'radio'
}); // });
return `<lookup-modal>${list_html}</lookup-modal>`; // return `<lookup-modal>${list_html}</lookup-modal>`;
//
} // }
} // }
}, // },
resolve: { // resolve: {
ListDefinition: ['InventoryList', function(InventoryList) { // ListDefinition: ['InventoryList', function(InventoryList) {
// mutate the provided list definition here // // mutate the provided list definition here
let list = _.cloneDeep(InventoryList); // let list = _.cloneDeep(InventoryList);
list.lookupConfirmText = 'SELECT'; // list.lookupConfirmText = 'SELECT';
return list; // return list;
}], // }],
Dataset: ['ListDefinition', 'QuerySet', '$stateParams', 'GetBasePath', // Dataset: ['ListDefinition', 'QuerySet', '$stateParams', 'GetBasePath',
(list, qs, $stateParams, GetBasePath) => { // (list, qs, $stateParams, GetBasePath) => {
let path = GetBasePath(list.name) || GetBasePath(list.basePath); // let path = GetBasePath(list.name) || GetBasePath(list.basePath);
return qs.search(path, $stateParams[`${list.iterator}_search`]); // return qs.search(path, $stateParams[`${list.iterator}_search`]);
} // }
] // ]
}, // },
onExit: function($state) { // onExit: function($state) {
if ($state.transition) { // if ($state.transition) {
$('#form-modal').modal('hide'); // $('#form-modal').modal('hide');
$('.modal-backdrop').remove(); // $('.modal-backdrop').remove();
$('body').removeClass('modal-open'); // $('body').removeClass('modal-open');
} // }
}, // },
}; // };
//
credentialLookup = { // credentialLookup = {
searchPrefix: 'credential', // searchPrefix: 'credential',
name: 'templates.editWorkflowJobTemplate.workflowMaker.credential', // name: 'templates.editWorkflowJobTemplate.workflowMaker.credential',
url: '/credential', // url: '/credential',
data: { // data: {
formChildState: true // formChildState: true
}, // },
params: { // params: {
credential_search: { // credential_search: {
value: { // value: {
page_size: '5' // page_size: '5'
}, // },
squash: true, // squash: true,
dynamic: true // dynamic: true
} // }
}, // },
ncyBreadcrumb: { // ncyBreadcrumb: {
skip: true // skip: true
}, // },
views: { // views: {
'related': { // 'related': {
templateProvider: function(ListDefinition, generateList) { // templateProvider: function(ListDefinition, generateList) {
let list_html = generateList.build({ // let list_html = generateList.build({
mode: 'lookup', // mode: 'lookup',
list: ListDefinition, // list: ListDefinition,
input_type: 'radio' // input_type: 'radio'
}); // });
return `<lookup-modal>${list_html}</lookup-modal>`; // return `<lookup-modal>${list_html}</lookup-modal>`;
//
} // }
} // }
}, // },
resolve: { // resolve: {
ListDefinition: ['CredentialList', function(CredentialList) { // ListDefinition: ['CredentialList', function(CredentialList) {
let list = _.cloneDeep(CredentialList); // let list = _.cloneDeep(CredentialList);
list.lookupConfirmText = 'SELECT'; // list.lookupConfirmText = 'SELECT';
return list; // return list;
}], // }],
Dataset: ['ListDefinition', 'QuerySet', '$stateParams', 'GetBasePath', // Dataset: ['ListDefinition', 'QuerySet', '$stateParams', 'GetBasePath',
(list, qs, $stateParams, GetBasePath) => { // (list, qs, $stateParams, GetBasePath) => {
let path = GetBasePath(list.name) || GetBasePath(list.basePath); // let path = GetBasePath(list.name) || GetBasePath(list.basePath);
return qs.search(path, $stateParams[`${list.iterator}_search`]); // return qs.search(path, $stateParams[`${list.iterator}_search`]);
} // }
] // ]
}, // },
onExit: function($state) { // onExit: function($state) {
if ($state.transition) { // if ($state.transition) {
$('#form-modal').modal('hide'); // $('#form-modal').modal('hide');
$('.modal-backdrop').remove(); // $('.modal-backdrop').remove();
$('body').removeClass('modal-open'); // $('body').removeClass('modal-open');
} // }
}, // },
}; // };
return Promise.all([ return Promise.all([
@@ -920,8 +853,8 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
}, [ }, [
stateExtender.buildDefinition(listRoute), stateExtender.buildDefinition(listRoute),
stateExtender.buildDefinition(workflowMaker), stateExtender.buildDefinition(workflowMaker),
stateExtender.buildDefinition(inventoryLookup), // stateExtender.buildDefinition(inventoryLookup),
stateExtender.buildDefinition(credentialLookup) // stateExtender.buildDefinition(credentialLookup)
]) ])
}; };
}); });

View File

@@ -1,5 +1,5 @@
<div class="Prompt"> <div class="Prompt">
<at-modal> <at-modal ng-if="vm.promptData">
<at-tab-group> <at-tab-group>
<at-tab ng-if="vm.steps.inventory.tab" state="vm.steps.inventory.tab">{{:: vm.strings.get('prompt.INVENTORY') }}</at-tab> <at-tab ng-if="vm.steps.inventory.tab" state="vm.steps.inventory.tab">{{:: vm.strings.get('prompt.INVENTORY') }}</at-tab>
<at-tab ng-if="vm.steps.credential.tab" state="vm.steps.credential.tab">{{:: vm.strings.get('prompt.CREDENTIAL') }}</at-tab> <at-tab ng-if="vm.steps.credential.tab" state="vm.steps.credential.tab">{{:: vm.strings.get('prompt.CREDENTIAL') }}</at-tab>

View File

@@ -19,7 +19,7 @@ function PromptService (Empty, $filter) {
let skipTags = _.has(params, 'currentValues.skip_tags') && params.currentValues.skip_tags ? params.currentValues.skip_tags : (_.has(params, 'launchConf.defaults.skip_tags') ? params.launchConf.defaults.skip_tags : ""); let skipTags = _.has(params, 'currentValues.skip_tags') && params.currentValues.skip_tags ? params.currentValues.skip_tags : (_.has(params, 'launchConf.defaults.skip_tags') ? params.launchConf.defaults.skip_tags : "");
let jobTags = _.has(params, 'currentValues.job_tags') && params.currentValues.job_tags ? params.currentValues.job_tags : (_.has(params, 'launchConf.defaults.job_tags') ? params.launchConf.defaults.job_tags : ""); let jobTags = _.has(params, 'currentValues.job_tags') && params.currentValues.job_tags ? params.currentValues.job_tags : (_.has(params, 'launchConf.defaults.job_tags') ? params.launchConf.defaults.job_tags : "");
prompts.variables.value = _.has(params, 'launchConf.defaults.extra_vars') ? params.launchConf.defaults.extra_vars : "---"; prompts.variables.value = _.has(params, 'launchConf.defaults.extra_vars') && params.launchConf.defaults.extra_vars !== "" ? params.launchConf.defaults.extra_vars : "---";
prompts.verbosity.choices = _.get(params, 'launchOptions.actions.POST.verbosity.choices', []).map(c => ({label: c[1], value: c[0]})); prompts.verbosity.choices = _.get(params, 'launchOptions.actions.POST.verbosity.choices', []).map(c => ({label: c[1], value: c[0]}));
prompts.verbosity.value = _.has(params, 'currentValues.verbosity') && params.currentValues.verbosity ? _.find(prompts.verbosity.choices, item => item.value === params.currentValues.verbosity) : _.find(prompts.verbosity.choices, item => item.value === params.launchConf.defaults.verbosity); prompts.verbosity.value = _.has(params, 'currentValues.verbosity') && params.currentValues.verbosity ? _.find(prompts.verbosity.choices, item => item.value === params.currentValues.verbosity) : _.find(prompts.verbosity.choices, item => item.value === params.launchConf.defaults.verbosity);
prompts.jobType.choices = _.get(params, 'launchOptions.actions.POST.job_type.choices', []).map(c => ({label: c[1], value: c[0]})); prompts.jobType.choices = _.get(params, 'launchOptions.actions.POST.job_type.choices', []).map(c => ({label: c[1], value: c[0]}));

View File

@@ -54,17 +54,17 @@ export default [ 'templateUrl', 'QuerySet', 'GetBasePath', 'generateList', '$com
$('#prompt-inventory').append($compile(html)(scope)); $('#prompt-inventory').append($compile(html)(scope));
scope.$watch('promptData.prompts.inventory.value', () => { scope.$watch('promptData.prompts.inventory.value', () => {
if(scope.promptData.prompts.inventory.value && scope.promptData.prompts.inventory.value.id) { scope.inventories.forEach((row, i) => {
// Loop across the inventories and see if one of them should be "checked" if (
scope.inventories.forEach((row, i) => { _.has(scope, 'promptData.prompts.inventory.value.id') &&
if (row.id === scope.promptData.prompts.inventory.value.id) { row.id === scope.promptData.prompts.inventory.value.id
scope.inventories[i].checked = 1; ) {
} scope.inventories[i].checked = 1;
else { }
scope.inventories[i].checked = 0; else {
} scope.inventories[i].checked = 0;
}); }
} });
}); });
}); });
} }

View File

@@ -5,7 +5,7 @@
*************************************************/ *************************************************/
export default export default
['ParseTypeChange', 'CreateSelect2', 'TemplatesStrings', function(ParseTypeChange, CreateSelect2, strings) { ['ParseTypeChange', 'CreateSelect2', 'TemplatesStrings', '$timeout', function(ParseTypeChange, CreateSelect2, strings, $timeout) {
const vm = this; const vm = this;
vm.strings = strings; vm.strings = strings;
@@ -30,10 +30,12 @@ export default
let codemirrorExtraVars = () => { let codemirrorExtraVars = () => {
if(scope.promptData.launchConf.ask_variables_on_launch && !scope.promptData.prompts.variables.ignore) { if(scope.promptData.launchConf.ask_variables_on_launch && !scope.promptData.prompts.variables.ignore) {
ParseTypeChange({ $timeout(() => {
scope: scope, ParseTypeChange({
variable: 'extraVariables', scope: scope,
field_id: 'job_launch_variables' variable: 'extraVariables',
field_id: 'job_launch_variables'
});
}); });
} }
}; };

View File

@@ -281,6 +281,15 @@ export default ['Rest', 'GetBasePath', '$q', 'NextPage', function(Rest, GetBaseP
}); });
return deferred.promise; return deferred.promise;
},
postWorkflowNodeCredential: function(params) {
// params.id
// params.data
var url = GetBasePath('workflow_job_template_nodes') + params.id + '/credentials';
Rest.setUrl(url);
return Rest.post(params.data);
} }
}; };
}]; }];

View File

@@ -93,7 +93,31 @@
<div id="workflow-project-sync-list" ng-show="workflowMakerFormConfig.activeTab === 'project_sync'" ui-view="projectSyncList"></div> <div id="workflow-project-sync-list" ng-show="workflowMakerFormConfig.activeTab === 'project_sync'" ui-view="projectSyncList"></div>
<div id="workflow-inventory-sync-list" ng-show="workflowMakerFormConfig.activeTab === 'inventory_sync'" ui-view="inventorySyncList"></div> <div id="workflow-inventory-sync-list" ng-show="workflowMakerFormConfig.activeTab === 'inventory_sync'" ui-view="inventorySyncList"></div>
</div> </div>
<div id="workflow-maker-form" ui-view="workflowForm"></div> <div ng-show="selectedTemplate">
<div class="form-group Form-formGroup Form-formGroup--singleColumn">
<label for="verbosity" class="Form-inputLabelContainer">
<span class="Form-requiredAsterisk">*</span>
<span class="Form-inputLabel">RUN</span>
</label>
<div>
<select
id="workflow_node_edge"
ng-options="v as v.label for v in edgeTypeOptions track by v.value"
ng-model="edgeType"
class="form-control Form-dropDown"
name="edgeType"
tabindex="-1"
aria-hidden="true">
</select>
</div>
</div>
<div class="buttons Form-buttons" id="workflow_maker_controls">
<button type="button" class="btn btn-sm Form-primaryButton Form-primaryButton--noMargin" id="workflow_maker_prompt_btn" ng-show="showPromptButton" ng-click="openPromptModal()"> Prompt</button>
<button type="button" class="btn btn-sm Form-cancelButton" id="workflow_maker_cancel_btn" ng-show="(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)" ng-click="cancelNodeForm()"> Cancel</button>
<button type="button" class="btn btn-sm Form-cancelButton" id="workflow_maker_close_btn" ng-show="!(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)" ng-click="cancelNodeForm()"> Close</button>
<button type="button" class="btn btn-sm Form-saveButton" id="workflow_maker_select_btn" ng-show="(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)" ng-click="confirmNodeForm()" ng-disabled="workflow_maker_form.$invalid || !selectedTemplate || promptModalMissingReqFields" disabled="disabled"> Select</button>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -101,4 +125,5 @@
<button type="button" class="btn btn-sm WorkflowMaker-cancelButton" ng-click="closeWorkflowMaker()"> Close</button> <button type="button" class="btn btn-sm WorkflowMaker-cancelButton" ng-click="closeWorkflowMaker()"> Close</button>
<button type="button" class="btn btn-sm WorkflowMaker-saveButton" ng-click="saveWorkflowMaker()" ng-show="workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate" ng-disabled="edgeFlags.conflict || workflowMakerFormConfig.nodeMode === 'add'"> Save</button> <button type="button" class="btn btn-sm WorkflowMaker-saveButton" ng-click="saveWorkflowMaker()" ng-show="workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate" ng-disabled="edgeFlags.conflict || workflowMakerFormConfig.nodeMode === 'add'"> Save</button>
</div> </div>
<prompt prompt-data="promptData" action-text="CONFIRM"></launch>
</div> </div>