mirror of
https://github.com/ansible/awx.git
synced 2024-11-01 16:51:11 +03:00
Merge pull request #1489 from mabashian/169-workflow-nodes
Implemented new workflow node prompting
This commit is contained in:
commit
597874b849
@ -349,7 +349,7 @@ function($filter, $state, $stateParams, Wait, $scope, moment,
|
||||
|
||||
let processed = PromptService.processSurveyQuestions({
|
||||
surveyQuestions: surveyQuestionRes.data.spec,
|
||||
extra_data: data.extra_data
|
||||
extra_data: _.cloneDeep(data.extra_data)
|
||||
});
|
||||
|
||||
$scope.missingSurveyValue = processed.missingSurveyValue;
|
||||
|
@ -37,7 +37,7 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
|
||||
.config(['$stateProvider', 'stateDefinitionsProvider', '$stateExtenderProvider',
|
||||
function($stateProvider, stateDefinitionsProvider, $stateExtenderProvider) {
|
||||
let stateTree, addJobTemplate, editJobTemplate, addWorkflow, editWorkflow,
|
||||
workflowMaker, inventoryLookup, credentialLookup,
|
||||
workflowMaker,
|
||||
stateDefinitions = stateDefinitionsProvider.$get(),
|
||||
stateExtender = $stateExtenderProvider.$get();
|
||||
|
||||
@ -401,8 +401,7 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
|
||||
job_template_search: {
|
||||
value: {
|
||||
page_size: '5',
|
||||
order_by: 'name',
|
||||
inventory__isnull: false
|
||||
order_by: 'name'
|
||||
},
|
||||
squash: false,
|
||||
dynamic: true
|
||||
@ -474,30 +473,29 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
|
||||
name: row.name
|
||||
};
|
||||
|
||||
$scope.templateSelected(row);
|
||||
$scope.templateManuallySelected(row);
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$scope.$on('templateSelected', function(e, options) {
|
||||
if(options.activeTab !== 'jobs') {
|
||||
$scope.$watch('selectedTemplate', () => {
|
||||
$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[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() {
|
||||
@ -552,30 +550,29 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
|
||||
name: row.name
|
||||
};
|
||||
|
||||
$scope.templateSelected(row);
|
||||
$scope.templateManuallySelected(row);
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$scope.$on('templateSelected', function(e, options) {
|
||||
if(options.activeTab !== 'inventory_sync') {
|
||||
$scope.$watch('selectedTemplate', () => {
|
||||
$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[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() {
|
||||
@ -630,30 +627,29 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
|
||||
name: row.name
|
||||
};
|
||||
|
||||
$scope.templateSelected(row);
|
||||
$scope.templateManuallySelected(row);
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$scope.$on('templateSelected', function(e, options) {
|
||||
if(options.activeTab !== 'project_sync') {
|
||||
$scope.$watch('selectedTemplate', () => {
|
||||
$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[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() {
|
||||
@ -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: {
|
||||
@ -798,116 +731,6 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
|
||||
}
|
||||
};
|
||||
|
||||
inventoryLookup = {
|
||||
searchPrefix: 'inventory',
|
||||
name: 'templates.editWorkflowJobTemplate.workflowMaker.inventory',
|
||||
url: '/inventory',
|
||||
data: {
|
||||
formChildState: true
|
||||
},
|
||||
params: {
|
||||
inventory_search: {
|
||||
value: {
|
||||
page_size: '5'
|
||||
},
|
||||
squash: true,
|
||||
dynamic: true
|
||||
}
|
||||
},
|
||||
ncyBreadcrumb: {
|
||||
skip: true
|
||||
},
|
||||
views: {
|
||||
'related': {
|
||||
templateProvider: function(ListDefinition, generateList) {
|
||||
let list_html = generateList.build({
|
||||
mode: 'lookup',
|
||||
list: ListDefinition,
|
||||
input_type: 'radio'
|
||||
});
|
||||
return `<lookup-modal>${list_html}</lookup-modal>`;
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
ListDefinition: ['InventoryList', function(InventoryList) {
|
||||
// mutate the provided list definition here
|
||||
let list = _.cloneDeep(InventoryList);
|
||||
list.lookupConfirmText = 'SELECT';
|
||||
return list;
|
||||
}],
|
||||
Dataset: ['ListDefinition', 'QuerySet', '$stateParams', 'GetBasePath',
|
||||
(list, qs, $stateParams, GetBasePath) => {
|
||||
let path = GetBasePath(list.name) || GetBasePath(list.basePath);
|
||||
return qs.search(path, $stateParams[`${list.iterator}_search`]);
|
||||
}
|
||||
]
|
||||
},
|
||||
onExit: function($state) {
|
||||
if ($state.transition) {
|
||||
$('#form-modal').modal('hide');
|
||||
$('.modal-backdrop').remove();
|
||||
$('body').removeClass('modal-open');
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
credentialLookup = {
|
||||
searchPrefix: 'credential',
|
||||
name: 'templates.editWorkflowJobTemplate.workflowMaker.credential',
|
||||
url: '/credential',
|
||||
data: {
|
||||
formChildState: true
|
||||
},
|
||||
params: {
|
||||
credential_search: {
|
||||
value: {
|
||||
page_size: '5'
|
||||
},
|
||||
squash: true,
|
||||
dynamic: true
|
||||
}
|
||||
},
|
||||
ncyBreadcrumb: {
|
||||
skip: true
|
||||
},
|
||||
views: {
|
||||
'related': {
|
||||
templateProvider: function(ListDefinition, generateList) {
|
||||
let list_html = generateList.build({
|
||||
mode: 'lookup',
|
||||
list: ListDefinition,
|
||||
input_type: 'radio'
|
||||
});
|
||||
return `<lookup-modal>${list_html}</lookup-modal>`;
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
ListDefinition: ['CredentialList', function(CredentialList) {
|
||||
let list = _.cloneDeep(CredentialList);
|
||||
list.lookupConfirmText = 'SELECT';
|
||||
return list;
|
||||
}],
|
||||
Dataset: ['ListDefinition', 'QuerySet', '$stateParams', 'GetBasePath',
|
||||
(list, qs, $stateParams, GetBasePath) => {
|
||||
let path = GetBasePath(list.name) || GetBasePath(list.basePath);
|
||||
return qs.search(path, $stateParams[`${list.iterator}_search`]);
|
||||
}
|
||||
]
|
||||
},
|
||||
onExit: function($state) {
|
||||
if ($state.transition) {
|
||||
$('#form-modal').modal('hide');
|
||||
$('.modal-backdrop').remove();
|
||||
$('body').removeClass('modal-open');
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
return Promise.all([
|
||||
addJobTemplate,
|
||||
editJobTemplate,
|
||||
@ -919,9 +742,7 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
|
||||
return result.concat(definition.states);
|
||||
}, [
|
||||
stateExtender.buildDefinition(listRoute),
|
||||
stateExtender.buildDefinition(workflowMaker),
|
||||
stateExtender.buildDefinition(inventoryLookup),
|
||||
stateExtender.buildDefinition(credentialLookup)
|
||||
stateExtender.buildDefinition(workflowMaker)
|
||||
])
|
||||
};
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
<div class="Prompt">
|
||||
<at-modal>
|
||||
<at-modal ng-if="vm.promptData">
|
||||
<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.credential.tab" state="vm.steps.credential.tab">{{:: vm.strings.get('prompt.CREDENTIAL') }}</at-tab>
|
||||
|
@ -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 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.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]}));
|
||||
|
@ -54,17 +54,17 @@ export default [ 'templateUrl', 'QuerySet', 'GetBasePath', 'generateList', '$com
|
||||
$('#prompt-inventory').append($compile(html)(scope));
|
||||
|
||||
scope.$watch('promptData.prompts.inventory.value', () => {
|
||||
if(scope.promptData.prompts.inventory.value && scope.promptData.prompts.inventory.value.id) {
|
||||
// Loop across the inventories and see if one of them should be "checked"
|
||||
scope.inventories.forEach((row, i) => {
|
||||
if (row.id === scope.promptData.prompts.inventory.value.id) {
|
||||
scope.inventories[i].checked = 1;
|
||||
}
|
||||
else {
|
||||
scope.inventories[i].checked = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
scope.inventories.forEach((row, i) => {
|
||||
if (
|
||||
_.has(scope, 'promptData.prompts.inventory.value.id') &&
|
||||
row.id === scope.promptData.prompts.inventory.value.id
|
||||
) {
|
||||
scope.inventories[i].checked = 1;
|
||||
}
|
||||
else {
|
||||
scope.inventories[i].checked = 0;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
*************************************************/
|
||||
|
||||
export default
|
||||
['ParseTypeChange', 'CreateSelect2', 'TemplatesStrings', function(ParseTypeChange, CreateSelect2, strings) {
|
||||
['ParseTypeChange', 'CreateSelect2', 'TemplatesStrings', '$timeout', function(ParseTypeChange, CreateSelect2, strings, $timeout) {
|
||||
const vm = this;
|
||||
|
||||
vm.strings = strings;
|
||||
@ -30,10 +30,12 @@ export default
|
||||
|
||||
let codemirrorExtraVars = () => {
|
||||
if(scope.promptData.launchConf.ask_variables_on_launch && !scope.promptData.prompts.variables.ignore) {
|
||||
ParseTypeChange({
|
||||
scope: scope,
|
||||
variable: 'extraVariables',
|
||||
field_id: 'job_launch_variables'
|
||||
$timeout(() => {
|
||||
ParseTypeChange({
|
||||
scope: scope,
|
||||
variable: 'extraVariables',
|
||||
field_id: 'job_launch_variables'
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -281,6 +281,15 @@ export default ['Rest', 'GetBasePath', '$q', 'NextPage', function(Rest, GetBaseP
|
||||
});
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
}];
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -93,7 +93,31 @@
|
||||
<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>
|
||||
<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>
|
||||
@ -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-saveButton" ng-click="saveWorkflowMaker()" ng-show="workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate" ng-disabled="edgeFlags.conflict || workflowMakerFormConfig.nodeMode === 'add'"> Save</button>
|
||||
</div>
|
||||
<prompt prompt-data="promptData" action-text="CONFIRM"></launch>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user