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 --> <!-- 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.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 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>
<div class="HostEvent-body"> <div class="HostEvent-body">

View File

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

View File

@@ -6,8 +6,8 @@
export default export default
['$stateParams', '$scope', '$state', 'Wait', 'JobDetailService', 'hostEvent', ['$stateParams', '$scope', '$state', 'Wait', 'JobDetailService', 'hostEvent', 'hostResults',
function($stateParams, $scope, $state, Wait, JobDetailService, hostEvent){ function($stateParams, $scope, $state, Wait, JobDetailService, hostEvent, hostResults){
$scope.processEventStatus = JobDetailService.processEventStatus; $scope.processEventStatus = JobDetailService.processEventStatus;
$scope.hostResults = []; $scope.hostResults = [];
@@ -17,15 +17,20 @@
if (typeof value === 'object'){return false;} if (typeof value === 'object'){return false;}
else {return true;} 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*/ /*ignore jslint start*/
var initCodeMirror = function(el, json){ var initCodeMirror = function(el, data, mode){
var container = $(el)[0]; var container = document.getElementById(el);
var editor = CodeMirror.fromTextArea(container, { // jshint ignore:line var editor = CodeMirror.fromTextArea(container, { // jshint ignore:line
lineNumbers: true, lineNumbers: true,
mode: {name: "javascript", json: true} mode: mode
}); });
editor.setSize("100%", 300); editor.setSize("100%", 300);
editor.getDoc().setValue(JSON.stringify(json, null, 4)); editor.getDoc().setValue(data);
}; };
/*ignore jslint end*/ /*ignore jslint end*/
$scope.isActiveState = function(name){ $scope.isActiveState = function(name){
@@ -60,26 +65,45 @@
}; };
var init = function(){ var init = function(){
$scope.event = hostEvent; $scope.event = _.cloneDeep(hostEvent);
JobDetailService.getJobEventChildren($stateParams.taskId).success(function(res){ $scope.hostResults = hostResults;
$scope.hostResults = res.results; $scope.json = JobDetailService.processJson(hostEvent);
});
$scope.json = JobDetailService.processJson($scope.event); // grab standard out & standard error if present, and remove from the results displayed in the details panel
/* jshint ignore:start */ if (hostEvent.event_data.res.stdout){
if ($state.current.name === 'jobDetail.host-event.json'){ $scope.stdout = hostEvent.event_data.res.stdout;
initCodeMirror('#HostEvent-json', $scope.json); delete $scope.event.event_data.res.stdout;
} }
try { if (hostEvent.event_data.res.stderr){
$scope.stdout = JobDetailService $scope.stderr = hostEvent.event_data.res.stderr;
.processJson($scope.event.event_data.res.stdout); delete $scope.event.event_data.res.stderr;
if ($state.current.name === 'jobDetail.host-event.stdout'){ }
initCodeMirror('#HostEvent-stdout', $scope.stdout); // 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){ else if ($state.current.name === 'jobDetail.host-event.stdout'){
$scope.stdout = null; 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'); $('#HostEvent').modal('show');
}; };
init(); init();

View File

@@ -17,6 +17,9 @@ var hostEventModal = {
return JobDetailService.getRelatedJobEvents($stateParams.id, { return JobDetailService.getRelatedJobEvents($stateParams.id, {
id: $stateParams.eventId id: $stateParams.eventId
}).then(function(res){ return res.data.results[0];}); }).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() { onExit: function() {
@@ -40,7 +43,22 @@ var hostEventModal = {
name: 'jobDetail.host-event.json', name: 'jobDetail.host-event.json',
url: '/json', url: '/json',
controller: 'HostEventController', 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, import {hostEventModal, hostEventDetails,
hostEventJson} from './host-event.route'; hostEventJson, hostEventStdout, hostEventStderr} from './host-event.route';
import controller from './host-event.controller'; import controller from './host-event.controller';
export default export default
@@ -16,4 +16,6 @@
$stateExtender.addState(hostEventModal); $stateExtender.addState(hostEventModal);
$stateExtender.addState(hostEventDetails); $stateExtender.addState(hostEventDetails);
$stateExtender.addState(hostEventJson); $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 // 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){ processJson: function(data){
// a deep copy
var result = $.extend(true, {}, data);
// configure fields to ignore // configure fields to ignore
var ignored = [ var ignored = [
'type',
'event_data', 'event_data',
'related', 'related',
'summary_fields', 'summary_fields',
'url', 'url',
'ansible_facts', 'ansible_facts',
]; ];
// remove ignored properties // remove ignored properties
Object.keys(result).forEach(function(key){ var result = _.chain(data).cloneDeep().forEach(function(value, key, collection){
if (ignored.indexOf(key) > -1) { if (ignored.indexOf(key) > -1){
delete result[key]; delete collection[key];
} }
}); }).value();
return result;
// 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;
}, },
// Return Ansible's passed-through response msg on a job_event // Return Ansible's passed-through response msg on a job_event
processEventMsg: function(event){ processEventMsg: function(event){