1
0
mirror of https://github.com/ansible/awx.git synced 2024-11-01 16:51:11 +03:00

fix host event stdout tab, add stderr tab, remove stdout/err msgs from details view, style fixes, resolves #2125 (#2187)

This commit is contained in:
Leigh 2016-06-07 11:03:35 -04:00
parent c4b06ce7c0
commit 3b6e528837
8 changed files with 84 additions and 51 deletions

View File

@ -0,0 +1,2 @@
<textarea id="HostEvent-codemirror" class="HostEvent-codemirror">
</textarea>

View File

@ -1,2 +0,0 @@
<textarea id="HostEvent-json" class="HostEvent-json">
</textarea>

View File

@ -14,6 +14,8 @@
<!-- view navigation buttons -->
<button ui-sref="jobDetail.host-event.details" type="button" class="btn btn-sm btn-default" ng-class="{'HostEvent-tab--selected' : isActiveState('jobDetail.host-event.details')}">Details</button>
<button ui-sref="jobDetail.host-event.json" type="button" class="btn btn-sm btn-default " ng-class="{'HostEvent-tab--selected' : isActiveState('jobDetail.host-event.json')}">JSON</button>
<button ng-if="stdout" ui-sref="jobDetail.host-event.stdout" type="button" class="btn btn-sm btn-default " ng-class="{'HostEvent-tab--selected' : isActiveState('jobDetail.host-event.stdout')}">Standard Out</button>
<button ng-if="stderr" ui-sref="jobDetail.host-event.stderr" type="button" class="btn btn-sm btn-default " ng-class="{'HostEvent-tab--selected' : isActiveState('jobDetail.host-event.stderr')}">Standard Error</button>
</div>
<div class="HostEvent-body">

View File

