mirror of
https://github.com/ZwareBear/awx.git
synced 2026-04-11 10:31:48 -05:00
271 lines
11 KiB
JavaScript
271 lines
11 KiB
JavaScript
export default ['workflowData', 'workflowResultsService', 'workflowDataOptions',
|
|
'jobLabels', 'workflowNodes', '$scope', 'ParseTypeChange',
|
|
'ParseVariableString', 'WorkflowService', 'count', '$state', 'i18n',
|
|
'moment', function(workflowData, workflowResultsService,
|
|
workflowDataOptions, jobLabels, workflowNodes, $scope, ParseTypeChange,
|
|
ParseVariableString, WorkflowService, count, $state, i18n, moment) {
|
|
var runTimeElapsedTimer = null;
|
|
|
|
var getLinks = function() {
|
|
var getLink = function(key) {
|
|
if(key === 'schedule') {
|
|
if($scope.workflow.related.schedule) {
|
|
return '/#/templates/workflow_job_template/' + $scope.workflow.workflow_job_template + '/schedules' + $scope.workflow.related.schedule.split(/api\/v\d+\/schedules/)[1];
|
|
}
|
|
else {
|
|
return null;
|
|
}
|
|
}
|
|
else {
|
|
if ($scope.workflow.related[key]) {
|
|
return '/#/' + $scope.workflow.related[key]
|
|
.split(/api\/v\d+\//)[1];
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
};
|
|
|
|
$scope.workflow_template_link = '/#/templates/workflow_job_template/'+$scope.workflow.workflow_job_template;
|
|
$scope.created_by_link = getLink('created_by');
|
|
$scope.scheduled_by_link = getLink('schedule');
|
|
$scope.cloud_credential_link = getLink('cloud_credential');
|
|
$scope.network_credential_link = getLink('network_credential');
|
|
|
|
$scope.strings = {
|
|
tooltips: {
|
|
RELAUNCH: i18n._('Relaunch using the same parameters'),
|
|
CANCEL: i18n._('Cancel'),
|
|
DELETE: i18n._('Delete'),
|
|
EDIT_USER: i18n._('Edit the user'),
|
|
EDIT_WORKFLOW: i18n._('Edit the workflow job template'),
|
|
EDIT_SCHEDULE: i18n._('Edit the schedule'),
|
|
TOGGLE_STDOUT_FULLSCREEN: i18n._('Expand Output'),
|
|
STATUS: '' // re-assigned elsewhere
|
|
},
|
|
labels: {
|
|
TEMPLATE: i18n._('Template'),
|
|
LAUNCHED_BY: i18n._('Launched By'),
|
|
STARTED: i18n._('Started'),
|
|
FINISHED: i18n._('Finished'),
|
|
LABELS: i18n._('Labels'),
|
|
STATUS: '', // re-assigned elsewhere
|
|
JOB_TYPE: '', // re-assigned elsewhere
|
|
VERBOSITY: '', // re-assigned elsewhere
|
|
},
|
|
details: {
|
|
HEADER: i18n._('DETAILS'),
|
|
NOT_FINISHED: i18n._('Not Finished'),
|
|
NOT_STARTED: i18n._('Not Started'),
|
|
},
|
|
results: {
|
|
TOTAL_JOBS: i18n._('Total Jobs'),
|
|
ELAPSED: i18n._('Elapsed'),
|
|
},
|
|
legend: {
|
|
ON_SUCCESS: i18n._('On Success'),
|
|
ON_FAIL: i18n._('On Fail'),
|
|
ALWAYS: i18n._('Always'),
|
|
PROJECT_SYNC: i18n._('Project Sync'),
|
|
INVENTORY_SYNC: i18n._('Inventory Sync'),
|
|
KEY: i18n._('KEY'),
|
|
}
|
|
};
|
|
};
|
|
|
|
var getLabelsAndTooltips = function() {
|
|
var getLabel = 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.strings.labels.STATUS = getLabel('status');
|
|
$scope.strings.tooltips.STATUS = `Job ${$scope.strings.labels.STATUS}`;
|
|
$scope.strings.labels.JOB_TYPE = getLabel('job_type');
|
|
$scope.strings.labels.VERBOSITY = getLabel('verbosity');
|
|
};
|
|
|
|
var updateWorkflowJobElapsedTimer = function(time) {
|
|
$scope.workflow.elapsed = time;
|
|
};
|
|
|
|
function init() {
|
|
// put initially resolved request data on scope
|
|
$scope.workflow = workflowData;
|
|
$scope.workflow_nodes = workflowNodes;
|
|
$scope.workflowOptions = workflowDataOptions.actions.GET;
|
|
$scope.labels = jobLabels;
|
|
$scope.count = count.val;
|
|
$scope.showManualControls = false;
|
|
|
|
// Start elapsed time updater for job known to be running
|
|
if ($scope.workflow.started !== null && $scope.workflow.status === 'running') {
|
|
runTimeElapsedTimer = workflowResultsService.createOneSecondTimer($scope.workflow.started, updateWorkflowJobElapsedTimer);
|
|
}
|
|
|
|
if(workflowData.summary_fields && workflowData.summary_fields.workflow_job_template &&
|
|
workflowData.summary_fields.workflow_job_template.id){
|
|
$scope.workflow_job_template_link = `/#/templates/workflow_job_template/${$scope.workflow.summary_fields.workflow_job_template.id}`;
|
|
}
|
|
|
|
// turn related api browser routes into front end routes
|
|
getLinks();
|
|
|
|
// use options labels to manipulate display of details
|
|
getLabelsAndTooltips();
|
|
|
|
// set up a read only code mirror for extra vars
|
|
$scope.variables = ParseVariableString($scope.workflow.extra_vars);
|
|
$scope.parseType = 'yaml';
|
|
$scope.varsTooltip= i18n._('Read only view of extra variables added to the workflow.');
|
|
$scope.varsLabel = i18n._('Extra Variables');
|
|
|
|
|
|
// Click binding for the expand/collapse button on the standard out log
|
|
$scope.stdoutFullScreen = false;
|
|
|
|
WorkflowService.buildTree({
|
|
workflowNodes: workflowNodes
|
|
}).then(function(data){
|
|
$scope.treeData = data;
|
|
|
|
// 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.canAddWorkflowJobTemplate = false;
|
|
});
|
|
|
|
}
|
|
|
|
$scope.toggleStdoutFullscreen = function() {
|
|
|
|
$scope.$broadcast('workflowDetailsResized');
|
|
|
|
$scope.stdoutFullScreen = !$scope.stdoutFullScreen;
|
|
|
|
if ($scope.stdoutFullScreen === true) {
|
|
$scope.toggleStdoutFullscreenTooltip = i18n._("Collapse Output");
|
|
} else if ($scope.stdoutFullScreen === false) {
|
|
$scope.toggleStdoutFullscreenTooltip = i18n._("Expand Output");
|
|
}
|
|
};
|
|
|
|
$scope.deleteJob = function() {
|
|
workflowResultsService.deleteJob($scope.workflow);
|
|
};
|
|
|
|
$scope.cancelJob = function() {
|
|
workflowResultsService.cancelJob($scope.workflow);
|
|
};
|
|
|
|
$scope.relaunchJob = function() {
|
|
workflowResultsService.relaunchJob($scope);
|
|
};
|
|
|
|
$scope.toggleManualControls = function() {
|
|
$scope.showManualControls = !$scope.showManualControls;
|
|
};
|
|
|
|
$scope.lessLabels = false;
|
|
$scope.toggleLessLabels = function() {
|
|
if (!$scope.lessLabels) {
|
|
$('#workflow-results-labels').slideUp(200);
|
|
$scope.lessLabels = true;
|
|
}
|
|
else {
|
|
$('#workflow-results-labels').slideDown(200);
|
|
$scope.lessLabels = false;
|
|
}
|
|
};
|
|
|
|
$scope.panChart = function(direction) {
|
|
$scope.$broadcast('panWorkflowChart', {
|
|
direction: direction
|
|
});
|
|
};
|
|
|
|
$scope.zoomChart = function(zoom) {
|
|
$scope.$broadcast('zoomWorkflowChart', {
|
|
zoom: zoom
|
|
});
|
|
};
|
|
|
|
$scope.resetChart = function() {
|
|
$scope.$broadcast('resetWorkflowChart');
|
|
};
|
|
|
|
$scope.zoomToFitChart = function() {
|
|
$scope.$broadcast('zoomToFitChart');
|
|
};
|
|
|
|
$scope.workflowZoomed = function(zoom) {
|
|
$scope.$broadcast('workflowZoomed', {
|
|
zoom: zoom
|
|
});
|
|
};
|
|
|
|
init();
|
|
|
|
// Processing of job-status messages from the websocket
|
|
$scope.$on(`ws-jobs`, function(e, data) {
|
|
// Update the workflow job's unified job:
|
|
if (parseInt(data.unified_job_id, 10) === parseInt($scope.workflow.id,10)) {
|
|
$scope.workflow.status = data.status;
|
|
// start internval counter for job that transitioned to running
|
|
if ($scope.workflow.status === 'running') {
|
|
runTimeElapsedTimer = workflowResultsService.createOneSecondTimer(moment(), updateWorkflowJobElapsedTimer);
|
|
}
|
|
|
|
if(data.status === "successful" || data.status === "failed" || data.status === "error"){
|
|
$state.go('.', null, { reload: true });
|
|
}
|
|
}
|
|
// Update the jobs spawned by the workflow:
|
|
if(data.hasOwnProperty('workflow_job_id') &&
|
|
parseInt(data.workflow_job_id, 10) === parseInt($scope.workflow.id,10)){
|
|
|
|
// This check ensures that the workflow status icon doesn't get stuck in
|
|
// the waiting state due to the UI missing the initial socket message. This
|
|
// can happen if the GET request on the workflow job returns "waiting" and
|
|
// the sockets aren't established yet so we miss the event that indicates
|
|
// the workflow job has moved into a running state.
|
|
if (!_.includes(['running', 'successful', 'failed', 'error'], $scope.workflow.status)){
|
|
$scope.workflow.status = 'running';
|
|
runTimeElapsedTimer = workflowResultsService.createOneSecondTimer(moment(), updateWorkflowJobElapsedTimer);
|
|
}
|
|
|
|
WorkflowService.updateStatusOfNode({
|
|
treeData: $scope.treeData,
|
|
nodeId: data.workflow_node_id,
|
|
status: data.status,
|
|
unified_job_id: data.unified_job_id
|
|
});
|
|
|
|
$scope.workflow_nodes.forEach(node => {
|
|
if(parseInt(node.id) === parseInt(data.workflow_node_id)){
|
|
node.summary_fields.job = {
|
|
status: data.status
|
|
};
|
|
}
|
|
});
|
|
|
|
$scope.count = workflowResultsService
|
|
.getCounts($scope.workflow_nodes);
|
|
$scope.$broadcast("refreshWorkflowChart");
|
|
}
|
|
});
|
|
|
|
$scope.$on('$destroy', function() {
|
|
workflowResultsService.destroyTimer(runTimeElapsedTimer);
|
|
});
|
|
}];
|