From 3b6e528837607108f9c991f0b57a390d18220b9e Mon Sep 17 00:00:00 2001 From: Leigh Date: Tue, 7 Jun 2016 11:03:35 -0400 Subject: [PATCH] fix host event stdout tab, add stderr tab, remove stdout/err msgs from details view, style fixes, resolves #2125 (#2187) --- .../host-event-codemirror.partial.html | 2 + .../host-event/host-event-json.partial.html | 2 - .../host-event/host-event-modal.partial.html | 2 + .../host-event/host-event.block.less | 5 +- .../host-event/host-event.controller.js | 68 +++++++++++++------ .../job-detail/host-event/host-event.route.js | 22 +++++- .../client/src/job-detail/host-event/main.js | 4 +- .../src/job-detail/job-detail.service.js | 30 ++------ 8 files changed, 84 insertions(+), 51 deletions(-) create mode 100644 awx/ui/client/src/job-detail/host-event/host-event-codemirror.partial.html delete mode 100644 awx/ui/client/src/job-detail/host-event/host-event-json.partial.html diff --git a/awx/ui/client/src/job-detail/host-event/host-event-codemirror.partial.html b/awx/ui/client/src/job-detail/host-event/host-event-codemirror.partial.html new file mode 100644 index 0000000000..7c744d2169 --- /dev/null +++ b/awx/ui/client/src/job-detail/host-event/host-event-codemirror.partial.html @@ -0,0 +1,2 @@ + diff --git a/awx/ui/client/src/job-detail/host-event/host-event-json.partial.html b/awx/ui/client/src/job-detail/host-event/host-event-json.partial.html deleted file mode 100644 index a574043dbd..0000000000 --- a/awx/ui/client/src/job-detail/host-event/host-event-json.partial.html +++ /dev/null @@ -1,2 +0,0 @@ - \ No newline at end of file diff --git a/awx/ui/client/src/job-detail/host-event/host-event-modal.partial.html b/awx/ui/client/src/job-detail/host-event/host-event-modal.partial.html index 1660de1b57..a48f9de95e 100644 --- a/awx/ui/client/src/job-detail/host-event/host-event-modal.partial.html +++ b/awx/ui/client/src/job-detail/host-event/host-event-modal.partial.html @@ -14,6 +14,8 @@ + +
diff --git a/awx/ui/client/src/job-detail/host-event/host-event.block.less b/awx/ui/client/src/job-detail/host-event/host-event.block.less index 6a3b6d637d..4df56a4d8c 100644 --- a/awx/ui/client/src/job-detail/host-event/host-event.block.less +++ b/awx/ui/client/src/job-detail/host-event/host-event.block.less @@ -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; } diff --git a/awx/ui/client/src/job-detail/host-event/host-event.controller.js b/awx/ui/client/src/job-detail/host-event/host-event.controller.js index 79c25dbf5f..f86452b005 100644 --- a/awx/ui/client/src/job-detail/host-event/host-event.controller.js +++ b/awx/ui/client/src/job-detail/host-event/host-event.controller.js @@ -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(); diff --git a/awx/ui/client/src/job-detail/host-event/host-event.route.js b/awx/ui/client/src/job-detail/host-event/host-event.route.js index e734b641cf..885034b747 100644 --- a/awx/ui/client/src/job-detail/host-event/host-event.route.js +++ b/awx/ui/client/src/job-detail/host-event/host-event.route.js @@ -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}; diff --git a/awx/ui/client/src/job-detail/host-event/main.js b/awx/ui/client/src/job-detail/host-event/main.js index a24bbdd5ae..4379427ff8 100644 --- a/awx/ui/client/src/job-detail/host-event/main.js +++ b/awx/ui/client/src/job-detail/host-event/main.js @@ -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); }]); diff --git a/awx/ui/client/src/job-detail/job-detail.service.js b/awx/ui/client/src/job-detail/job-detail.service.js index 61b67b1035..df3033d708 100644 --- a/awx/ui/client/src/job-detail/job-detail.service.js +++ b/awx/ui/client/src/job-detail/job-detail.service.js @@ -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){