@ -7,6 +7,9 @@
width: 700px;
}
}
.HostEvent .CodeMirror{
overflow-x: hidden;
}
.HostEvent-controls button.HostEvent-close{
color: #FFFFFF;
text-transform: uppercase;
@ -78,7 +81,7 @@
.HostEvent-field--label{
text-transform: uppercase;
flex: 0 1 80px;
margin-right: 20px;
max-width: 80px;
font-size: 12px;
word-wrap: break-word;
}

View File

@ -6,8 +6,8 @@
export default
['$stateParams', '$scope', '$state', 'Wait', 'JobDetailService', 'hostEvent',
function($stateParams, $scope, $state, Wait, JobDetailService, hostEvent){
['$stateParams', '$scope', '$state', 'Wait', 'JobDetailService', 'hostEvent', 'hostResults',
function($stateParams, $scope, $state, Wait, JobDetailService, hostEvent, hostResults){
$scope.processEventStatus = JobDetailService.processEventStatus;
$scope.hostResults = [];
@ -17,15 +17,20 @@
if (typeof value === 'object'){return false;}
else {return true;}
};
$scope.isStdOut = function(){
if ($state.current.name === 'jobDetails.host-event.stdout' || $state.current.name === 'jobDetaisl.histe-event.stderr'){
return 'StandardOut-preContainer StandardOut-preContent';
}
};
/*ignore jslint start*/
var initCodeMirror = function(el, json){
var container = $(el)[0];
var initCodeMirror = function(el, data, mode){
var container = document.getElementById(el);
var editor = CodeMirror.fromTextArea(container, { // jshint ignore:line
lineNumbers: true,
mode: {name: "javascript", json: true}
mode: mode
});
editor.setSize("100%", 300);
editor.getDoc().setValue(JSON.stringify(json, null, 4));
editor.getDoc().setValue(data);
};
/*ignore jslint end*/
$scope.isActiveState = function(name){
@ -60,26 +65,45 @@
};
var init = function(){
$scope.event = hostEvent;
JobDetailService.getJobEventChildren($stateParams.taskId).success(function(res){
$scope.hostResults = res.results;
});
$scope.json = JobDetailService.processJson($scope.event);
/* jshint ignore:start */
if ($state.current.name === 'jobDetail.host-event.json'){
initCodeMirror('#HostEvent-json', $scope.json);
$scope.event = _.cloneDeep(hostEvent);
$scope.hostResults = hostResults;
$scope.json = JobDetailService.processJson(hostEvent);
// grab standard out & standard error if present, and remove from the results displayed in the details panel
if (hostEvent.event_data.res.stdout){
$scope.stdout = hostEvent.event_data.res.stdout;
delete $scope.event.event_data.res.stdout;
}
try {
$scope.stdout = JobDetailService
.processJson($scope.event.event_data.res.stdout);
if ($state.current.name === 'jobDetail.host-event.stdout'){
initCodeMirror('#HostEvent-stdout', $scope.stdout);
if (hostEvent.event_data.res.stderr){
$scope.stderr = hostEvent.event_data.res.stderr;
delete $scope.event.event_data.res.stderr;
}
// instantiate Codemirror
// try/catch pattern prevents the abstract-state controller from complaining about element being null
if ($state.current.name === 'jobDetail.host-event.json'){
try{
initCodeMirror('HostEvent-codemirror', JSON.stringify($scope.json, null, 4), {name: "javascript", json: true});
}
catch(err){
// element with id HostEvent-codemirror is not the view controlled by this instance of HostEventController
}
}
catch(err){
$scope.stdout = null;
else if ($state.current.name === 'jobDetail.host-event.stdout'){
try{
initCodeMirror('HostEvent-codemirror', $scope.stdout, 'shell');
}
catch(err){
// element with id HostEvent-codemirror is not the view controlled by this instance of HostEventController
}
}
else if ($state.current.name === 'jobDetail.host-event.stderr'){
try{
initCodeMirror('HostEvent-codemirror', $scope.stderr, 'shell');
}
catch(err){
// element with id HostEvent-codemirror is not the view controlled by this instance of HostEventController
}
}
/* jshint ignore:end */
$('#HostEvent').modal('show');
};
init();

View File

@ -17,6 +17,9 @@ var hostEventModal = {
return JobDetailService.getRelatedJobEvents($stateParams.id, {
id: $stateParams.eventId
}).then(function(res){ return res.data.results[0];});
}],
hostResults: ['JobDetailService', '$stateParams', function(JobDetailService, $stateParams){
return JobDetailService.getJobEventChildren($stateParams.taskId).then(res => res.data.results);
}]
},
onExit: function() {
@ -40,7 +43,22 @@ var hostEventModal = {
name: 'jobDetail.host-event.json',
url: '/json',
controller: 'HostEventController',
templateUrl: templateUrl('job-detail/host-event/host-event-json')
templateUrl: templateUrl('job-detail/host-event/host-event-codemirror')
};
export {hostEventDetails, hostEventJson, hostEventModal};
var hostEventStdout = {
name: 'jobDetail.host-event.stdout',
url: '/stdout',
controller: 'HostEventController',
templateUrl: templateUrl('job-detail/host-event/host-event-codemirror')
};
var hostEventStderr = {
name: 'jobDetail.host-event.stderr',
url: '/stderr',
controller: 'HostEventController',
templateUrl: templateUrl('job-detail/host-event/host-event-codemirror')
};
export {hostEventDetails, hostEventJson, hostEventModal, hostEventStdout, hostEventStderr};

View File

@ -5,7 +5,7 @@
*************************************************/
import {hostEventModal, hostEventDetails,
hostEventJson} from './host-event.route';
hostEventJson, hostEventStdout, hostEventStderr} from './host-event.route';
import controller from './host-event.controller';
export default
@ -16,4 +16,6 @@
$stateExtender.addState(hostEventModal);
$stateExtender.addState(hostEventDetails);
$stateExtender.addState(hostEventJson);
$stateExtender.addState(hostEventStdout);
$stateExtender.addState(hostEventStderr);
}]);

View File

@ -8,40 +8,24 @@ export default
},
// the the API passes through Ansible's event_data response
// we need to massage away the verbose and redundant properties
// we need to massage away the verbose & redundant stdout/stderr properties
processJson: function(data){
// a deep copy
var result = $.extend(true, {}, data);
// configure fields to ignore
var ignored = [
'type',
'event_data',
'related',
'summary_fields',
'url',
'ansible_facts',
];
// remove ignored properties
Object.keys(result).forEach(function(key){
if (ignored.indexOf(key) > -1) {
delete result[key];
var result = _.chain(data).cloneDeep().forEach(function(value, key, collection){
if (ignored.indexOf(key) > -1){
delete collection[key];
}
});
// flatten Ansible's passed-through response
try{
result.event_data = {};
Object.keys(data.event_data.res).forEach(function(key){
if (ignored.indexOf(key) > -1) {
return;
}
else{
result.event_data[key] = data.event_data.res[key];
}
});
}
catch(err){result.event_data = undefined;}
return result === {} ? null : result;
}).value();
return result;
},
// Return Ansible's passed-through response msg on a job_event
processEventMsg: function(event){