mirror of
https://github.com/ansible/awx.git
synced 2026-01-11 10:00:01 -03:30
Merge pull request #4014 from mabashian/3968-workflow-graph-on-details-v2
Add workflow graph to details view and re-org job-templates directory
This commit is contained in:
commit
831b67ce7f
@ -67,7 +67,7 @@ import moment from './shared/moment/main';
|
||||
import login from './login/main';
|
||||
import activityStream from './activity-stream/main';
|
||||
import standardOut from './standard-out/main';
|
||||
import JobTemplates from './job-templates/main';
|
||||
import Templates from './templates/main';
|
||||
import credentials from './credentials/main';
|
||||
import { ProjectsList, ProjectsAdd, ProjectsEdit } from './controllers/Projects';
|
||||
import { UsersList, UsersAdd, UsersEdit } from './controllers/Users';
|
||||
@ -126,7 +126,7 @@ var tower = angular.module('Tower', [
|
||||
jobSubmission.name,
|
||||
notifications.name,
|
||||
standardOut.name,
|
||||
JobTemplates.name,
|
||||
Templates.name,
|
||||
portalMode.name,
|
||||
config.name,
|
||||
credentials.name,
|
||||
@ -135,7 +135,7 @@ var tower = angular.module('Tower', [
|
||||
'OrganizationFormDefinition',
|
||||
'UserFormDefinition',
|
||||
'OrganizationListDefinition',
|
||||
'jobTemplates',
|
||||
'templates',
|
||||
'UserListDefinition',
|
||||
'UserHelper',
|
||||
'PromptDialog',
|
||||
@ -158,7 +158,7 @@ var tower = angular.module('Tower', [
|
||||
'TeamHelper',
|
||||
'CredentialsListDefinition',
|
||||
'CredentialFormDefinition',
|
||||
'JobTemplatesListDefinition',
|
||||
'TemplatesListDefinition',
|
||||
'PortalJobTemplatesListDefinition',
|
||||
'JobTemplateFormDefinition',
|
||||
'JobTemplatesHelper',
|
||||
|
||||
@ -14,7 +14,7 @@ function InventoriesEdit($scope, $rootScope, $compile, $location,
|
||||
$log, $stateParams, InventoryForm, Rest, Alert, ProcessErrors,
|
||||
ClearScope, GetBasePath, ParseTypeChange, Wait, ToJSON,
|
||||
ParseVariableString, Prompt, InitiatePlaybookRun,
|
||||
JobTemplateService, $state, $filter) {
|
||||
TemplatesService, $state, $filter) {
|
||||
|
||||
// Inject dynamic view
|
||||
var defaultUrl = GetBasePath('inventory'),
|
||||
@ -146,7 +146,7 @@ function InventoriesEdit($scope, $rootScope, $compile, $location,
|
||||
action = function () {
|
||||
$('#prompt-modal').modal('hide');
|
||||
Wait('start');
|
||||
JobTemplateService.deleteJobTemplate(id)
|
||||
TemplatesService.deleteJobTemplate(id)
|
||||
.success(function () {
|
||||
$('#prompt-modal').modal('hide');
|
||||
// @issue: OLD SEARCH
|
||||
@ -174,5 +174,5 @@ export default ['$scope', '$rootScope', '$compile', '$location',
|
||||
'$log', '$stateParams', 'InventoryForm', 'Rest', 'Alert',
|
||||
'ProcessErrors', 'ClearScope', 'GetBasePath', 'ParseTypeChange', 'Wait',
|
||||
'ToJSON', 'ParseVariableString', 'Prompt', 'InitiatePlaybookRun',
|
||||
'JobTemplateService', '$state', '$filter', InventoriesEdit,
|
||||
'TemplatesService', '$state', '$filter', InventoriesEdit,
|
||||
];
|
||||
|
||||
@ -1,127 +0,0 @@
|
||||
export default ['CreateDialog', 'Wait', '$q', '$state', function(CreateDialog, Wait, $q, $state){
|
||||
return {
|
||||
closeDialog: function() {
|
||||
$('#workflow-modal-dialog').dialog('destroy');
|
||||
|
||||
$state.go('^');
|
||||
},
|
||||
searchTree: function(params) {
|
||||
// params.element
|
||||
// params.matchingId
|
||||
|
||||
if(params.element.id === params.matchingId){
|
||||
return params.element;
|
||||
}else if (params.element.children && params.element.children.length > 0){
|
||||
let result = null;
|
||||
const thisService = this;
|
||||
_.forEach(params.element.children, function(child) {
|
||||
result = thisService.searchTree({
|
||||
element: child,
|
||||
matchingId: params.matchingId
|
||||
});
|
||||
if(result) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
removeNodeFromTree: function(params) {
|
||||
// params.tree
|
||||
// params.nodeToBeDeleted
|
||||
|
||||
let parentNode = this.searchTree({
|
||||
element: params.tree,
|
||||
matchingId: params.nodeToBeDeleted.parent.id
|
||||
});
|
||||
let nodeToBeDeleted = this.searchTree({
|
||||
element: parentNode,
|
||||
matchingId: params.nodeToBeDeleted.id
|
||||
});
|
||||
|
||||
if(nodeToBeDeleted.children) {
|
||||
_.forEach(nodeToBeDeleted.children, function(child) {
|
||||
if(nodeToBeDeleted.isRoot) {
|
||||
child.isRoot = true;
|
||||
child.edgeType = "always";
|
||||
}
|
||||
|
||||
parentNode.children.push(child);
|
||||
});
|
||||
}
|
||||
|
||||
_.forEach(parentNode.children, function(child, index) {
|
||||
if(child.id === params.nodeToBeDeleted.id) {
|
||||
parentNode.children.splice(index, 1);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
addPlaceholderNode: function(params) {
|
||||
// params.parent
|
||||
// params.betweenTwoNodes
|
||||
// params.tree
|
||||
// params.id
|
||||
|
||||
let placeholder = {
|
||||
children: [],
|
||||
c: "#D7D7D7",
|
||||
id: params.id,
|
||||
canDelete: true,
|
||||
canEdit: false,
|
||||
canAddTo: true,
|
||||
placeholder: true,
|
||||
isNew: true,
|
||||
edited: false
|
||||
};
|
||||
|
||||
let parentNode = (params.betweenTwoNodes) ? this.searchTree({element: params.tree, matchingId: params.parent.source.id}) : this.searchTree({element: params.tree, matchingId: params.parent.id});
|
||||
let placeholderRef;
|
||||
|
||||
if(params.betweenTwoNodes) {
|
||||
_.forEach(parentNode.children, function(child, index) {
|
||||
if(child.id === params.parent.target.id) {
|
||||
placeholder.children.push(angular.copy(child));
|
||||
parentNode.children[index] = placeholder;
|
||||
placeholderRef = parentNode.children[index];
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
if(parentNode.children) {
|
||||
parentNode.children.push(placeholder);
|
||||
placeholderRef = parentNode.children[parentNode.children.length - 1];
|
||||
} else {
|
||||
parentNode.children = [placeholder];
|
||||
placeholderRef = parentNode.children[0];
|
||||
}
|
||||
}
|
||||
|
||||
return placeholderRef;
|
||||
},
|
||||
getSiblingConnectionTypes: function(params) {
|
||||
// params.parentId
|
||||
// params.tree
|
||||
|
||||
let siblingConnectionTypes = {};
|
||||
|
||||
let parentNode = this.searchTree({
|
||||
element: params.tree,
|
||||
matchingId: params.parentId
|
||||
});
|
||||
|
||||
if(parentNode.children && parentNode.children.length > 0) {
|
||||
// Loop across them and add the types as keys to siblingConnectionTypes
|
||||
_.forEach(parentNode.children, function(child) {
|
||||
if(!child.placeholder && child.edgeType) {
|
||||
siblingConnectionTypes[child.edgeType] = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return Object.keys(siblingConnectionTypes);
|
||||
}
|
||||
};
|
||||
}];
|
||||
@ -16,7 +16,6 @@ import InventoryHosts from "./lists/InventoryHosts";
|
||||
import InventorySources from "./lists/InventorySources";
|
||||
import JobEvents from "./lists/JobEvents";
|
||||
import JobHosts from "./lists/JobHosts";
|
||||
import JobTemplates from "./lists/JobTemplates";
|
||||
import Jobs from "./lists/Jobs";
|
||||
import Organizations from "./lists/Organizations";
|
||||
import PortalJobTemplates from "./lists/PortalJobTemplates";
|
||||
@ -27,6 +26,7 @@ import ScheduledJobs from "./lists/ScheduledJobs";
|
||||
import Schedules from "./lists/Schedules";
|
||||
import Streams from "./lists/Streams";
|
||||
import Teams from "./lists/Teams";
|
||||
import Templates from "./lists/Templates";
|
||||
import Users from "./lists/Users";
|
||||
|
||||
export
|
||||
@ -42,7 +42,6 @@ export
|
||||
InventorySources,
|
||||
JobEvents,
|
||||
JobHosts,
|
||||
JobTemplates,
|
||||
Jobs,
|
||||
Organizations,
|
||||
PortalJobTemplates,
|
||||
@ -53,5 +52,6 @@ export
|
||||
Schedules,
|
||||
Streams,
|
||||
Teams,
|
||||
Templates,
|
||||
Users
|
||||
};
|
||||
|
||||
@ -6,8 +6,8 @@
|
||||
|
||||
|
||||
export default
|
||||
angular.module('JobTemplatesListDefinition', [])
|
||||
.factory('JobTemplateList', ['i18n', function(i18n) {
|
||||
angular.module('TemplatesListDefinition', [])
|
||||
.factory('TemplateList', ['i18n', function(i18n) {
|
||||
return {
|
||||
|
||||
name: 'templates',
|
||||
@ -288,13 +288,15 @@ export default [{
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}],
|
||||
OrgJobTemplateList: ['JobTemplateList', 'GetBasePath', '$stateParams', function(JobTemplateList) {
|
||||
let list = _.cloneDeep(JobTemplateList);
|
||||
OrgJobTemplateList: ['TemplateList', 'GetBasePath', '$stateParams', function(TemplateList) {
|
||||
let list = _.cloneDeep(TemplateList);
|
||||
delete list.actions;
|
||||
// @issue Why is the delete action unavailable in this view?
|
||||
delete list.fieldActions.delete;
|
||||
list.emptyListText = "This list is populated by job templates added from the <a ui-sref='jobTemplates.add'>Job Templates</a> section";
|
||||
list.searchSize = "col-lg-12 col-md-12 col-sm-12 col-xs-12";
|
||||
list.iterator = 'job_template';
|
||||
list.name = 'job_templates';
|
||||
return list;
|
||||
}],
|
||||
OrgJobTemplateDataset: ['OrgJobTemplateList', 'QuerySet', '$stateParams', 'GetBasePath',
|
||||
|
||||
@ -9,7 +9,7 @@ import route from './job-templates-copy.route';
|
||||
import service from './job-templates-copy.service';
|
||||
|
||||
export default
|
||||
angular.module('jobTemplates.copy', [])
|
||||
angular.module('templates.copy', [])
|
||||
.service('jobTemplateCopyService', service)
|
||||
.controller('jobTemplateCopyController', controller)
|
||||
.run(['$stateExtender', function($stateExtender) {
|
||||
@ -12,7 +12,7 @@ export default
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: false,
|
||||
templateUrl: templateUrl('job-templates/labels/labelsList'),
|
||||
templateUrl: templateUrl('templates/labels/labelsList'),
|
||||
link: function(scope, element, attrs) {
|
||||
scope.showDelete = attrs.showDelete === 'true';
|
||||
scope.seeMoreInactive = true;
|
||||
@ -4,8 +4,8 @@
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
import controller from './job-templates-list.controller';
|
||||
import controller from './templates-list.controller';
|
||||
|
||||
export default
|
||||
angular.module('jobTemplatesList', [])
|
||||
.controller('JobTemplatesListController', controller);
|
||||
angular.module('templatesList', [])
|
||||
.controller('TemplatesListController', controller);
|
||||
@ -5,18 +5,18 @@
|
||||
*************************************************/
|
||||
|
||||
export default ['$scope', '$rootScope', '$location', '$stateParams', 'Rest', 'Alert',
|
||||
'JobTemplateList', 'Prompt', 'ClearScope', 'ProcessErrors', 'GetBasePath',
|
||||
'InitiatePlaybookRun', 'Wait', '$state', '$filter', 'Dataset', 'rbacUiControlService', 'JobTemplateService',
|
||||
'TemplateList', 'Prompt', 'ClearScope', 'ProcessErrors', 'GetBasePath',
|
||||
'InitiatePlaybookRun', 'Wait', '$state', '$filter', 'Dataset', 'rbacUiControlService', 'TemplatesService',
|
||||
'QuerySet',
|
||||
function(
|
||||
$scope, $rootScope, $location, $stateParams, Rest, Alert,
|
||||
JobTemplateList, Prompt, ClearScope, ProcessErrors, GetBasePath,
|
||||
InitiatePlaybookRun, Wait, $state, $filter, Dataset, rbacUiControlService, JobTemplateService,
|
||||
TemplateList, Prompt, ClearScope, ProcessErrors, GetBasePath,
|
||||
InitiatePlaybookRun, Wait, $state, $filter, Dataset, rbacUiControlService, TemplatesService,
|
||||
qs
|
||||
) {
|
||||
ClearScope();
|
||||
|
||||
var list = JobTemplateList;
|
||||
var list = TemplateList;
|
||||
|
||||
init();
|
||||
|
||||
@ -95,7 +95,7 @@ export default ['$scope', '$rootScope', '$location', '$stateParams', 'Rest', 'Al
|
||||
$('#prompt-modal').modal('hide');
|
||||
Wait('start');
|
||||
if(template.type && (template.type === 'Workflow Job Template' || template.type === 'workflow_job_template')) {
|
||||
JobTemplateService.deleteWorkflowJobTemplate(template.id)
|
||||
TemplatesService.deleteWorkflowJobTemplate(template.id)
|
||||
.then(function () {
|
||||
handleSuccessfulDelete();
|
||||
}, function (data) {
|
||||
@ -105,7 +105,7 @@ export default ['$scope', '$rootScope', '$location', '$stateParams', 'Rest', 'Al
|
||||
});
|
||||
}
|
||||
else if(template.type && (template.type === 'Job Template' || template.type === 'job_template')) {
|
||||
JobTemplateService.deleteJobTemplate(template.id)
|
||||
TemplatesService.deleteJobTemplate(template.id)
|
||||
.then(function () {
|
||||
handleSuccessfulDelete();
|
||||
}, function (data) {
|
||||
@ -27,10 +27,10 @@ export default {
|
||||
searchPrefix: 'template',
|
||||
views: {
|
||||
'@': {
|
||||
controller: 'JobTemplatesListController',
|
||||
templateProvider: function(JobTemplateList, generateList) {
|
||||
controller: 'TemplatesListController',
|
||||
templateProvider: function(TemplateList, generateList) {
|
||||
let html = generateList.build({
|
||||
list: JobTemplateList,
|
||||
list: TemplateList,
|
||||
mode: 'edit'
|
||||
});
|
||||
html = generateList.wrapPanel(html);
|
||||
@ -39,7 +39,7 @@ export default {
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
Dataset: ['JobTemplateList', 'QuerySet', '$stateParams', 'GetBasePath',
|
||||
Dataset: ['TemplateList', 'QuerySet', '$stateParams', 'GetBasePath',
|
||||
function(list, qs, $stateParams, GetBasePath) {
|
||||
let path = GetBasePath(list.basePath) || GetBasePath(list.name);
|
||||
return qs.search(path, $stateParams[`${list.iterator}_search`]);
|
||||
@ -4,26 +4,27 @@
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
import jobTemplateService from './job-template.service';
|
||||
|
||||
import templatesService from './templates.service';
|
||||
import surveyMaker from './survey-maker/main';
|
||||
import jobTemplatesList from './list/main';
|
||||
import jobTemplatesAdd from './add-job-template/main';
|
||||
import jobTemplatesEdit from './edit-job-template/main';
|
||||
import jobTemplatesCopy from './copy/main';
|
||||
import workflowAdd from './add-workflow/main';
|
||||
import workflowEdit from './edit-workflow/main';
|
||||
import templatesList from './list/main';
|
||||
import jobTemplatesAdd from './job_templates/add-job-template/main';
|
||||
import jobTemplatesEdit from './job_templates/edit-job-template/main';
|
||||
import jobTemplatesCopy from './job_templates/copy-job-template/main';
|
||||
import workflowAdd from './workflows/add-workflow/main';
|
||||
import workflowEdit from './workflows/edit-workflow/main';
|
||||
import labels from './labels/main';
|
||||
import workflowChart from './workflow-chart/main';
|
||||
import workflowMaker from './workflow-maker/main';
|
||||
import jobTemplatesListRoute from './list/job-templates-list.route';
|
||||
import workflowChart from './workflows/workflow-chart/main';
|
||||
import workflowMaker from './workflows/workflow-maker/main';
|
||||
import templatesListRoute from './list/templates-list.route';
|
||||
import workflowService from './workflows/workflow.service';
|
||||
|
||||
export default
|
||||
angular.module('jobTemplates', [surveyMaker.name, jobTemplatesList.name, jobTemplatesAdd.name,
|
||||
angular.module('templates', [surveyMaker.name, templatesList.name, jobTemplatesAdd.name,
|
||||
jobTemplatesEdit.name, jobTemplatesCopy.name, labels.name, workflowAdd.name, workflowEdit.name,
|
||||
workflowChart.name, workflowMaker.name
|
||||
])
|
||||
.service('JobTemplateService', jobTemplateService)
|
||||
.service('TemplatesService', templatesService)
|
||||
.service('WorkflowService', workflowService)
|
||||
.config(['$stateProvider', 'stateDefinitionsProvider', '$stateExtenderProvider',
|
||||
function($stateProvider, stateDefinitionsProvider, $stateExtenderProvider) {
|
||||
let stateTree, addJobTemplate, editJobTemplate, addWorkflow, editWorkflow,
|
||||
@ -332,9 +333,9 @@ angular.module('jobTemplates', [surveyMaker.name, jobTemplatesList.name, jobTemp
|
||||
return qs.search(path, $stateParams[`${list.iterator}_search`]);
|
||||
}
|
||||
],
|
||||
WorkflowMakerJobTemplateList: ['JobTemplateList',
|
||||
(JobTemplateList) => {
|
||||
let list = _.cloneDeep(JobTemplateList);
|
||||
WorkflowMakerJobTemplateList: ['TemplateList',
|
||||
(TemplateList) => {
|
||||
let list = _.cloneDeep(TemplateList);
|
||||
delete list.fields.type;
|
||||
delete list.fields.description;
|
||||
delete list.fields.smart_status;
|
||||
@ -472,7 +473,7 @@ angular.module('jobTemplates', [surveyMaker.name, jobTemplatesList.name, jobTemp
|
||||
states: _.reduce(generated, (result, definition) => {
|
||||
return result.concat(definition.states);
|
||||
}, [
|
||||
stateExtender.buildDefinition(jobTemplatesListRoute),
|
||||
stateExtender.buildDefinition(templatesListRoute),
|
||||
stateExtender.buildDefinition(workflowMaker),
|
||||
stateExtender.buildDefinition(inventoryLookup),
|
||||
stateExtender.buildDefinition(credentialLookup)
|
||||
@ -5,7 +5,7 @@ import render from './render/main';
|
||||
import shared from './shared/main';
|
||||
|
||||
export default
|
||||
angular.module('jobTemplates.surveyMaker',
|
||||
angular.module('templates.surveyMaker',
|
||||
[ listGenerator.name,
|
||||
questions.name,
|
||||
surveys.name,
|
||||
@ -6,11 +6,11 @@
|
||||
|
||||
export default
|
||||
[ '$scope', 'WorkflowForm', 'GenerateForm', 'Alert', 'ProcessErrors', 'ClearScope',
|
||||
'Wait', '$state', 'CreateSelect2', 'JobTemplateService', 'ToJSON',
|
||||
'Wait', '$state', 'CreateSelect2', 'TemplatesService', 'ToJSON',
|
||||
'ParseTypeChange', 'OrganizationList', '$q', 'Rest', 'GetBasePath',
|
||||
function(
|
||||
$scope, WorkflowForm, GenerateForm, Alert, ProcessErrors, ClearScope,
|
||||
Wait, $state, CreateSelect2, JobTemplateService, ToJSON,
|
||||
Wait, $state, CreateSelect2, TemplatesService, ToJSON,
|
||||
ParseTypeChange, OrganizationList, $q, Rest, GetBasePath
|
||||
) {
|
||||
|
||||
@ -45,7 +45,7 @@
|
||||
});
|
||||
|
||||
// Go out and grab the possible labels
|
||||
JobTemplateService.getLabelOptions()
|
||||
TemplatesService.getLabelOptions()
|
||||
.then(function(data){
|
||||
$scope.labelOptions = data;
|
||||
// select2-ify the labels input
|
||||
@ -98,7 +98,7 @@
|
||||
.filter("[data-label-is-present=true]")
|
||||
.map((i, val) => ({name: $(val).text()}));
|
||||
|
||||
JobTemplateService.createWorkflowJobTemplate(data)
|
||||
TemplatesService.createWorkflowJobTemplate(data)
|
||||
.then(function(data) {
|
||||
|
||||
let orgDefer = $q.defer();
|
||||
@ -8,13 +8,13 @@
|
||||
[ '$scope', '$stateParams', 'WorkflowForm', 'GenerateForm', 'Alert', 'ProcessErrors',
|
||||
'ClearScope', 'GetBasePath', '$q', 'ParseTypeChange', 'Wait', 'Empty',
|
||||
'ToJSON', 'initSurvey', '$state', 'CreateSelect2', 'ParseVariableString',
|
||||
'JobTemplateService', 'OrganizationList', 'Rest',
|
||||
'TemplatesService', 'OrganizationList', 'Rest', 'WorkflowService',
|
||||
function(
|
||||
$scope, $stateParams, WorkflowForm, GenerateForm, Alert, ProcessErrors,
|
||||
ClearScope, GetBasePath, $q, ParseTypeChange, Wait, Empty,
|
||||
ToJSON, SurveyControllerInit, $state, CreateSelect2, ParseVariableString,
|
||||
JobTemplateService, OrganizationList, Rest
|
||||
) {window.state = $state;
|
||||
TemplatesService, OrganizationList, Rest, WorkflowService
|
||||
) {
|
||||
|
||||
ClearScope();
|
||||
|
||||
@ -40,90 +40,6 @@
|
||||
$scope.associateRequests = [];
|
||||
$scope.disassociateRequests = [];
|
||||
|
||||
$scope.workflowTree = {
|
||||
data: {
|
||||
id: 1,
|
||||
canDelete: false,
|
||||
canEdit: false,
|
||||
canAddTo: true,
|
||||
isStartNode: true,
|
||||
unifiedJobTemplate: {
|
||||
name: "Workflow Launch"
|
||||
},
|
||||
children: [],
|
||||
deletedNodes: [],
|
||||
totalNodes: 0
|
||||
},
|
||||
nextIndex: 2
|
||||
};
|
||||
|
||||
function buildBranch(params) {
|
||||
// params.nodeId
|
||||
// params.parentId
|
||||
// params.edgeType
|
||||
// params.nodesObj
|
||||
// params.isRoot
|
||||
|
||||
let treeNode = {
|
||||
children: [],
|
||||
c: "#D7D7D7",
|
||||
id: $scope.workflowTree.nextIndex,
|
||||
nodeId: params.nodeId,
|
||||
canDelete: true,
|
||||
canEdit: true,
|
||||
canAddTo: true,
|
||||
placeholder: false,
|
||||
edgeType: params.edgeType,
|
||||
unifiedJobTemplate: _.clone(params.nodesObj[params.nodeId].summary_fields.unified_job_template),
|
||||
isNew: false,
|
||||
edited: false,
|
||||
originalEdge: params.edgeType,
|
||||
originalNodeObj: _.clone(params.nodesObj[params.nodeId]),
|
||||
promptValues: {},
|
||||
isRoot: params.isRoot ? params.isRoot : false
|
||||
};
|
||||
|
||||
$scope.workflowTree.data.totalNodes++;
|
||||
|
||||
$scope.workflowTree.nextIndex++;
|
||||
|
||||
if(params.parentId) {
|
||||
treeNode.originalParentId = params.parentId;
|
||||
}
|
||||
|
||||
// Loop across the success nodes and add them recursively
|
||||
_.forEach(params.nodesObj[params.nodeId].success_nodes, function(successNodeId) {
|
||||
treeNode.children.push(buildBranch({
|
||||
nodeId: successNodeId,
|
||||
parentId: params.nodeId,
|
||||
edgeType: "success",
|
||||
nodesObj: params.nodesObj
|
||||
}));
|
||||
});
|
||||
|
||||
// failure nodes
|
||||
_.forEach(params.nodesObj[params.nodeId].failure_nodes, function(failureNodesId) {
|
||||
treeNode.children.push(buildBranch({
|
||||
nodeId: failureNodesId,
|
||||
parentId: params.nodeId,
|
||||
edgeType: "failure",
|
||||
nodesObj: params.nodesObj
|
||||
}));
|
||||
});
|
||||
|
||||
// always nodes
|
||||
_.forEach(params.nodesObj[params.nodeId].always_nodes, function(alwaysNodesId) {
|
||||
treeNode.children.push(buildBranch({
|
||||
nodeId: alwaysNodesId,
|
||||
parentId: params.nodeId,
|
||||
edgeType: "always",
|
||||
nodesObj: params.nodesObj
|
||||
}));
|
||||
});
|
||||
|
||||
return treeNode;
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
// Select2-ify the lables input
|
||||
@ -192,43 +108,11 @@
|
||||
});
|
||||
|
||||
// Get the workflow nodes
|
||||
JobTemplateService.getWorkflowJobTemplateNodes(id)
|
||||
TemplatesService.getWorkflowJobTemplateNodes(id)
|
||||
.then(function(data){
|
||||
|
||||
let nodesArray = data.data.results;
|
||||
let nodesObj = {};
|
||||
let nonRootNodeIds = [];
|
||||
let allNodeIds = [];
|
||||
|
||||
// Determine which nodes are root nodes
|
||||
_.forEach(nodesArray, function(node) {
|
||||
nodesObj[node.id] = _.clone(node);
|
||||
|
||||
allNodeIds.push(node.id);
|
||||
|
||||
_.forEach(node.success_nodes, function(nodeId){
|
||||
nonRootNodeIds.push(nodeId);
|
||||
});
|
||||
_.forEach(node.failure_nodes, function(nodeId){
|
||||
nonRootNodeIds.push(nodeId);
|
||||
});
|
||||
_.forEach(node.always_nodes, function(nodeId){
|
||||
nonRootNodeIds.push(nodeId);
|
||||
});
|
||||
});
|
||||
|
||||
let rootNodes = _.difference(allNodeIds, nonRootNodeIds);
|
||||
|
||||
// Loop across the root nodes and re-build the tree
|
||||
_.forEach(rootNodes, function(rootNodeId) {
|
||||
let branch = buildBranch({
|
||||
nodeId: rootNodeId,
|
||||
edgeType: "always",
|
||||
nodesObj: nodesObj,
|
||||
isRoot: true
|
||||
});
|
||||
|
||||
$scope.workflowTree.data.children.push(branch);
|
||||
$scope.workflowTree = WorkflowService.buildTree({
|
||||
workflowNodes: data.data.results
|
||||
});
|
||||
|
||||
// TODO: I think that the workflow chart directive (and eventually d3) is meddling with
|
||||
@ -251,7 +135,7 @@
|
||||
});
|
||||
|
||||
// Go out and GET the workflow job temlate data needed to populate the form
|
||||
JobTemplateService.getWorkflowJobTemplate(id)
|
||||
TemplatesService.getWorkflowJobTemplate(id)
|
||||
.then(function(data){
|
||||
let workflowJobTemplateData = data.data;
|
||||
$scope.workflow_job_template_obj = workflowJobTemplateData;
|
||||
@ -392,7 +276,7 @@
|
||||
|
||||
if(params.node.isNew) {
|
||||
|
||||
JobTemplateService.addWorkflowNode({
|
||||
TemplatesService.addWorkflowNode({
|
||||
url: generatePostUrl(),
|
||||
data: buildSendableNodeData()
|
||||
})
|
||||
@ -500,7 +384,7 @@
|
||||
// these promise arrays to play nicely. I tried to just append
|
||||
// a single promise to deletePromises but it just wasn't working
|
||||
let editWorkflowJobTemplate = [id].map(function(id) {
|
||||
return JobTemplateService.updateWorkflowJobTemplate({
|
||||
return TemplatesService.updateWorkflowJobTemplate({
|
||||
id: id,
|
||||
data: data
|
||||
});
|
||||
@ -510,7 +394,7 @@
|
||||
let completionCallback = function() {
|
||||
|
||||
let disassociatePromises = $scope.disassociateRequests.map(function(request) {
|
||||
return JobTemplateService.disassociateWorkflowNode({
|
||||
return TemplatesService.disassociateWorkflowNode({
|
||||
parentId: request.parentId,
|
||||
nodeId: request.nodeId,
|
||||
edge: request.edge
|
||||
@ -518,7 +402,7 @@
|
||||
});
|
||||
|
||||
let editNodePromises = $scope.editRequests.map(function(request) {
|
||||
return JobTemplateService.editWorkflowNode({
|
||||
return TemplatesService.editWorkflowNode({
|
||||
id: request.id,
|
||||
data: request.data
|
||||
});
|
||||
@ -528,7 +412,7 @@
|
||||
.then(function() {
|
||||
|
||||
let associatePromises = $scope.associateRequests.map(function(request) {
|
||||
return JobTemplateService.associateWorkflowNode({
|
||||
return TemplatesService.associateWorkflowNode({
|
||||
parentId: request.parentId,
|
||||
nodeId: request.nodeId,
|
||||
edge: request.edge
|
||||
@ -536,7 +420,7 @@
|
||||
});
|
||||
|
||||
let deletePromises = $scope.workflowTree.data.deletedNodes.map(function(nodeId) {
|
||||
return JobTemplateService.deleteWorkflowJobTemplateNode(nodeId);
|
||||
return TemplatesService.deleteWorkflowJobTemplateNode(nodeId);
|
||||
});
|
||||
|
||||
$q.all(associatePromises.concat(deletePromises))
|
||||
@ -634,7 +518,7 @@
|
||||
else {
|
||||
|
||||
let deletePromises = $scope.workflowTree.data.deletedNodes.map(function(nodeId) {
|
||||
return JobTemplateService.deleteWorkflowJobTemplateNode(nodeId);
|
||||
return TemplatesService.deleteWorkflowJobTemplateNode(nodeId);
|
||||
});
|
||||
|
||||
$q.all(deletePromises.concat(editWorkflowJobTemplate))
|
||||
@ -7,5 +7,5 @@
|
||||
import workflowChart from './workflow-chart.directive';
|
||||
|
||||
export default
|
||||
angular.module('jobTemplatesWorkflowChart', [])
|
||||
angular.module('workflowChart', [])
|
||||
.directive('workflowChart', workflowChart);
|
||||
@ -1,10 +1,8 @@
|
||||
import helper from './workflow-help.service';
|
||||
import workflowMaker from './workflow-maker.directive';
|
||||
import WorkflowMakerController from './workflow-maker.controller';
|
||||
|
||||
export default
|
||||
angular.module('jobTemplates.workflowMaker', [])
|
||||
.service('WorkflowHelpService', helper)
|
||||
angular.module('templates.workflowMaker', [])
|
||||
// In order to test this controller I had to expose it at the module level
|
||||
// like so. Is this correct? Is there a better pattern for doing this?
|
||||
.controller('WorkflowMakerController', WorkflowMakerController)
|
||||
@ -4,12 +4,12 @@
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
export default ['$scope', 'WorkflowHelpService', 'generateList', 'JobTemplateList', 'ProjectList',
|
||||
'GetBasePath', 'Wait', 'JobTemplateService', '$state',
|
||||
export default ['$scope', 'WorkflowService', 'generateList', 'TemplateList', 'ProjectList',
|
||||
'GetBasePath', 'Wait', 'TemplatesService', '$state',
|
||||
'ProcessErrors', 'InventorySourcesList', 'CreateSelect2', 'WorkflowMakerForm',
|
||||
'GenerateForm', 'InventoryList', 'CredentialList', '$q',
|
||||
function($scope, WorkflowHelpService, GenerateList, JobTemplateList, ProjectList,
|
||||
GetBasePath, Wait, JobTemplateService, $state,
|
||||
function($scope, WorkflowService, GenerateList, TemplateList, ProjectList,
|
||||
GetBasePath, Wait, TemplatesService, $state,
|
||||
ProcessErrors, InventorySourcesList, CreateSelect2, WorkflowMakerForm,
|
||||
GenerateForm, InventoryList, CredentialList, $q) {
|
||||
|
||||
@ -59,11 +59,11 @@ export default ['$scope', 'WorkflowHelpService', 'generateList', 'JobTemplateLis
|
||||
$scope.closeWorkflowMaker = function() {
|
||||
// Revert the data to the master which was created when the dialog was opened
|
||||
$scope.treeData.data = angular.copy($scope.treeDataMaster);
|
||||
WorkflowHelpService.closeDialog();
|
||||
$scope.closeDialog();
|
||||
};
|
||||
|
||||
$scope.saveWorkflowMaker = function() {
|
||||
WorkflowHelpService.closeDialog();
|
||||
$scope.closeDialog();
|
||||
};
|
||||
|
||||
/* ADD NODE FUNCTIONS */
|
||||
@ -78,7 +78,7 @@ export default ['$scope', 'WorkflowHelpService', 'generateList', 'JobTemplateLis
|
||||
$scope.addParent = parent;
|
||||
$scope.betweenTwoNodes = betweenTwoNodes;
|
||||
|
||||
$scope.placeholderNode = WorkflowHelpService.addPlaceholderNode({
|
||||
$scope.placeholderNode = WorkflowService.addPlaceholderNode({
|
||||
parent: parent,
|
||||
betweenTwoNodes: betweenTwoNodes,
|
||||
tree: $scope.treeData.data,
|
||||
@ -87,7 +87,7 @@ export default ['$scope', 'WorkflowHelpService', 'generateList', 'JobTemplateLis
|
||||
|
||||
$scope.treeData.nextIndex++;
|
||||
|
||||
let siblingConnectionTypes = WorkflowHelpService.getSiblingConnectionTypes({
|
||||
let siblingConnectionTypes = WorkflowService.getSiblingConnectionTypes({
|
||||
tree: $scope.treeData.data,
|
||||
parentId: betweenTwoNodes ? parent.source.id : parent.id
|
||||
});
|
||||
@ -187,7 +187,7 @@ export default ['$scope', 'WorkflowHelpService', 'generateList', 'JobTemplateLis
|
||||
$scope.cancelNodeForm = function() {
|
||||
if ($scope.workflowMakerFormConfig.nodeMode === "add") {
|
||||
// Remove the placeholder node from the tree
|
||||
WorkflowHelpService.removeNodeFromTree({
|
||||
WorkflowService.removeNodeFromTree({
|
||||
tree: $scope.treeData.data,
|
||||
nodeToBeDeleted: $scope.placeholderNode
|
||||
});
|
||||
@ -212,12 +212,12 @@ export default ['$scope', 'WorkflowHelpService', 'generateList', 'JobTemplateLis
|
||||
|
||||
$scope.workflowMakerFormConfig.nodeMode = "edit";
|
||||
|
||||
let parent = WorkflowHelpService.searchTree({
|
||||
let parent = WorkflowService.searchTree({
|
||||
element: $scope.treeData.data,
|
||||
matchingId: nodeToEdit.parent.id
|
||||
});
|
||||
|
||||
$scope.nodeBeingEdited = WorkflowHelpService.searchTree({
|
||||
$scope.nodeBeingEdited = WorkflowService.searchTree({
|
||||
element: parent,
|
||||
matchingId: nodeToEdit.id
|
||||
});
|
||||
@ -348,7 +348,7 @@ export default ['$scope', 'WorkflowHelpService', 'generateList', 'JobTemplateLis
|
||||
// This is a node that we got back from the api with an incomplete
|
||||
// unified job template so we're going to pull down the whole object
|
||||
|
||||
JobTemplateService.getUnifiedJobTemplate($scope.nodeBeingEdited.unifiedJobTemplate.id)
|
||||
TemplatesService.getUnifiedJobTemplate($scope.nodeBeingEdited.unifiedJobTemplate.id)
|
||||
.then(function(data) {
|
||||
|
||||
$scope.nodeBeingEdited.unifiedJobTemplate = _.clone(data.data.results[0]);
|
||||
@ -358,12 +358,12 @@ export default ['$scope', 'WorkflowHelpService', 'generateList', 'JobTemplateLis
|
||||
let retrievingInventory = false;
|
||||
|
||||
if ($scope.nodeBeingEdited.unifiedJobTemplate.ask_credential_on_launch && $scope.nodeBeingEdited.originalNodeObj.credential) {
|
||||
defers.push(JobTemplateService.getCredential($scope.nodeBeingEdited.originalNodeObj.credential));
|
||||
defers.push(TemplatesService.getCredential($scope.nodeBeingEdited.originalNodeObj.credential));
|
||||
retrievingCredential = true;
|
||||
}
|
||||
|
||||
if ($scope.nodeBeingEdited.unifiedJobTemplate.ask_inventory_on_launch && $scope.nodeBeingEdited.originalNodeObj.inventory) {
|
||||
defers.push(JobTemplateService.getInventory($scope.nodeBeingEdited.originalNodeObj.inventory));
|
||||
defers.push(TemplatesService.getInventory($scope.nodeBeingEdited.originalNodeObj.inventory));
|
||||
retrievingInventory = true;
|
||||
}
|
||||
|
||||
@ -427,7 +427,7 @@ export default ['$scope', 'WorkflowHelpService', 'generateList', 'JobTemplateLis
|
||||
|
||||
// TODO: turn this into a promise so that we can handle errors
|
||||
|
||||
WorkflowHelpService.removeNodeFromTree({
|
||||
WorkflowService.removeNodeFromTree({
|
||||
tree: $scope.treeData.data,
|
||||
nodeToBeDeleted: $scope.nodeToBeDeleted
|
||||
});
|
||||
@ -6,15 +6,15 @@
|
||||
|
||||
import workflowMakerController from './workflow-maker.controller';
|
||||
|
||||
export default ['templateUrl', 'CreateDialog', 'Wait',
|
||||
function(templateUrl, CreateDialog, Wait) {
|
||||
export default ['templateUrl', 'CreateDialog', 'Wait', '$state',
|
||||
function(templateUrl, CreateDialog, Wait, $state) {
|
||||
return {
|
||||
scope: {
|
||||
treeData: '=',
|
||||
canAddWorkflowJobTemplate: '='
|
||||
},
|
||||
restrict: 'E',
|
||||
templateUrl: templateUrl('job-templates/workflow-maker/workflow-maker'),
|
||||
templateUrl: templateUrl('templates/workflows/workflow-maker/workflow-maker'),
|
||||
controller: workflowMakerController,
|
||||
link: function(scope) {
|
||||
CreateDialog({
|
||||
@ -49,6 +49,12 @@ export default ['templateUrl', 'CreateDialog', 'Wait',
|
||||
|
||||
scope.$broadcast("refreshWorkflowChart");
|
||||
});
|
||||
|
||||
scope.closeDialog = function() {
|
||||
$('#workflow-modal-dialog').dialog('destroy');
|
||||
|
||||
$state.go('^');
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
255
awx/ui/client/src/templates/workflows/workflow.service.js
Normal file
255
awx/ui/client/src/templates/workflows/workflow.service.js
Normal file
@ -0,0 +1,255 @@
|
||||
export default [function(){
|
||||
return {
|
||||
searchTree: function(params) {
|
||||
// params.element
|
||||
// params.matchingId
|
||||
|
||||
if(params.element.id === params.matchingId){
|
||||
return params.element;
|
||||
}else if (params.element.children && params.element.children.length > 0){
|
||||
let result = null;
|
||||
const thisService = this;
|
||||
_.forEach(params.element.children, function(child) {
|
||||
result = thisService.searchTree({
|
||||
element: child,
|
||||
matchingId: params.matchingId
|
||||
});
|
||||
if(result) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
removeNodeFromTree: function(params) {
|
||||
// params.tree
|
||||
// params.nodeToBeDeleted
|
||||
|
||||
let parentNode = this.searchTree({
|
||||
element: params.tree,
|
||||
matchingId: params.nodeToBeDeleted.parent.id
|
||||
});
|
||||
let nodeToBeDeleted = this.searchTree({
|
||||
element: parentNode,
|
||||
matchingId: params.nodeToBeDeleted.id
|
||||
});
|
||||
|
||||
if(nodeToBeDeleted.children) {
|
||||
_.forEach(nodeToBeDeleted.children, function(child) {
|
||||
if(nodeToBeDeleted.isRoot) {
|
||||
child.isRoot = true;
|
||||
child.edgeType = "always";
|
||||
}
|
||||
|
||||
parentNode.children.push(child);
|
||||
});
|
||||
}
|
||||
|
||||
_.forEach(parentNode.children, function(child, index) {
|
||||
if(child.id === params.nodeToBeDeleted.id) {
|
||||
parentNode.children.splice(index, 1);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
addPlaceholderNode: function(params) {
|
||||
// params.parent
|
||||
// params.betweenTwoNodes
|
||||
// params.tree
|
||||
// params.id
|
||||
|
||||
let placeholder = {
|
||||
children: [],
|
||||
c: "#D7D7D7",
|
||||
id: params.id,
|
||||
canDelete: true,
|
||||
canEdit: false,
|
||||
canAddTo: true,
|
||||
placeholder: true,
|
||||
isNew: true,
|
||||
edited: false
|
||||
};
|
||||
|
||||
let parentNode = (params.betweenTwoNodes) ? this.searchTree({element: params.tree, matchingId: params.parent.source.id}) : this.searchTree({element: params.tree, matchingId: params.parent.id});
|
||||
let placeholderRef;
|
||||
|
||||
if(params.betweenTwoNodes) {
|
||||
_.forEach(parentNode.children, function(child, index) {
|
||||
if(child.id === params.parent.target.id) {
|
||||
placeholder.children.push(angular.copy(child));
|
||||
parentNode.children[index] = placeholder;
|
||||
placeholderRef = parentNode.children[index];
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
if(parentNode.children) {
|
||||
parentNode.children.push(placeholder);
|
||||
placeholderRef = parentNode.children[parentNode.children.length - 1];
|
||||
} else {
|
||||
parentNode.children = [placeholder];
|
||||
placeholderRef = parentNode.children[0];
|
||||
}
|
||||
}
|
||||
|
||||
return placeholderRef;
|
||||
},
|
||||
getSiblingConnectionTypes: function(params) {
|
||||
// params.parentId
|
||||
// params.tree
|
||||
|
||||
let siblingConnectionTypes = {};
|
||||
|
||||
let parentNode = this.searchTree({
|
||||
element: params.tree,
|
||||
matchingId: params.parentId
|
||||
});
|
||||
|
||||
if(parentNode.children && parentNode.children.length > 0) {
|
||||
// Loop across them and add the types as keys to siblingConnectionTypes
|
||||
_.forEach(parentNode.children, function(child) {
|
||||
if(!child.placeholder && child.edgeType) {
|
||||
siblingConnectionTypes[child.edgeType] = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return Object.keys(siblingConnectionTypes);
|
||||
},
|
||||
buildTree: function(params) {
|
||||
//params.workflowNodes
|
||||
|
||||
let _this = this;
|
||||
|
||||
let treeData = {
|
||||
data: {
|
||||
id: 1,
|
||||
canDelete: false,
|
||||
canEdit: false,
|
||||
canAddTo: true,
|
||||
isStartNode: true,
|
||||
unifiedJobTemplate: {
|
||||
name: "Workflow Launch"
|
||||
},
|
||||
children: [],
|
||||
deletedNodes: [],
|
||||
totalNodes: 0
|
||||
},
|
||||
nextIndex: 2
|
||||
};
|
||||
|
||||
let nodesArray = params.workflowNodes;
|
||||
let nodesObj = {};
|
||||
let nonRootNodeIds = [];
|
||||
let allNodeIds = [];
|
||||
|
||||
// Determine which nodes are root nodes
|
||||
_.forEach(nodesArray, function(node) {
|
||||
nodesObj[node.id] = _.clone(node);
|
||||
|
||||
allNodeIds.push(node.id);
|
||||
|
||||
_.forEach(node.success_nodes, function(nodeId){
|
||||
nonRootNodeIds.push(nodeId);
|
||||
});
|
||||
_.forEach(node.failure_nodes, function(nodeId){
|
||||
nonRootNodeIds.push(nodeId);
|
||||
});
|
||||
_.forEach(node.always_nodes, function(nodeId){
|
||||
nonRootNodeIds.push(nodeId);
|
||||
});
|
||||
});
|
||||
|
||||
let rootNodes = _.difference(allNodeIds, nonRootNodeIds);
|
||||
|
||||
// Loop across the root nodes and re-build the tree
|
||||
_.forEach(rootNodes, function(rootNodeId) {
|
||||
let branch = _this.buildBranch({
|
||||
nodeId: rootNodeId,
|
||||
edgeType: "always",
|
||||
nodesObj: nodesObj,
|
||||
isRoot: true,
|
||||
treeData: treeData
|
||||
});
|
||||
|
||||
treeData.data.children.push(branch);
|
||||
});
|
||||
|
||||
return treeData;
|
||||
},
|
||||
buildBranch: function(params) {
|
||||
// params.nodeId
|
||||
// params.parentId
|
||||
// params.edgeType
|
||||
// params.nodesObj
|
||||
// params.isRoot
|
||||
// params.treeData
|
||||
|
||||
let _this = this;
|
||||
|
||||
let treeNode = {
|
||||
children: [],
|
||||
c: "#D7D7D7",
|
||||
id: params.treeData.nextIndex,
|
||||
nodeId: params.nodeId,
|
||||
canDelete: true,
|
||||
canEdit: true,
|
||||
canAddTo: true,
|
||||
placeholder: false,
|
||||
edgeType: params.edgeType,
|
||||
unifiedJobTemplate: _.clone(params.nodesObj[params.nodeId].summary_fields.unified_job_template),
|
||||
isNew: false,
|
||||
edited: false,
|
||||
originalEdge: params.edgeType,
|
||||
originalNodeObj: _.clone(params.nodesObj[params.nodeId]),
|
||||
promptValues: {},
|
||||
isRoot: params.isRoot ? params.isRoot : false
|
||||
};
|
||||
|
||||
params.treeData.data.totalNodes++;
|
||||
|
||||
params.treeData.nextIndex++;
|
||||
|
||||
if(params.parentId) {
|
||||
treeNode.originalParentId = params.parentId;
|
||||
}
|
||||
|
||||
// Loop across the success nodes and add them recursively
|
||||
_.forEach(params.nodesObj[params.nodeId].success_nodes, function(successNodeId) {
|
||||
treeNode.children.push(_this.buildBranch({
|
||||
nodeId: successNodeId,
|
||||
parentId: params.nodeId,
|
||||
edgeType: "success",
|
||||
nodesObj: params.nodesObj,
|
||||
treeData: params.treeData
|
||||
}));
|
||||
});
|
||||
|
||||
// failure nodes
|
||||
_.forEach(params.nodesObj[params.nodeId].failure_nodes, function(failureNodesId) {
|
||||
treeNode.children.push(_this.buildBranch({
|
||||
nodeId: failureNodesId,
|
||||
parentId: params.nodeId,
|
||||
edgeType: "failure",
|
||||
nodesObj: params.nodesObj,
|
||||
treeData: params.treeData
|
||||
}));
|
||||
});
|
||||
|
||||
// always nodes
|
||||
_.forEach(params.nodesObj[params.nodeId].always_nodes, function(alwaysNodesId) {
|
||||
treeNode.children.push(_this.buildBranch({
|
||||
nodeId: alwaysNodesId,
|
||||
parentId: params.nodeId,
|
||||
edgeType: "always",
|
||||
nodesObj: params.nodesObj,
|
||||
treeData: params.treeData
|
||||
}));
|
||||
});
|
||||
|
||||
return treeNode;
|
||||
}
|
||||
};
|
||||
}];
|
||||
@ -6,6 +6,7 @@ export default ['workflowData',
|
||||
'$scope',
|
||||
'ParseTypeChange',
|
||||
'ParseVariableString',
|
||||
'WorkflowService',
|
||||
function(workflowData,
|
||||
workflowResultsService,
|
||||
workflowDataOptions,
|
||||
@ -13,176 +14,198 @@ export default ['workflowData',
|
||||
workflowNodes,
|
||||
$scope,
|
||||
ParseTypeChange,
|
||||
ParseVariableString
|
||||
ParseVariableString,
|
||||
WorkflowService
|
||||
) {
|
||||
var getTowerLinks = function() {
|
||||
var getTowerLink = function(key) {
|
||||
if ($scope.workflow.related[key]) {
|
||||
return '/#/' + $scope.workflow.related[key]
|
||||
.split('api/v1/')[1];
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
|
||||
var getTowerLinks = function() {
|
||||
var getTowerLink = function(key) {
|
||||
if ($scope.workflow.related[key]) {
|
||||
return '/#/' + $scope.workflow.related[key]
|
||||
.split('api/v1/')[1];
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.workflow_template_link = '/#/templates/workflow_job_template/'+$scope.workflow.workflow_job_template;
|
||||
$scope.created_by_link = getTowerLink('created_by');
|
||||
$scope.cloud_credential_link = getTowerLink('cloud_credential');
|
||||
$scope.network_credential_link = getTowerLink('network_credential');
|
||||
};
|
||||
|
||||
$scope.workflow_template_link = '/#/templates/workflow_job_template/'+$scope.workflow.workflow_job_template;
|
||||
$scope.created_by_link = getTowerLink('created_by');
|
||||
$scope.cloud_credential_link = getTowerLink('cloud_credential');
|
||||
$scope.network_credential_link = getTowerLink('network_credential');
|
||||
};
|
||||
var getTowerLabels = function() {
|
||||
var getTowerLabel = function(key) {
|
||||
if ($scope.workflowOptions && $scope.workflowOptions[key]) {
|
||||
return $scope.workflowOptions[key].choices
|
||||
.filter(val => val[0] === $scope.workflow[key])
|
||||
.map(val => val[1])[0];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
var getTowerLabels = function() {
|
||||
var getTowerLabel = function(key) {
|
||||
if ($scope.workflowOptions && $scope.workflowOptions[key]) {
|
||||
return $scope.workflowOptions[key].choices
|
||||
.filter(val => val[0] === $scope.workflow[key])
|
||||
.map(val => val[1])[0];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
$scope.status_label = getTowerLabel('status');
|
||||
$scope.type_label = getTowerLabel('job_type');
|
||||
$scope.verbosity_label = getTowerLabel('verbosity');
|
||||
};
|
||||
|
||||
$scope.status_label = getTowerLabel('status');
|
||||
$scope.type_label = getTowerLabel('job_type');
|
||||
$scope.verbosity_label = getTowerLabel('verbosity');
|
||||
};
|
||||
function init() {
|
||||
// put initially resolved request data on scope
|
||||
$scope.workflow = workflowData;
|
||||
$scope.workflow_nodes = workflowNodes;
|
||||
$scope.workflowOptions = workflowDataOptions.actions.GET;
|
||||
$scope.labels = jobLabels;
|
||||
|
||||
// var getTotalHostCount = function(count) {
|
||||
// return Object
|
||||
// .keys(count).reduce((acc, i) => acc += count[i], 0);
|
||||
// };
|
||||
// turn related api browser routes into tower routes
|
||||
getTowerLinks();
|
||||
|
||||
// put initially resolved request data on scope
|
||||
$scope.workflow = workflowData;
|
||||
$scope.workflow_nodes = workflowNodes;
|
||||
$scope.workflowOptions = workflowDataOptions.actions.GET;
|
||||
$scope.labels = jobLabels;
|
||||
// use options labels to manipulate display of details
|
||||
getTowerLabels();
|
||||
|
||||
// turn related api browser routes into tower routes
|
||||
getTowerLinks();
|
||||
// set up a read only code mirror for extra vars
|
||||
$scope.variables = ParseVariableString($scope.workflow.extra_vars);
|
||||
$scope.parseType = 'yaml';
|
||||
ParseTypeChange({ scope: $scope,
|
||||
field_id: 'pre-formatted-variables',
|
||||
readOnly: true });
|
||||
|
||||
// use options labels to manipulate display of details
|
||||
getTowerLabels();
|
||||
// Click binding for the expand/collapse button on the standard out log
|
||||
$scope.stdoutFullScreen = false;
|
||||
|
||||
// set up a read only code mirror for extra vars
|
||||
$scope.variables = ParseVariableString($scope.workflow.extra_vars);
|
||||
$scope.parseType = 'yaml';
|
||||
ParseTypeChange({ scope: $scope,
|
||||
field_id: 'pre-formatted-variables',
|
||||
readOnly: true });
|
||||
$scope.stdoutArr = [];
|
||||
|
||||
// Click binding for the expand/collapse button on the standard out log
|
||||
$scope.stdoutFullScreen = false;
|
||||
$scope.toggleStdoutFullscreen = function() {
|
||||
$scope.stdoutFullScreen = !$scope.stdoutFullScreen;
|
||||
};
|
||||
$scope.treeData = WorkflowService.buildTree({
|
||||
workflowNodes: workflowNodes
|
||||
});
|
||||
|
||||
$scope.deleteJob = function() {
|
||||
workflowResultsService.deleteJob($scope.workflow);
|
||||
};
|
||||
// TODO: I think that the workflow chart directive (and eventually d3) is meddling with
|
||||
// this treeData object and removing the children object for some reason (?)
|
||||
// This happens on occasion and I think is a race condition (?)
|
||||
if(!$scope.treeData.data.children) {
|
||||
$scope.treeData.data.children = [];
|
||||
}
|
||||
|
||||
$scope.cancelJob = function() {
|
||||
workflowResultsService.cancelJob($scope.workflow);
|
||||
};
|
||||
$scope.canAddWorkflowJobTemplate = false;
|
||||
|
||||
$scope.relaunchJob = function() {
|
||||
workflowResultsService.relaunchJob($scope);
|
||||
};
|
||||
|
||||
$scope.stdoutArr = [];
|
||||
|
||||
// EVENT STUFF BELOW
|
||||
|
||||
// just putting the event queue on scope so it can be inspected in the
|
||||
// console
|
||||
// $scope.event_queue = eventQueue.queue;
|
||||
// $scope.defersArr = eventQueue.populateDefers;
|
||||
|
||||
// This is where the async updates to the UI actually happen.
|
||||
// Flow is event queue munging in the service -> $scope setting in here
|
||||
// var processEvent = function(event) {
|
||||
// // put the event in the queue
|
||||
// eventQueue.populate(event).then(mungedEvent => {
|
||||
// // make changes to ui based on the event returned from the queue
|
||||
// if (mungedEvent.changes) {
|
||||
// mungedEvent.changes.forEach(change => {
|
||||
// // we've got a change we need to make to the UI!
|
||||
// // update the necessary scope and make the change
|
||||
// if (change === 'startTime' && !$scope.workflow.start) {
|
||||
// $scope.workflow.start = mungedEvent.startTime;
|
||||
// }
|
||||
//
|
||||
// if (change === 'count' && !$scope.countFinished) {
|
||||
// // for all events that affect the host count,
|
||||
// // update the status bar as well as the host
|
||||
// // count badge
|
||||
// $scope.count = mungedEvent.count;
|
||||
// $scope.hostCount = getTotalHostCount(mungedEvent
|
||||
// .count);
|
||||
// }
|
||||
//
|
||||
// if (change === 'playCount') {
|
||||
// $scope.playCount = mungedEvent.playCount;
|
||||
// }
|
||||
//
|
||||
// if (change === 'taskCount') {
|
||||
// $scope.taskCount = mungedEvent.taskCount;
|
||||
// }
|
||||
//
|
||||
// if (change === 'finishedTime' && !$scope.workflow.finished) {
|
||||
// $scope.workflow.finished = mungedEvent.finishedTime;
|
||||
// }
|
||||
//
|
||||
// if (change === 'countFinished') {
|
||||
// // the playbook_on_stats event actually lets
|
||||
// // us know that we don't need to iteratively
|
||||
// // look at event to update the host counts
|
||||
// // any more.
|
||||
// $scope.countFinished = true;
|
||||
// }
|
||||
//
|
||||
// if(change === 'stdout'){
|
||||
// angular
|
||||
// .element(".JobResultsStdOut-stdoutContainer")
|
||||
// .append($compile(mungedEvent
|
||||
// .stdout)($scope));
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// // the changes have been processed in the ui, mark it in the queue
|
||||
// eventQueue.markProcessed(event);
|
||||
// });
|
||||
// };
|
||||
|
||||
// PULL! grab completed event data and process each event
|
||||
// TODO: implement retry logic in case one of these requests fails
|
||||
// var getEvents = function(url) {
|
||||
// workflowResultsService.getEvents(url)
|
||||
// .then(events => {
|
||||
// events.results.forEach(event => {
|
||||
// // get the name in the same format as the data
|
||||
// // coming over the websocket
|
||||
// event.event_name = event.event;
|
||||
// processEvent(event);
|
||||
// });
|
||||
// if (events.next) {
|
||||
// getEvents(events.next);
|
||||
// }
|
||||
// });
|
||||
// };
|
||||
// getEvents($scope.job.related.job_events);
|
||||
|
||||
// // Processing of job_events messages from the websocket
|
||||
// $scope.$on(`ws-job_events-${$scope.workflow.id}`, function(e, data) {
|
||||
// processEvent(data);
|
||||
// });
|
||||
|
||||
// Processing of job-status messages from the websocket
|
||||
$scope.$on(`ws-jobs`, function(e, data) {
|
||||
if (parseInt(data.unified_job_id, 10) === parseInt($scope.workflow.id,10)) {
|
||||
$scope.workflow.status = data.status;
|
||||
}
|
||||
});
|
||||
|
||||
// var getTotalHostCount = function(count) {
|
||||
// return Object
|
||||
// .keys(count).reduce((acc, i) => acc += count[i], 0);
|
||||
// };
|
||||
|
||||
|
||||
$scope.toggleStdoutFullscreen = function() {
|
||||
$scope.stdoutFullScreen = !$scope.stdoutFullScreen;
|
||||
};
|
||||
|
||||
$scope.deleteJob = function() {
|
||||
workflowResultsService.deleteJob($scope.workflow);
|
||||
};
|
||||
|
||||
$scope.cancelJob = function() {
|
||||
workflowResultsService.cancelJob($scope.workflow);
|
||||
};
|
||||
|
||||
$scope.relaunchJob = function() {
|
||||
workflowResultsService.relaunchJob($scope);
|
||||
};
|
||||
|
||||
// EVENT STUFF BELOW
|
||||
|
||||
// just putting the event queue on scope so it can be inspected in the
|
||||
// console
|
||||
// $scope.event_queue = eventQueue.queue;
|
||||
// $scope.defersArr = eventQueue.populateDefers;
|
||||
|
||||
// This is where the async updates to the UI actually happen.
|
||||
// Flow is event queue munging in the service -> $scope setting in here
|
||||
// var processEvent = function(event) {
|
||||
// // put the event in the queue
|
||||
// eventQueue.populate(event).then(mungedEvent => {
|
||||
// // make changes to ui based on the event returned from the queue
|
||||
// if (mungedEvent.changes) {
|
||||
// mungedEvent.changes.forEach(change => {
|
||||
// // we've got a change we need to make to the UI!
|
||||
// // update the necessary scope and make the change
|
||||
// if (change === 'startTime' && !$scope.workflow.start) {
|
||||
// $scope.workflow.start = mungedEvent.startTime;
|
||||
// }
|
||||
//
|
||||
// if (change === 'count' && !$scope.countFinished) {
|
||||
// // for all events that affect the host count,
|
||||
// // update the status bar as well as the host
|
||||
// // count badge
|
||||
// $scope.count = mungedEvent.count;
|
||||
// $scope.hostCount = getTotalHostCount(mungedEvent
|
||||
// .count);
|
||||
// }
|
||||
//
|
||||
// if (change === 'playCount') {
|
||||
// $scope.playCount = mungedEvent.playCount;
|
||||
// }
|
||||
//
|
||||
// if (change === 'taskCount') {
|
||||
// $scope.taskCount = mungedEvent.taskCount;
|
||||
// }
|
||||
//
|
||||
// if (change === 'finishedTime' && !$scope.workflow.finished) {
|
||||
// $scope.workflow.finished = mungedEvent.finishedTime;
|
||||
// }
|
||||
//
|
||||
// if (change === 'countFinished') {
|
||||
// // the playbook_on_stats event actually lets
|
||||
// // us know that we don't need to iteratively
|
||||
// // look at event to update the host counts
|
||||
// // any more.
|
||||
// $scope.countFinished = true;
|
||||
// }
|
||||
//
|
||||
// if(change === 'stdout'){
|
||||
// angular
|
||||
// .element(".JobResultsStdOut-stdoutContainer")
|
||||
// .append($compile(mungedEvent
|
||||
// .stdout)($scope));
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// // the changes have been processed in the ui, mark it in the queue
|
||||
// eventQueue.markProcessed(event);
|
||||
// });
|
||||
// };
|
||||
|
||||
// PULL! grab completed event data and process each event
|
||||
// TODO: implement retry logic in case one of these requests fails
|
||||
// var getEvents = function(url) {
|
||||
// workflowResultsService.getEvents(url)
|
||||
// .then(events => {
|
||||
// events.results.forEach(event => {
|
||||
// // get the name in the same format as the data
|
||||
// // coming over the websocket
|
||||
// event.event_name = event.event;
|
||||
// processEvent(event);
|
||||
// });
|
||||
// if (events.next) {
|
||||
// getEvents(events.next);
|
||||
// }
|
||||
// });
|
||||
// };
|
||||
// getEvents($scope.job.related.job_events);
|
||||
|
||||
// // Processing of job_events messages from the websocket
|
||||
// $scope.$on(`ws-job_events-${$scope.workflow.id}`, function(e, data) {
|
||||
// processEvent(data);
|
||||
// });
|
||||
|
||||
// Processing of job-status messages from the websocket
|
||||
$scope.$on(`ws-jobs`, function(e, data) {
|
||||
if (parseInt(data.unified_job_id, 10) === parseInt($scope.workflow.id,10)) {
|
||||
$scope.workflow.status = data.status;
|
||||
}
|
||||
});
|
||||
|
||||
init();
|
||||
}];
|
||||
|
||||
@ -228,7 +228,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<workflow-status-bar></workflow-status-bar>
|
||||
<!-- <job-results-standard-out></job-results-standard-out> -->
|
||||
<workflow-chart tree-data="treeData.data" can-add-workflow-job-template="canAddWorkflowJobTemplate" class="WorkflowMaker-chart"></workflow-chart>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
describe('Controller: JobTemplatesList', () => {
|
||||
describe('Controller: TemplatesList', () => {
|
||||
// Setup
|
||||
let scope,
|
||||
rootScope,
|
||||
state,
|
||||
JobTemplatesListController,
|
||||
TemplatesListController,
|
||||
ClearScope,
|
||||
GetChoices,
|
||||
Alert,
|
||||
@ -14,13 +14,13 @@ describe('Controller: JobTemplatesList', () => {
|
||||
rbacUiControlService,
|
||||
canAddDeferred,
|
||||
q,
|
||||
JobTemplateService,
|
||||
TemplatesService,
|
||||
deleteWorkflowJobTemplateDeferred,
|
||||
deleteJobTemplateDeferred,
|
||||
Dataset;
|
||||
|
||||
beforeEach(angular.mock.module('Tower'));
|
||||
beforeEach(angular.mock.module('jobTemplates', ($provide) => {
|
||||
beforeEach(angular.mock.module('templates', ($provide) => {
|
||||
|
||||
state = jasmine.createSpyObj('state', [
|
||||
'$get',
|
||||
@ -38,7 +38,7 @@ describe('Controller: JobTemplatesList', () => {
|
||||
}
|
||||
};
|
||||
|
||||
JobTemplateService = {
|
||||
TemplatesService = {
|
||||
deleteWorkflowJobTemplate: function(){
|
||||
return angular.noop;
|
||||
},
|
||||
@ -85,10 +85,10 @@ describe('Controller: JobTemplatesList', () => {
|
||||
|
||||
rbacUiControlService.canAdd = jasmine.createSpy('canAdd').and.returnValue(canAddDeferred.promise);
|
||||
|
||||
JobTemplateService.deleteWorkflowJobTemplate = jasmine.createSpy('deleteWorkflowJobTemplate').and.returnValue(deleteWorkflowJobTemplateDeferred.promise);
|
||||
JobTemplateService.deleteJobTemplate = jasmine.createSpy('deleteJobTemplate').and.returnValue(deleteJobTemplateDeferred.promise);
|
||||
TemplatesService.deleteWorkflowJobTemplate = jasmine.createSpy('deleteWorkflowJobTemplate').and.returnValue(deleteWorkflowJobTemplateDeferred.promise);
|
||||
TemplatesService.deleteJobTemplate = jasmine.createSpy('deleteJobTemplate').and.returnValue(deleteJobTemplateDeferred.promise);
|
||||
|
||||
JobTemplatesListController = $controller('JobTemplatesListController', {
|
||||
TemplatesListController = $controller('TemplatesListController', {
|
||||
$scope: scope,
|
||||
$rootScope: rootScope,
|
||||
$state: state,
|
||||
@ -98,7 +98,7 @@ describe('Controller: JobTemplatesList', () => {
|
||||
Prompt: Prompt,
|
||||
InitiatePlaybookRun: InitiatePlaybookRun,
|
||||
rbacUiControlService: rbacUiControlService,
|
||||
JobTemplateService: JobTemplateService,
|
||||
TemplatesService: TemplatesService,
|
||||
Dataset: Dataset
|
||||
});
|
||||
}));
|
||||
@ -163,7 +163,7 @@ describe('Controller: JobTemplatesList', () => {
|
||||
expect(Prompt).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call JobTemplateService.deleteWorkflowJobTemplate when the user takes affirmative action on the delete modal and type = "Workflow Job Template"', ()=>{
|
||||
it('should call TemplatesService.deleteWorkflowJobTemplate when the user takes affirmative action on the delete modal and type = "Workflow Job Template"', ()=>{
|
||||
// Note that Prompt has been mocked up above to immediately call the callback function that gets passed in
|
||||
// which is how we access the private function in the controller
|
||||
|
||||
@ -174,10 +174,10 @@ describe('Controller: JobTemplatesList', () => {
|
||||
};
|
||||
|
||||
scope.deleteJobTemplate(testTemplate);
|
||||
expect(JobTemplateService.deleteWorkflowJobTemplate).toHaveBeenCalled();
|
||||
expect(TemplatesService.deleteWorkflowJobTemplate).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call JobTemplateService.deleteJobTemplate when the user takes affirmative action on the delete modal and type = "Workflow Job Template"', ()=>{
|
||||
it('should call TemplatesService.deleteJobTemplate when the user takes affirmative action on the delete modal and type = "Workflow Job Template"', ()=>{
|
||||
// Note that Prompt has been mocked up above to immediately call the callback function that gets passed in
|
||||
// which is how we access the private function in the controller
|
||||
|
||||
@ -188,7 +188,7 @@ describe('Controller: JobTemplatesList', () => {
|
||||
};
|
||||
|
||||
scope.deleteJobTemplate(testTemplate);
|
||||
expect(JobTemplateService.deleteJobTemplate).toHaveBeenCalled();
|
||||
expect(TemplatesService.deleteJobTemplate).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
@ -8,7 +8,7 @@ describe('Controller: WorkflowAdd', () => {
|
||||
ClearScope,
|
||||
Alert,
|
||||
GenerateForm,
|
||||
JobTemplateService,
|
||||
TemplatesService,
|
||||
q,
|
||||
getLabelsDeferred,
|
||||
createWorkflowJobTemplateDeferred,
|
||||
@ -20,7 +20,7 @@ describe('Controller: WorkflowAdd', () => {
|
||||
ToJSON;
|
||||
|
||||
beforeEach(angular.mock.module('Tower'));
|
||||
beforeEach(angular.mock.module('jobTemplates', ($provide) => {
|
||||
beforeEach(angular.mock.module('templates', ($provide) => {
|
||||
|
||||
state = jasmine.createSpyObj('state', [
|
||||
'$get',
|
||||
@ -35,7 +35,7 @@ describe('Controller: WorkflowAdd', () => {
|
||||
'applyDefaults'
|
||||
]);
|
||||
|
||||
JobTemplateService = {
|
||||
TemplatesService = {
|
||||
getLabelOptions: function(){
|
||||
return angular.noop;
|
||||
},
|
||||
@ -79,8 +79,8 @@ describe('Controller: WorkflowAdd', () => {
|
||||
ParseTypeChange = _ParseTypeChange_;
|
||||
ToJSON = _ToJSON_;
|
||||
|
||||
JobTemplateService.getLabelOptions = jasmine.createSpy('getLabelOptions').and.returnValue(getLabelsDeferred.promise);
|
||||
JobTemplateService.createWorkflowJobTemplate = jasmine.createSpy('createWorkflowJobTemplate').and.returnValue(createWorkflowJobTemplateDeferred.promise);
|
||||
TemplatesService.getLabelOptions = jasmine.createSpy('getLabelOptions').and.returnValue(getLabelsDeferred.promise);
|
||||
TemplatesService.createWorkflowJobTemplate = jasmine.createSpy('createWorkflowJobTemplate').and.returnValue(createWorkflowJobTemplateDeferred.promise);
|
||||
|
||||
WorkflowAdd = $controller('WorkflowAdd', {
|
||||
$scope: scope,
|
||||
@ -88,7 +88,7 @@ describe('Controller: WorkflowAdd', () => {
|
||||
ClearScope: ClearScope,
|
||||
Alert: Alert,
|
||||
GenerateForm: GenerateForm,
|
||||
JobTemplateService: JobTemplateService,
|
||||
TemplatesService: TemplatesService,
|
||||
ProcessErrors: ProcessErrors,
|
||||
CreateSelect2: CreateSelect2,
|
||||
Wait: Wait,
|
||||
@ -102,7 +102,7 @@ describe('Controller: WorkflowAdd', () => {
|
||||
});
|
||||
|
||||
it('should get/set the label options and select2-ify the input', ()=>{
|
||||
// Resolve JobTemplateService.getLabelsForJobTemplate
|
||||
// Resolve TemplatesService.getLabelsForJobTemplate
|
||||
getLabelsDeferred.resolve({
|
||||
foo: "bar"
|
||||
});
|
||||
@ -120,7 +120,7 @@ describe('Controller: WorkflowAdd', () => {
|
||||
});
|
||||
|
||||
it('should call ProcessErrors when getLabelsForJobTemplate returns a rejected promise', ()=>{
|
||||
// Reject JobTemplateService.getLabelsForJobTemplate
|
||||
// Reject TemplatesService.getLabelsForJobTemplate
|
||||
getLabelsDeferred.reject({
|
||||
data: "mockedData",
|
||||
status: 400
|
||||
@ -133,11 +133,11 @@ describe('Controller: WorkflowAdd', () => {
|
||||
|
||||
describe('scope.formSave()', () => {
|
||||
|
||||
it('should call JobTemplateService.createWorkflowJobTemplate', ()=>{
|
||||
it('should call TemplatesService.createWorkflowJobTemplate', ()=>{
|
||||
scope.name = "Test Workflow";
|
||||
scope.description = "This is a test description";
|
||||
scope.formSave();
|
||||
expect(JobTemplateService.createWorkflowJobTemplate).toHaveBeenCalledWith({
|
||||
expect(TemplatesService.createWorkflowJobTemplate).toHaveBeenCalledWith({
|
||||
name: "Test Workflow",
|
||||
description: "This is a test description",
|
||||
labels: undefined,
|
||||
|
||||
@ -7,7 +7,7 @@ describe('Controller: WorkflowMaker', () => {
|
||||
WorkflowHelpService;
|
||||
|
||||
beforeEach(angular.mock.module('Tower'));
|
||||
beforeEach(angular.mock.module('jobTemplates', ($provide) => {
|
||||
beforeEach(angular.mock.module('templates', ($provide) => {
|
||||
|
||||
WorkflowHelpService = jasmine.createSpyObj('WorkflowHelpService', [
|
||||
'closeDialog',
|
||||
@ -21,6 +21,7 @@ describe('Controller: WorkflowMaker', () => {
|
||||
|
||||
beforeEach(angular.mock.inject( ($rootScope, $controller, _WorkflowHelpService_) => {
|
||||
scope = $rootScope.$new();
|
||||
scope.closeDialog = jasmine.createSpy();
|
||||
scope.treeData = {
|
||||
data: {
|
||||
id: 1,
|
||||
@ -50,9 +51,9 @@ describe('Controller: WorkflowMaker', () => {
|
||||
|
||||
it('should close the dialog', ()=>{
|
||||
scope.saveWorkflowMaker();
|
||||
expect(WorkflowHelpService.closeDialog).toHaveBeenCalled();
|
||||
expect(scope.closeDialog).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user