mirror of
https://github.com/ansible/awx.git
synced 2024-10-31 23:51:09 +03:00
Show workflow badge
Add Workflow tags Hookup workflow details link Add parent workflow and job explanation fields Add workflow key icon to WF maker and WF results Hookup wf prompting Add wf key dropdown and hide wf info badge
This commit is contained in:
parent
f6cc351f7f
commit
e20d8c8e81
@ -102,6 +102,7 @@ function TemplatesStrings (BaseString) {
|
||||
ALWAYS: t.s('Always'),
|
||||
PROJECT_SYNC: t.s('Project Sync'),
|
||||
INVENTORY_SYNC: t.s('Inventory Sync'),
|
||||
WORKFLOW: t.s('Workflow'),
|
||||
WARNING: t.s('Warning'),
|
||||
TOTAL_TEMPLATES: t.s('TOTAL TEMPLATES'),
|
||||
ADD_A_TEMPLATE: t.s('ADD A TEMPLATE'),
|
||||
|
@ -493,21 +493,6 @@ table, tbody {
|
||||
}
|
||||
}
|
||||
|
||||
.List-infoCell--badge {
|
||||
height: 15px;
|
||||
color: @default-interface-txt;
|
||||
background-color: @default-list-header-bg;
|
||||
border-radius: 5px;
|
||||
font-size: 10px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
margin-left: 10px;
|
||||
text-transform: uppercase;
|
||||
font-weight: 100;
|
||||
margin-top: 2.25px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.List-actionsInner {
|
||||
display: flex;
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
<div class="List-infoCell">
|
||||
<span class="List-infoCell--badge" aw-pop-over="<dl><dt>{{ 'INVENTORY' | translate }}</dt><dd>{{(job_template.summary_fields.inventory.name | sanitize) || ('NONE SELECTED' | translate)}}</dd></dl><dl><dt>{{ 'PROJECT' | translate }}</dt><dd>{{job_template.summary_fields.project.name | sanitize}}</dd></dl><dl><dt>{{ 'PLAYBOOK' | translate }}</dt><dd>{{job_template.playbook| sanitize}}</dd></dl><dl><dt>{{ 'CREDENTIAL' | translate }}</dt> <dd>{{(job_template.summary_fields.credential.name | sanitize) || ('NONE SELECTED' | translate)}}</dd></dl>" data-popover-title="{{job_template.name| sanitize}}" translate>INFO</span>
|
||||
<div class="List-infoCell" ng-if="job_template.type === 'job_template'">
|
||||
<span class="Key-icon Key-icon--circle Key-icon--default" aw-pop-over="<dl><dt>{{ 'INVENTORY' | translate }}</dt><dd>{{(job_template.summary_fields.inventory.name | sanitize) || ('NONE SELECTED' | translate)}}</dd></dl><dl><dt>{{ 'PROJECT' | translate }}</dt><dd>{{job_template.summary_fields.project.name | sanitize}}</dd></dl><dl><dt>{{ 'PLAYBOOK' | translate }}</dt><dd>{{job_template.playbook| sanitize}}</dd></dl><dl><dt>{{ 'CREDENTIAL' | translate }}</dt> <dd>{{(job_template.summary_fields.credential.name | sanitize) || ('NONE SELECTED' | translate)}}</dd></dl>"
|
||||
data-popover-title="{{job_template.name| sanitize}}">?</span>
|
||||
</div>
|
||||
|
@ -696,6 +696,13 @@ angular.module('GeneratorHelpers', [systemStatus.name])
|
||||
if (options.mode !== 'lookup' && field.badgeIcon && field.badgePlacement && field.badgePlacement !== 'left') {
|
||||
html += Badge(field);
|
||||
}
|
||||
|
||||
// Field Tag
|
||||
if (field.tag) {
|
||||
html += `<span class="at-RowItem-tag" ng-show="${field.showTag}">
|
||||
${field.tag}
|
||||
</span>`;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -409,9 +409,6 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
|
||||
workflowMaker = {
|
||||
name: 'templates.editWorkflowJobTemplate.workflowMaker',
|
||||
url: '/workflow-maker',
|
||||
// ncyBreadcrumb: {
|
||||
// label: 'WORKFLOW MAKER'
|
||||
// },
|
||||
data: {
|
||||
formChildState: true
|
||||
},
|
||||
@ -468,14 +465,14 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
|
||||
$scope[`${list.iterator}_dataset`] = Dataset.data;
|
||||
$scope[list.name] = $scope[`${list.iterator}_dataset`].results;
|
||||
|
||||
$scope.$watch('job_templates', function(){
|
||||
$scope.$watch('templates', function(){
|
||||
if($scope.selectedTemplate){
|
||||
$scope.job_templates.forEach(function(row, i) {
|
||||
$scope.templates.forEach(function(row, i) {
|
||||
if(row.id === $scope.selectedTemplate.id) {
|
||||
$scope.job_templates[i].checked = 1;
|
||||
$scope.templates[i].checked = 1;
|
||||
}
|
||||
else {
|
||||
$scope.job_templates[i].checked = 0;
|
||||
$scope.templates[i].checked = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -484,9 +481,9 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
|
||||
|
||||
$scope.toggle_row = function(selectedRow) {
|
||||
if ($scope.workflowJobTemplateObj.summary_fields.user_capabilities.edit) {
|
||||
$scope.job_templates.forEach(function(row, i) {
|
||||
$scope.templates.forEach(function(row, i) {
|
||||
if (row.id === selectedRow.id) {
|
||||
$scope.job_templates[i].checked = 1;
|
||||
$scope.templates[i].checked = 1;
|
||||
$scope.selection[list.iterator] = {
|
||||
id: row.id,
|
||||
name: row.name
|
||||
@ -499,27 +496,27 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
|
||||
};
|
||||
|
||||
$scope.$watch('selectedTemplate', () => {
|
||||
$scope.job_templates.forEach(function(row, i) {
|
||||
if(_.hasIn($scope, 'selectedTemplate.id') && row.id === $scope.selectedTemplate.id) {
|
||||
$scope.job_templates[i].checked = 1;
|
||||
$scope.templates.forEach(function(row, i) {
|
||||
if(_.has($scope, 'selectedTemplate.id') && row.id === $scope.selectedTemplate.id) {
|
||||
$scope.templates[i].checked = 1;
|
||||
}
|
||||
else {
|
||||
$scope.job_templates[i].checked = 0;
|
||||
$scope.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;
|
||||
$scope.templates.forEach(function(row, i) {
|
||||
$scope.templates[i].checked = 0;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$on('clearWorkflowLists', function() {
|
||||
$scope.job_templates.forEach(function(row, i) {
|
||||
$scope.job_templates[i].checked = 0;
|
||||
$scope.templates.forEach(function(row, i) {
|
||||
$scope.templates[i].checked = 0;
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -699,8 +696,8 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
|
||||
return qs.search(path, $stateParams[`${list.iterator}_search`]);
|
||||
}
|
||||
],
|
||||
WorkflowMakerJobTemplateList: ['TemplateList',
|
||||
(TemplateList) => {
|
||||
WorkflowMakerJobTemplateList: ['TemplateList', 'i18n',
|
||||
(TemplateList, i18n) => {
|
||||
let list = _.cloneDeep(TemplateList);
|
||||
delete list.actions;
|
||||
delete list.fields.type;
|
||||
@ -709,15 +706,18 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
|
||||
delete list.fields.labels;
|
||||
delete list.fieldActions;
|
||||
list.fields.name.columnClass = "col-md-8";
|
||||
list.fields.name.tag = i18n._('WORKFLOW');
|
||||
list.fields.name.showTag = "{{template.type === 'workflow_job_template'}}";
|
||||
list.disableRow = "{{ !workflowJobTemplateObj.summary_fields.user_capabilities.edit }}";
|
||||
list.disableRowValue = '!workflowJobTemplateObj.summary_fields.user_capabilities.edit';
|
||||
list.iterator = 'job_template';
|
||||
list.name = 'job_templates';
|
||||
list.iterator = 'template';
|
||||
list.name = 'templates';
|
||||
list.basePath = 'unified_job_templates';
|
||||
list.fields.info = {
|
||||
ngInclude: "'/static/partials/job-template-details.html'",
|
||||
type: 'template',
|
||||
columnClass: 'col-md-3',
|
||||
infoHeaderClass: 'col-md-3',
|
||||
label: '',
|
||||
nosort: true
|
||||
};
|
||||
|
@ -385,7 +385,12 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
||||
.attr("r", 10)
|
||||
.attr("class", "WorkflowChart-nodeTypeCircle")
|
||||
.style("display", function (d) {
|
||||
return d.unifiedJobTemplate && (d.unifiedJobTemplate.type === "project" || d.unifiedJobTemplate.unified_job_type === "project_update" || d.unifiedJobTemplate.type === "inventory_source" || d.unifiedJobTemplate.unified_job_type === "inventory_update") ? null : "none";
|
||||
return d.unifiedJobTemplate && (d.unifiedJobTemplate.type === "project" ||
|
||||
d.unifiedJobTemplate.unified_job_type === "project_update" ||
|
||||
d.unifiedJobTemplate.type === "inventory_source" ||
|
||||
d.unifiedJobTemplate.unified_job_type === "inventory_update" ||
|
||||
d.unifiedJobTemplate.type === "workflow_job_template" ||
|
||||
d.unifiedJobTemplate.unified_job_type === "workflow_job") ? null : "none";
|
||||
});
|
||||
|
||||
thisNode.append("text")
|
||||
@ -394,10 +399,42 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
||||
.attr("text-anchor", "middle")
|
||||
.attr("class", "WorkflowChart-nodeTypeLetter")
|
||||
.text(function (d) {
|
||||
return (d.unifiedJobTemplate && (d.unifiedJobTemplate.type === "project" || d.unifiedJobTemplate.unified_job_type === "project_update")) ? "P" : (d.unifiedJobTemplate && (d.unifiedJobTemplate.type === "inventory_source" || d.unifiedJobTemplate.unified_job_type === "inventory_update") ? "I" : "");
|
||||
let nodeTypeLetter = "";
|
||||
if (d.unifiedJobTemplate && d.unifiedJobTemplate.type) {
|
||||
switch (d.unifiedJobTemplate.type) {
|
||||
case "project":
|
||||
nodeTypeLetter = "P";
|
||||
break;
|
||||
case "inventory_source":
|
||||
nodeTypeLetter = "I";
|
||||
break;
|
||||
case "workflow_job_template":
|
||||
nodeTypeLetter = "W";
|
||||
break;
|
||||
}
|
||||
} else if (d.unifiedJobTemplate && d.unifiedJobTemplate.unified_job_type) {
|
||||
switch (d.unifiedJobTemplate.unified_job_type) {
|
||||
case "project_update":
|
||||
nodeTypeLetter = "P";
|
||||
break;
|
||||
case "inventory_update":
|
||||
nodeTypeLetter = "I";
|
||||
break;
|
||||
case "workflow_job":
|
||||
nodeTypeLetter = "W";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return nodeTypeLetter;
|
||||
})
|
||||
.style("display", function (d) {
|
||||
return d.unifiedJobTemplate && (d.unifiedJobTemplate.type === "project" || d.unifiedJobTemplate.unified_job_type === "project_update" || d.unifiedJobTemplate.type === "inventory_source" || d.unifiedJobTemplate.unified_job_type === "inventory_update") ? null : "none";
|
||||
return d.unifiedJobTemplate &&
|
||||
(d.unifiedJobTemplate.type === "project" ||
|
||||
d.unifiedJobTemplate.unified_job_type === "project_update" ||
|
||||
d.unifiedJobTemplate.type === "inventory_source" ||
|
||||
d.unifiedJobTemplate.unified_job_type === "inventory_update" ||
|
||||
d.unifiedJobTemplate.type === "workflow_job_template" ||
|
||||
d.unifiedJobTemplate.unified_job_type === "workflow_job") ? null : "none";
|
||||
});
|
||||
|
||||
thisNode.append("rect")
|
||||
@ -828,15 +865,52 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
||||
|
||||
t.selectAll(".WorkflowChart-nodeTypeCircle")
|
||||
.style("display", function (d) {
|
||||
return d.unifiedJobTemplate && (d.unifiedJobTemplate.type === "project" || d.unifiedJobTemplate.unified_job_type === "project_update" || d.unifiedJobTemplate.type === "inventory_source" || d.unifiedJobTemplate.unified_job_type === "inventory_update") ? null : "none";
|
||||
return d.unifiedJobTemplate && (d.unifiedJobTemplate.type === "project" ||
|
||||
d.unifiedJobTemplate.unified_job_type === "project_update" ||
|
||||
d.unifiedJobTemplate.type === "inventory_source" ||
|
||||
d.unifiedJobTemplate.unified_job_type === "inventory_update" ||
|
||||
d.unifiedJobTemplate.type === "workflow_job_template" ||
|
||||
d.unifiedJobTemplate.unified_job_type === "workflow_job") ? null : "none";
|
||||
});
|
||||
|
||||
t.selectAll(".WorkflowChart-nodeTypeLetter")
|
||||
.text(function (d) {
|
||||
return (d.unifiedJobTemplate && (d.unifiedJobTemplate.type === "project" || d.unifiedJobTemplate.unified_job_type === "project_update")) ? "P" : (d.unifiedJobTemplate && (d.unifiedJobTemplate.type === "inventory_source" || d.unifiedJobTemplate.unified_job_type === "inventory_update") ? "I" : "");
|
||||
let nodeTypeLetter = "";
|
||||
if (d.unifiedJobTemplate && d.unifiedJobTemplate.type) {
|
||||
switch (d.unifiedJobTemplate.type) {
|
||||
case "project":
|
||||
nodeTypeLetter = "P";
|
||||
break;
|
||||
case "inventory_source":
|
||||
nodeTypeLetter = "I";
|
||||
break;
|
||||
case "workflow_job_template":
|
||||
nodeTypeLetter = "W";
|
||||
break;
|
||||
}
|
||||
} else if (d.unifiedJobTemplate && d.unifiedJobTemplate.unified_job_type) {
|
||||
switch (d.unifiedJobTemplate.unified_job_type) {
|
||||
case "project_update":
|
||||
nodeTypeLetter = "P";
|
||||
break;
|
||||
case "inventory_update":
|
||||
nodeTypeLetter = "I";
|
||||
break;
|
||||
case "workflow_job":
|
||||
nodeTypeLetter = "W";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return nodeTypeLetter;
|
||||
})
|
||||
.style("display", function (d) {
|
||||
return d.unifiedJobTemplate && (d.unifiedJobTemplate.type === "project" || d.unifiedJobTemplate.unified_job_type === "project_update" || d.unifiedJobTemplate.type === "inventory_source" || d.unifiedJobTemplate.unified_job_type === "inventory_update") ? null : "none";
|
||||
return d.unifiedJobTemplate &&
|
||||
(d.unifiedJobTemplate.type === "project" ||
|
||||
d.unifiedJobTemplate.unified_job_type === "project_update" ||
|
||||
d.unifiedJobTemplate.type === "inventory_source" ||
|
||||
d.unifiedJobTemplate.unified_job_type === "inventory_update" ||
|
||||
d.unifiedJobTemplate.type === "workflow_job_template" ||
|
||||
d.unifiedJobTemplate.unified_job_type === "workflow_job") ? null : "none";
|
||||
});
|
||||
|
||||
t.selectAll(".WorkflowChart-nodeStatus")
|
||||
@ -1011,6 +1085,10 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
||||
id: d.job.id,
|
||||
type: 'project'
|
||||
});
|
||||
} else if (job_type === 'workflow_job') {
|
||||
$state.go('workflowResults', {
|
||||
id: d.job.id,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -202,23 +202,17 @@
|
||||
line-height: 20px;
|
||||
}
|
||||
.WorkflowLegend-details {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
padding-left: 20px;
|
||||
margin-top:10px;
|
||||
border: 1px solid @d7grey;
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
}
|
||||
.WorkflowLegend-legendItem {
|
||||
display: flex;
|
||||
}
|
||||
.WorkflowLegend-legendItem:not(:last-child) {
|
||||
padding-right: 20px;
|
||||
}
|
||||
.WorkflowLegend-details--left {
|
||||
display: flex;
|
||||
display: block;
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
.WorkflowLegend-details--right {
|
||||
@ -304,6 +298,7 @@
|
||||
height: 3px;
|
||||
width: 20px;
|
||||
margin: 9px 5px 9px 0px;
|
||||
outline: none;
|
||||
}
|
||||
.Key-heading {
|
||||
font-weight: 700;
|
||||
|
@ -5,10 +5,10 @@
|
||||
*************************************************/
|
||||
|
||||
export default ['$scope', 'WorkflowService', 'TemplatesService',
|
||||
'ProcessErrors', 'CreateSelect2', '$q', 'JobTemplateModel',
|
||||
'ProcessErrors', 'CreateSelect2', '$q', 'JobTemplateModel', 'WorkflowJobTemplateModel',
|
||||
'Empty', 'PromptService', 'Rest', 'TemplatesStrings', '$timeout',
|
||||
function ($scope, WorkflowService, TemplatesService,
|
||||
ProcessErrors, CreateSelect2, $q, JobTemplate,
|
||||
ProcessErrors, CreateSelect2, $q, JobTemplate, WorkflowJobTemplate,
|
||||
Empty, PromptService, Rest, TemplatesStrings, $timeout) {
|
||||
|
||||
let promptWatcher, surveyQuestionWatcher, credentialsWatcher;
|
||||
@ -110,7 +110,7 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
|
||||
// Check to see if the user has provided any prompt values that are different
|
||||
// from the defaults in the job template
|
||||
|
||||
if (params.node.unifiedJobTemplate.type === "job_template" && params.node.promptData) {
|
||||
if ((params.node.unifiedJobTemplate.type === "job_template" || params.node.unifiedJobTemplate.type === "workflow_job_template") && params.node.promptData) {
|
||||
sendableNodeData = PromptService.bundlePromptDataForSaving({
|
||||
promptData: params.node.promptData,
|
||||
dataToSave: sendableNodeData
|
||||
@ -188,7 +188,11 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
|
||||
|
||||
params.node.isNew = false;
|
||||
continueRecursing(data.data.id);
|
||||
}, function ({ data, config, status }) {
|
||||
}, function ({
|
||||
data,
|
||||
config,
|
||||
status
|
||||
}) {
|
||||
ProcessErrors($scope, data, status, null, {
|
||||
hdr: $scope.strings.get('error.HEADER'),
|
||||
msg: $scope.strings.get('error.CALL', {
|
||||
@ -339,7 +343,7 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
|
||||
let missingPromptValue = false;
|
||||
if ($scope.missingSurveyValue) {
|
||||
missingPromptValue = true;
|
||||
} else if (!$scope.promptData.prompts.inventory.value || !$scope.promptData.prompts.inventory.value.id) {
|
||||
} else if ($scope.selectedTemplate.type === 'job_template' && (!$scope.promptData.prompts.inventory.value || !$scope.promptData.prompts.inventory.value.id)) {
|
||||
missingPromptValue = true;
|
||||
}
|
||||
$scope.promptModalMissingReqFields = missingPromptValue;
|
||||
@ -481,7 +485,8 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
|
||||
|
||||
$scope.placeholderNode.unifiedJobTemplate = $scope.selectedTemplate;
|
||||
$scope.placeholderNode.edgeType = $scope.edgeType.value;
|
||||
if ($scope.placeholderNode.unifiedJobTemplate.type === 'job_template') {
|
||||
if ($scope.placeholderNode.unifiedJobTemplate.type === 'job_template' ||
|
||||
$scope.placeholderNode.unifiedJobTemplate.type === 'workflow_job_template') {
|
||||
$scope.placeholderNode.promptData = _.cloneDeep($scope.promptData);
|
||||
}
|
||||
$scope.placeholderNode.canEdit = true;
|
||||
@ -498,8 +503,7 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
|
||||
if ($scope.selectedTemplate && $scope.edgeType && $scope.edgeType.value) {
|
||||
$scope.nodeBeingEdited.unifiedJobTemplate = $scope.selectedTemplate;
|
||||
$scope.nodeBeingEdited.edgeType = $scope.edgeType.value;
|
||||
|
||||
if ($scope.nodeBeingEdited.unifiedJobTemplate.type === 'job_template') {
|
||||
if ($scope.nodeBeingEdited.unifiedJobTemplate.type === 'job_template' || $scope.nodeBeingEdited.unifiedJobTemplate.type === 'workflow_job_template') {
|
||||
$scope.nodeBeingEdited.promptData = _.cloneDeep($scope.promptData);
|
||||
}
|
||||
|
||||
@ -591,9 +595,8 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
|
||||
$scope.nodeBeingEdited.isActiveEdit = true;
|
||||
|
||||
let finishConfiguringEdit = function () {
|
||||
|
||||
let jobTemplate = new JobTemplate();
|
||||
|
||||
let templateType = $scope.nodeBeingEdited.unifiedJobTemplate.type;
|
||||
let jobTemplate = templateType === "workflow_job_template" ? new WorkflowJobTemplate() : new JobTemplate();
|
||||
if (!_.isEmpty($scope.nodeBeingEdited.promptData)) {
|
||||
$scope.promptData = _.cloneDeep($scope.nodeBeingEdited.promptData);
|
||||
const launchConf = $scope.promptData.launchConf;
|
||||
@ -615,15 +618,17 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
|
||||
} else {
|
||||
$scope.showPromptButton = true;
|
||||
|
||||
if (launchConf.ask_inventory_on_launch && !_.has(launchConf, 'defaults.inventory') && !_.has($scope, 'nodeBeingEdited.originalNodeObj.summary_fields.inventory')) {
|
||||
if ($scope.nodeBeingEdited.unifiedJobTemplate.type === 'job_template' && launchConf.ask_inventory_on_launch && !_.has(launchConf, 'defaults.inventory') && !_.has($scope, 'nodeBeingEdited.originalNodeObj.summary_fields.inventory')) {
|
||||
$scope.promptModalMissingReqFields = true;
|
||||
} else {
|
||||
$scope.promptModalMissingReqFields = false;
|
||||
}
|
||||
}
|
||||
} else if (
|
||||
_.get($scope, 'nodeBeingEdited.unifiedJobTemplate.unified_job_type') === 'job_template' ||
|
||||
_.get($scope, 'nodeBeingEdited.unifiedJobTemplate.type') === 'job_template'
|
||||
_.get($scope, 'nodeBeingEdited.unifiedJobTemplate.unified_job_type') === 'job' ||
|
||||
_.get($scope, 'nodeBeingEdited.unifiedJobTemplate.type') === 'job_template' ||
|
||||
_.get($scope, 'nodeBeingEdited.unifiedJobTemplate.unified_job_type') === 'workflow_job' ||
|
||||
_.get($scope, 'nodeBeingEdited.unifiedJobTemplate.type') === 'workflow_job_template'
|
||||
) {
|
||||
let promises = [jobTemplate.optionsLaunch($scope.nodeBeingEdited.unifiedJobTemplate.id), jobTemplate.getLaunch($scope.nodeBeingEdited.unifiedJobTemplate.id)];
|
||||
|
||||
@ -674,11 +679,15 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
|
||||
|
||||
prompts.credentials.value = workflowNodeCredentials.concat(defaultCredsWithoutOverrides);
|
||||
|
||||
if ($scope.nodeBeingEdited.unifiedJobTemplate.unified_job_template === 'job') {
|
||||
if ((!$scope.nodeBeingEdited.unifiedJobTemplate.inventory && !launchConf.ask_inventory_on_launch) || !$scope.nodeBeingEdited.unifiedJobTemplate.project) {
|
||||
$scope.selectedTemplateInvalid = true;
|
||||
} else {
|
||||
$scope.selectedTemplateInvalid = false;
|
||||
}
|
||||
} else {
|
||||
$scope.selectedTemplateInvalid = false;
|
||||
}
|
||||
|
||||
let credentialRequiresPassword = false;
|
||||
|
||||
@ -774,7 +783,9 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
|
||||
}
|
||||
|
||||
if (_.get($scope, 'nodeBeingEdited.unifiedJobTemplate')) {
|
||||
if (_.get($scope, 'nodeBeingEdited.unifiedJobTemplate.type') === "job_template") {
|
||||
|
||||
if (_.get($scope, 'nodeBeingEdited.unifiedJobTemplate.type') === "job_template" ||
|
||||
_.get($scope, 'nodeBeingEdited.unifiedJobTemplate.type') === "workflow_job_template") {
|
||||
$scope.workflowMakerFormConfig.activeTab = "jobs";
|
||||
}
|
||||
|
||||
@ -783,6 +794,7 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
|
||||
if ($scope.selectedTemplate.unified_job_type) {
|
||||
switch ($scope.selectedTemplate.unified_job_type) {
|
||||
case "job":
|
||||
case "workflow_job":
|
||||
$scope.workflowMakerFormConfig.activeTab = "jobs";
|
||||
break;
|
||||
case "project_update":
|
||||
@ -795,6 +807,7 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
|
||||
} else if ($scope.selectedTemplate.type) {
|
||||
switch ($scope.selectedTemplate.type) {
|
||||
case "job_template":
|
||||
case "workflow_job_template":
|
||||
$scope.workflowMakerFormConfig.activeTab = "jobs";
|
||||
break;
|
||||
case "project":
|
||||
@ -843,8 +856,9 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
|
||||
|
||||
// Determine whether or not we need to go out and GET this nodes unified job template
|
||||
// in order to determine whether or not prompt fields are needed
|
||||
|
||||
if (!$scope.nodeBeingEdited.isNew && !$scope.nodeBeingEdited.edited && $scope.nodeBeingEdited.unifiedJobTemplate && $scope.nodeBeingEdited.unifiedJobTemplate.unified_job_type && $scope.nodeBeingEdited.unifiedJobTemplate.unified_job_type === 'job') {
|
||||
if (!$scope.nodeBeingEdited.isNew && !$scope.nodeBeingEdited.edited &&
|
||||
(_.get($scope, 'nodeBeingEdited.unifiedJobTemplate.unified_job_type') === 'job' ||
|
||||
_.get($scope, 'nodeBeingEdited.unifiedJobTemplate.unified_job_type') === 'workflow_job')) {
|
||||
// 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
|
||||
|
||||
@ -852,7 +866,11 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
|
||||
.then(function (data) {
|
||||
$scope.nodeBeingEdited.unifiedJobTemplate = _.clone(data.data.results[0]);
|
||||
finishConfiguringEdit();
|
||||
}, function ({ data, status, config }) {
|
||||
}, function ({
|
||||
data,
|
||||
status,
|
||||
config
|
||||
}) {
|
||||
ProcessErrors($scope, data, status, null, {
|
||||
hdr: $scope.strings.get('error.HEADER'),
|
||||
msg: $scope.strings.get('error.CALL', {
|
||||
@ -982,14 +1000,13 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
|
||||
}
|
||||
|
||||
$scope.promptData = null;
|
||||
|
||||
if (selectedTemplate.type === "job_template") {
|
||||
let jobTemplate = new JobTemplate();
|
||||
if (selectedTemplate.type === "job_template" || selectedTemplate.type === "workflow_job_template") {
|
||||
let jobTemplate = selectedTemplate.type === "workflow_job_template" ? new WorkflowJobTemplate() : new JobTemplate();
|
||||
|
||||
$q.all([jobTemplate.optionsLaunch(selectedTemplate.id), jobTemplate.getLaunch(selectedTemplate.id)])
|
||||
.then((responses) => {
|
||||
let launchConf = responses[1].data;
|
||||
|
||||
if (selectedTemplate.type === 'job_template') {
|
||||
if ((!selectedTemplate.inventory && !launchConf.ask_inventory_on_launch) || !selectedTemplate.project) {
|
||||
$scope.selectedTemplateInvalid = true;
|
||||
} else {
|
||||
@ -1001,6 +1018,7 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
|
||||
} else {
|
||||
$scope.credentialRequiresPassword = false;
|
||||
}
|
||||
}
|
||||
|
||||
$scope.selectedTemplate = angular.copy(selectedTemplate);
|
||||
|
||||
@ -1021,11 +1039,15 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
|
||||
} else {
|
||||
$scope.showPromptButton = true;
|
||||
|
||||
if (selectedTemplate.type === 'job_template') {
|
||||
if (launchConf.ask_inventory_on_launch && !_.has(launchConf, 'defaults.inventory')) {
|
||||
$scope.promptModalMissingReqFields = true;
|
||||
} else {
|
||||
$scope.promptModalMissingReqFields = false;
|
||||
}
|
||||
} else {
|
||||
$scope.promptModalMissingReqFields = false;
|
||||
}
|
||||
|
||||
if (launchConf.survey_enabled) {
|
||||
// go out and get the survey questions
|
||||
@ -1156,7 +1178,11 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
|
||||
// This is the last page
|
||||
buildTreeFromNodes();
|
||||
}
|
||||
}, function ({ data, status, config }) {
|
||||
}, function ({
|
||||
data,
|
||||
status,
|
||||
config
|
||||
}) {
|
||||
ProcessErrors($scope, data, status, null, {
|
||||
hdr: $scope.strings.get('error.HEADER'),
|
||||
msg: $scope.strings.get('error.CALL', {
|
||||
|
@ -62,6 +62,10 @@
|
||||
<div class="Key-icon Key-icon--circle Key-icon--default">I</div>
|
||||
<p class="Key-listItemContent Key-listItemContent--circle">{{strings.get('workflow_maker.INVENTORY_SYNC')}}</p>
|
||||
</li>
|
||||
<li class="Key-listItem">
|
||||
<div class="Key-icon Key-icon--circle Key-icon--default">W</div>
|
||||
<p class="Key-listItemContent Key-listItemContent--circle">{{strings.get('workflow_maker.WORKFLOW')}}</p>
|
||||
</li>
|
||||
<li class="Key-listItem">
|
||||
<div class="Key-icon Key-icon--circle Key-icon--warning">!</div>
|
||||
<p class="Key-listItemContent Key-listItemContent--circle">{{strings.get('workflow_maker.WARNING')}}</p>
|
||||
@ -95,7 +99,9 @@
|
||||
</div>
|
||||
<span ng-show="selectedTemplate &&
|
||||
((selectedTemplate.type === 'job_template' || selectedTemplate.type === 'workflow_job_template' && workflowMakerFormConfig.activeTab === 'jobs') ||
|
||||
(selectedTemplate.unified_job_type === 'job' || selectedTemplate.unified_job_type === 'workflow_job' && workflowMakerFormConfig.activeTab === 'jobs') ||
|
||||
(selectedTemplate.type === 'project' && workflowMakerFormConfig.activeTab === 'project_sync') ||
|
||||
(selectedTemplate.unified_job_type === 'inventory_update' && workflowMakerFormConfig.activeTab === 'inventory_sync') ||
|
||||
(selectedTemplate.type === 'inventory_source' && workflowMakerFormConfig.activeTab === 'inventory_sync'))">
|
||||
<div ng-if="selectedTemplate && selectedTemplateInvalid">
|
||||
<div class="WorkflowMaker-invalidJobTemplateWarning">
|
||||
|
@ -141,3 +141,13 @@
|
||||
.WorkflowResults-extraVarsLabel {
|
||||
font-size:14px!important;
|
||||
}
|
||||
|
||||
.WorkflowResults-seeMoreLess {
|
||||
color: #337AB7;
|
||||
margin: 4px 0px;
|
||||
text-transform: uppercase;
|
||||
padding: 2px 0px;
|
||||
cursor: pointer;
|
||||
border-radius: 5px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
export default ['workflowData', 'workflowResultsService', 'workflowDataOptions',
|
||||
'jobLabels', 'workflowNodes', '$scope', 'ParseTypeChange',
|
||||
'ParseVariableString', 'WorkflowService', 'count', '$state', 'i18n',
|
||||
'moment', function(workflowData, workflowResultsService,
|
||||
'moment', '$filter', function(workflowData, workflowResultsService,
|
||||
workflowDataOptions, jobLabels, workflowNodes, $scope, ParseTypeChange,
|
||||
ParseVariableString, WorkflowService, count, $state, i18n, moment) {
|
||||
ParseVariableString, WorkflowService, count, $state, i18n, moment, $filter) {
|
||||
var runTimeElapsedTimer = null;
|
||||
|
||||
var getLinks = function() {
|
||||
@ -50,13 +50,17 @@ export default ['workflowData', 'workflowResultsService', 'workflowDataOptions',
|
||||
STARTED: i18n._('Started'),
|
||||
FINISHED: i18n._('Finished'),
|
||||
LABELS: i18n._('Labels'),
|
||||
STATUS: i18n._('Status'),
|
||||
SLICE_TEMPLATE: i18n._('Slice Job Template'),
|
||||
STATUS: i18n._('Status')
|
||||
JOB_EXPLANATION: i18n._('Explanation'),
|
||||
SOURCE_WORKFLOW_JOB: i18n._('Parent Workflow')
|
||||
},
|
||||
details: {
|
||||
HEADER: i18n._('DETAILS'),
|
||||
NOT_FINISHED: i18n._('Not Finished'),
|
||||
NOT_STARTED: i18n._('Not Started'),
|
||||
SHOW_LESS: i18n._('Show Less'),
|
||||
SHOW_MORE: i18n._('Show More'),
|
||||
},
|
||||
results: {
|
||||
TOTAL_JOBS: i18n._('Total Jobs'),
|
||||
@ -68,6 +72,7 @@ export default ['workflowData', 'workflowResultsService', 'workflowDataOptions',
|
||||
ALWAYS: i18n._('Always'),
|
||||
PROJECT_SYNC: i18n._('Project Sync'),
|
||||
INVENTORY_SYNC: i18n._('Inventory Sync'),
|
||||
WORKFLOW: i18n._('Workflow'),
|
||||
KEY: i18n._('KEY'),
|
||||
}
|
||||
};
|
||||
@ -100,6 +105,9 @@ export default ['workflowData', 'workflowResultsService', 'workflowDataOptions',
|
||||
$scope.labels = jobLabels;
|
||||
$scope.count = count.val;
|
||||
$scope.showManualControls = false;
|
||||
$scope.showKey = false;
|
||||
$scope.toggleKey = () => $scope.showKey = !$scope.showKey;
|
||||
$scope.keyClassList = `{ 'Key-menuIcon--active': showKey }`;
|
||||
|
||||
// Start elapsed time updater for job known to be running
|
||||
if ($scope.workflow.started !== null && $scope.workflow.status === 'running') {
|
||||
@ -116,6 +124,27 @@ export default ['workflowData', 'workflowResultsService', 'workflowDataOptions',
|
||||
$scope.slice_job_template_link = `/#/templates/job_template/${$scope.workflow.summary_fields.job_template.id}`;
|
||||
}
|
||||
|
||||
if (_.get(workflowData, 'summary_fields.source_workflow_job.id')) {
|
||||
$scope.source_workflow_job_link = `/#/workflows/${workflowData.summary_fields.source_workflow_job.id}`;
|
||||
}
|
||||
|
||||
if (workflowData.job_explanation) {
|
||||
const limit = 150;
|
||||
const more = workflowData.job_explanation;
|
||||
const less = $filter('limitTo')(more, limit);
|
||||
const showMore = false;
|
||||
const hasMoreToShow = more.length > limit;
|
||||
|
||||
const job_explanation = {
|
||||
more: more,
|
||||
less: less,
|
||||
showMore: showMore,
|
||||
hasMoreToShow: hasMoreToShow
|
||||
};
|
||||
|
||||
$scope.job_explanation = job_explanation;
|
||||
}
|
||||
|
||||
// turn related api browser routes into front end routes
|
||||
getLinks();
|
||||
|
||||
|
@ -75,6 +75,33 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- EXPLANATION DETAIL -->
|
||||
<div class="WorkflowResults-resultRow" ng-show="workflow.job_explanation">
|
||||
<label class="WorkflowResults-resultRowLabel">
|
||||
{{ strings.labels.JOB_EXPLANATION }}
|
||||
</label>
|
||||
|
||||
<div class="WorkflowResults-resultRowText"
|
||||
ng-show="!job_explanation.showMore">
|
||||
{{ job_explanation.less }}
|
||||
<span ng-show="job_explanation.hasMoreToShow">...</span>
|
||||
<span ng-show="job_explanation.hasMoreToShow"
|
||||
class="WorkflowResults-seeMoreLess"
|
||||
ng-click="job_explanation.showMore = true">
|
||||
{{ strings.details.SHOW_MORE }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="WorkflowResults-resultRowText"
|
||||
ng-show="job_explanation.showMore">
|
||||
{{ job_explanation.more }}
|
||||
<span class="WorkflowResults-seeMoreLess"
|
||||
ng-click="job_explanation.showMore = false">
|
||||
{{ strings.details.SHOW_LESS }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- START TIME DETAIL -->
|
||||
<div class="WorkflowResults-resultRow"
|
||||
ng-show="workflow.started">
|
||||
@ -160,6 +187,19 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PARENT WORKFLOW DETAIL -->
|
||||
<div class="WorkflowResults-resultRow"
|
||||
ng-if="workflow.summary_fields.source_workflow_job">
|
||||
<label class="WorkflowResults-resultRowLabel">
|
||||
{{ strings.labels.SOURCE_WORKFLOW_JOB }}
|
||||
</label>
|
||||
<div class="WorkflowResults-resultRowText">
|
||||
<a href="{{ source_workflow_job_link }}">
|
||||
{{ workflow.summary_fields.source_workflow_job.name }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- EXTRA VARIABLES DETAIL -->
|
||||
<at-code-mirror
|
||||
ng-if="variables"
|
||||
@ -268,27 +308,36 @@
|
||||
<workflow-status-bar></workflow-status-bar>
|
||||
<div class="WorkflowLegend-details">
|
||||
<div class="WorkflowLegend-details--left">
|
||||
<div class="WorkflowLegend-legendItem">{{ strings.legend.KEY }}:</div>
|
||||
<div class="WorkflowLegend-legendItem">
|
||||
<div class="WorkflowLegend-onSuccessLegend"></div>
|
||||
<div>{{ strings.legend.ON_SUCCESS }}</div>
|
||||
</div>
|
||||
<div class="WorkflowLegend-legendItem">
|
||||
<div class="WorkflowLegend-onFailLegend"></div>
|
||||
<div>{{ strings.legend.ON_FAIL }}</div>
|
||||
</div>
|
||||
<div class="WorkflowLegend-legendItem">
|
||||
<div class="WorkflowLegend-alwaysLegend"></div>
|
||||
<div>{{ strings.legend.ALWAYS }}</div>
|
||||
</div>
|
||||
<div class="WorkflowLegend-legendItem">
|
||||
<div class="WorkflowLegend-letterCircle">P</div>
|
||||
<div>{{ strings.legend.PROJECT_SYNC }}</div>
|
||||
</div>
|
||||
<div class="WorkflowLegend-legendItem">
|
||||
<div class="WorkflowLegend-letterCircle">I</div>
|
||||
<div>{{ strings.legend.INVENTORY_SYNC }}</div>
|
||||
</div>
|
||||
<i ng-class="{{ keyClassList }}" class="fa fa-key Key-menuIcon" ng-click="toggleKey()"></i>
|
||||
<ul ng-show="showKey" class="Key-list noselect">
|
||||
<li class="Key-listItem">
|
||||
<p class="Key-heading">{{strings.legend.KEY}}</p>
|
||||
</li>
|
||||
<li class="Key-listItem">
|
||||
<div class="Key-icon Key-icon--success"></div>
|
||||
<p class="Key-listItemContent">{{strings.legend.ON_SUCCESS}}</p>
|
||||
</li>
|
||||
<li class="Key-listItem">
|
||||
<div class="Key-icon Key-icon--fail"></div>
|
||||
<p class="Key-listItemContent">{{strings.legend.ON_FAILURE}}</p>
|
||||
</li>
|
||||
<li class="Key-listItem">
|
||||
<div class="Key-icon Key-icon--always"></div>
|
||||
<p class="Key-listItemContent">{{strings.legend.ALWAYS}}</p>
|
||||
</li>
|
||||
<li class="Key-listItem">
|
||||
<div class="Key-icon Key-icon--circle Key-icon--default">P</div>
|
||||
<p class="Key-listItemContent Key-listItemContent--circle">{{strings.legend.PROJECT_SYNC}}</p>
|
||||
</li>
|
||||
<li class="Key-listItem">
|
||||
<div class="Key-icon Key-icon--circle Key-icon--default">I</div>
|
||||
<p class="Key-listItemContent Key-listItemContent--circle">{{strings.legend.INVENTORY_SYNC}}</p>
|
||||
</li>
|
||||
<li class="Key-listItem">
|
||||
<div class="Key-icon Key-icon--circle Key-icon--default">W</div>
|
||||
<p class="Key-listItemContent Key-listItemContent--circle">{{strings.legend.WORKFLOW}}</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="WorkflowLegend-details--right">
|
||||
<i ng-class="{'WorkflowMaker-manualControlsIcon--active': showManualControls}" class="fa fa-cog WorkflowMaker-manualControlsIcon" aria-hidden="true" alt="Controls" ng-click="toggleManualControls()"></i>
|
||||
|
Loading…
Reference in New Issue
Block a user