mirror of
https://github.com/ansible/awx.git
synced 2024-11-01 08:21:15 +03:00
Merge pull request #4195 from mabashian/4146-details-node-link
Implemented details link on workflow node
This commit is contained in:
commit
376098fe0a
@ -20,9 +20,12 @@
|
||||
fill: @default-err-hov;
|
||||
}
|
||||
|
||||
.node .WorkflowChart-defaultText {
|
||||
.node {
|
||||
font-size: 12px;
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
}
|
||||
|
||||
.WorkflowChart-defaultText {
|
||||
fill: @default-interface-txt;
|
||||
}
|
||||
|
||||
@ -76,3 +79,7 @@
|
||||
.workflowChart-nodeStatus--failed {
|
||||
fill: @default-err;
|
||||
}
|
||||
.WorkflowChart-detailsLink {
|
||||
fill: @default-link;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -4,8 +4,8 @@
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
export default [
|
||||
function() {
|
||||
export default [ '$state',
|
||||
function($state) {
|
||||
|
||||
return {
|
||||
scope: {
|
||||
@ -13,7 +13,8 @@ export default [
|
||||
canAddWorkflowJobTemplate: '=',
|
||||
addNode: '&',
|
||||
editNode: '&',
|
||||
deleteNode: '&'
|
||||
deleteNode: '&',
|
||||
mode: '@'
|
||||
},
|
||||
restrict: 'E',
|
||||
link: function(scope, element) {
|
||||
@ -64,8 +65,11 @@ export default [
|
||||
// TODO: this function is hacky and we need to come up with a better solution
|
||||
// see: http://stackoverflow.com/questions/15975440/add-ellipses-to-overflowing-text-in-svg#answer-27723752
|
||||
function wrap(text) {
|
||||
if(text && text.length > 15) {
|
||||
return text.substring(0,15) + '...';
|
||||
|
||||
let maxLength = scope.mode === 'details' ? 14 : 15;
|
||||
|
||||
if(text && text.length > maxLength) {
|
||||
return text.substring(0,maxLength) + '...';
|
||||
}
|
||||
else {
|
||||
return text;
|
||||
@ -156,11 +160,12 @@ export default [
|
||||
.attr("class", function(d) {
|
||||
return d.placeholder ? "rect placeholder" : "rect";
|
||||
});
|
||||
|
||||
thisNode.append("text")
|
||||
.attr("x", rectW / 2)
|
||||
.attr("y", rectH / 2)
|
||||
.attr("x", function(d){ return (scope.mode === 'details' && d.job && d.job.jobStatus) ? 20 : rectW / 2; })
|
||||
.attr("y", function(d){ return (scope.mode === 'details' && d.job && d.job.jobStatus) ? 10 : rectH / 2; })
|
||||
.attr("dy", ".35em")
|
||||
.attr("text-anchor", "middle")
|
||||
.attr("text-anchor", function(d){ return (scope.mode === 'details' && d.job && d.job.jobStatus) ? "inherit" : "middle"; })
|
||||
.attr("class", "WorkflowChart-defaultText WorkflowChart-nameText")
|
||||
.text(function (d) {
|
||||
return (d.unifiedJobTemplate && d.unifiedJobTemplate.name) ? d.unifiedJobTemplate.name : "";
|
||||
@ -199,6 +204,16 @@ export default [
|
||||
.classed("hovering", false);
|
||||
}
|
||||
});
|
||||
thisNode.append("text")
|
||||
.attr("x", rectW - 50)
|
||||
.attr("y", rectH - 10)
|
||||
.attr("dy", ".35em")
|
||||
.attr("class", "WorkflowChart-detailsLink")
|
||||
.style("display", function(d){ return d.job && d.job.jobStatus && d.job.unified_job_id ? null : "none"; })
|
||||
.text(function () {
|
||||
return "DETAILS";
|
||||
})
|
||||
.call(details);
|
||||
thisNode.append("circle")
|
||||
.attr("id", function(d){return "node-" + d.id + "-add";})
|
||||
.attr("cx", rectW)
|
||||
@ -288,27 +303,29 @@ export default [
|
||||
|
||||
let statusClass = "WorkflowChart-nodeStatus ";
|
||||
|
||||
switch(d.jobStatus) {
|
||||
case "pending":
|
||||
statusClass = "workflowChart-nodeStatus--running";
|
||||
break;
|
||||
case "waiting":
|
||||
statusClass = "workflowChart-nodeStatus--running";
|
||||
break;
|
||||
case "running":
|
||||
statusClass = "workflowChart-nodeStatus--running";
|
||||
break;
|
||||
case "successful":
|
||||
statusClass = "workflowChart-nodeStatus--success";
|
||||
break;
|
||||
case "failed":
|
||||
statusClass = "workflowChart-nodeStatus--failed";
|
||||
break;
|
||||
if(d.job){
|
||||
switch(d.job.jobStatus) {
|
||||
case "pending":
|
||||
statusClass = "workflowChart-nodeStatus--running";
|
||||
break;
|
||||
case "waiting":
|
||||
statusClass = "workflowChart-nodeStatus--running";
|
||||
break;
|
||||
case "running":
|
||||
statusClass = "workflowChart-nodeStatus--running";
|
||||
break;
|
||||
case "successful":
|
||||
statusClass = "workflowChart-nodeStatus--success";
|
||||
break;
|
||||
case "failed":
|
||||
statusClass = "workflowChart-nodeStatus--failed";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return statusClass;
|
||||
})
|
||||
.style("display", function(d) { return d.jobStatus ? null : "none"; })
|
||||
.style("display", function(d) { return d.job && d.job.jobStatus ? null : "none"; })
|
||||
.attr("cy", 10)
|
||||
.attr("cx", 10)
|
||||
.attr("r", 6);
|
||||
@ -456,11 +473,6 @@ export default [
|
||||
return d.placeholder ? "rect placeholder" : "rect";
|
||||
});
|
||||
|
||||
t.selectAll(".WorkflowChart-nameText")
|
||||
.text(function (d) {
|
||||
return (d.unifiedJobTemplate && d.unifiedJobTemplate.name) ? wrap(d.unifiedJobTemplate.name) : "";
|
||||
});
|
||||
|
||||
t.selectAll(".node")
|
||||
.attr("transform", function(d) {d.px = d.x; d.py = d.y; return "translate(" + d.y + "," + d.x + ")"; });
|
||||
|
||||
@ -478,32 +490,34 @@ export default [
|
||||
|
||||
let statusClass = "WorkflowChart-nodeStatus ";
|
||||
|
||||
switch(d.jobStatus) {
|
||||
case "pending":
|
||||
statusClass += "workflowChart-nodeStatus--running";
|
||||
break;
|
||||
case "waiting":
|
||||
statusClass += "workflowChart-nodeStatus--running";
|
||||
break;
|
||||
case "running":
|
||||
statusClass += "workflowChart-nodeStatus--running";
|
||||
break;
|
||||
case "successful":
|
||||
statusClass += "workflowChart-nodeStatus--success";
|
||||
break;
|
||||
case "failed":
|
||||
statusClass += "workflowChart-nodeStatus--failed";
|
||||
break;
|
||||
if(d.job){
|
||||
switch(d.job.jobStatus) {
|
||||
case "pending":
|
||||
statusClass += "workflowChart-nodeStatus--running";
|
||||
break;
|
||||
case "waiting":
|
||||
statusClass += "workflowChart-nodeStatus--running";
|
||||
break;
|
||||
case "running":
|
||||
statusClass += "workflowChart-nodeStatus--running";
|
||||
break;
|
||||
case "successful":
|
||||
statusClass += "workflowChart-nodeStatus--success";
|
||||
break;
|
||||
case "failed":
|
||||
statusClass += "workflowChart-nodeStatus--failed";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return statusClass;
|
||||
})
|
||||
.style("display", function(d) { return d.jobStatus ? null : "none"; })
|
||||
.style("display", function(d) { return d.job && d.job.jobStatus ? null : "none"; })
|
||||
.transition()
|
||||
.duration(0)
|
||||
.attr("r", 6)
|
||||
.each(function(d) {
|
||||
if(d.jobStatus && (d.jobStatus === "pending" || d.jobStatus === "waiting" || d.jobStatus === "running")) {
|
||||
if(d.job && d.job.jobStatus && (d.job.jobStatus === "pending" || d.job.jobStatus === "waiting" || d.job.jobStatus === "running")) {
|
||||
// Pulse the circle
|
||||
var circle = d3.select(this);
|
||||
(function repeat() {
|
||||
@ -519,6 +533,18 @@ export default [
|
||||
}
|
||||
});
|
||||
|
||||
t.selectAll(".WorkflowChart-nameText")
|
||||
.attr("x", function(d){ return (scope.mode === 'details' && d.job && d.job.jobStatus) ? 20 : rectW / 2; })
|
||||
.attr("y", function(d){ return (scope.mode === 'details' && d.job && d.job.jobStatus) ? 10 : rectH / 2; })
|
||||
.attr("text-anchor", function(d){ return (scope.mode === 'details' && d.job && d.job.jobStatus) ? "inherit" : "middle"; })
|
||||
.text(function (d) {
|
||||
return (d.unifiedJobTemplate && d.unifiedJobTemplate.name) ? wrap(d.unifiedJobTemplate.name) : "";
|
||||
});
|
||||
|
||||
t.selectAll(".WorkflowChart-detailsLink")
|
||||
.style("display", function(d){ return d.job && d.job.jobStatus && d.job.unified_job_id ? null : "none"; });
|
||||
|
||||
|
||||
}
|
||||
|
||||
function add_node() {
|
||||
@ -563,6 +589,28 @@ export default [
|
||||
});
|
||||
}
|
||||
|
||||
function details() {
|
||||
this.on("mouseover", function() {
|
||||
d3.select(this).style("text-decoration", "underline");
|
||||
});
|
||||
this.on("mouseout", function() {
|
||||
d3.select(this).style("text-decoration", null);
|
||||
});
|
||||
this.on("click", function(d) {
|
||||
if(d.job.unified_job_id && d.unifiedJobTemplate) {
|
||||
if(d.unifiedJobTemplate.unified_job_type === 'job') {
|
||||
$state.go('jobDetail', {id: d.job.unified_job_id});
|
||||
}
|
||||
else if(d.unifiedJobTemplate.unified_job_type === 'inventory_update') {
|
||||
$state.go('inventorySyncStdout', {id: d.job.unified_job_id});
|
||||
}
|
||||
else if(d.unifiedJobTemplate.unified_job_type === 'project_update') {
|
||||
$state.go('scmUpdateStdout', {id: d.job.unified_job_id});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
scope.$on('refreshWorkflowChart', function(){
|
||||
update();
|
||||
});
|
||||
|
@ -60,7 +60,7 @@
|
||||
<span class="badge List-titleBadge" ng-bind="treeData.data.totalNodes"></span>
|
||||
</div>
|
||||
</div>
|
||||
<workflow-chart tree-data="treeData.data" add-node="startAddNode(parent, betweenTwoNodes)" edit-node="startEditNode(nodeToEdit)" delete-node="startDeleteNode(nodeToDelete)" can-add-workflow-job-template="canAddWorkflowJobTemplate" class="WorkflowMaker-chart"></workflow-chart>
|
||||
<workflow-chart tree-data="treeData.data" add-node="startAddNode(parent, betweenTwoNodes)" edit-node="startEditNode(nodeToEdit)" delete-node="startDeleteNode(nodeToDelete)" can-add-workflow-job-template="canAddWorkflowJobTemplate" mode="edit" class="WorkflowMaker-chart"></workflow-chart>
|
||||
</div>
|
||||
<div class="WorkflowMaker-contentRight">
|
||||
<div class="WorkflowMaker-formTitle">{{(workflowMakerFormConfig.nodeMode === 'edit' && nodeBeingEdited && nodeBeingEdited.unifiedJobTemplate && nodeBeingEdited.unifiedJobTemplate.name) ? nodeBeingEdited.unifiedJobTemplate.name : "ADD A TEMPLATE"}}</div>
|
||||
|
@ -221,7 +221,10 @@ export default [function(){
|
||||
}
|
||||
|
||||
if(params.nodesObj[params.nodeId].summary_fields.job) {
|
||||
treeNode.jobStatus = params.nodesObj[params.nodeId].summary_fields.job.status;
|
||||
treeNode.job = {
|
||||
jobStatus: params.nodesObj[params.nodeId].summary_fields.job.status,
|
||||
unified_job_id: params.nodesObj[params.nodeId].summary_fields.job.id
|
||||
};
|
||||
}
|
||||
|
||||
// Loop across the success nodes and add them recursively
|
||||
@ -271,7 +274,10 @@ export default [function(){
|
||||
});
|
||||
|
||||
if(matchingNode) {
|
||||
matchingNode.jobStatus = params.status;
|
||||
matchingNode.job = {
|
||||
jobStatus: params.status,
|
||||
unified_job_id: params.unified_job_id
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -118,7 +118,8 @@ export default ['workflowData',
|
||||
WorkflowService.updateStatusOfNode({
|
||||
treeData: $scope.treeData,
|
||||
nodeId: data.workflow_node_id,
|
||||
status: data.status
|
||||
status: data.status,
|
||||
unified_job_id: data.unified_job_id
|
||||
});
|
||||
|
||||
$scope.$broadcast("refreshWorkflowChart");
|
||||
|
@ -216,7 +216,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<workflow-status-bar></workflow-status-bar>
|
||||
<workflow-chart tree-data="treeData.data" can-add-workflow-job-template="canAddWorkflowJobTemplate" class="WorkflowMaker-chart"></workflow-chart>
|
||||
<workflow-chart tree-data="treeData.data" can-add-workflow-job-template="canAddWorkflowJobTemplate" mode="details" class="WorkflowMaker-chart"></workflow-chart>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -67,7 +67,7 @@ describe('Controller: jobResultsController', () => {
|
||||
.respond('');
|
||||
|
||||
$httpBackend
|
||||
.whenGET('/api/')
|
||||
.whenGET('/api')
|
||||
.respond(200, '');
|
||||
|
||||
$scope = $rootScope.$new();
|
||||
|
@ -29,7 +29,7 @@ describe('Service: QuerySet', () => {
|
||||
// @todo: improve appsource
|
||||
// provide api version via package.json config block
|
||||
$httpBackend
|
||||
.whenGET('/api/')
|
||||
.whenGET('/api')
|
||||
.respond(200, '');
|
||||
}));
|
||||
|
||||
|
@ -81,7 +81,7 @@ describe('Controller: WorkflowAdd', () => {
|
||||
ToJSON = _ToJSON_;
|
||||
|
||||
httpBackend
|
||||
.whenGET('/api/')
|
||||
.whenGET('/api')
|
||||
.respond(200, '');
|
||||
|
||||
TemplatesService.getLabelOptions = jasmine.createSpy('getLabelOptions').and.returnValue(getLabelsDeferred.promise);
|
||||
|
Loading…
Reference in New Issue
Block a user