From b3c5df193a1375b9be189d8f1906b35f606d588e Mon Sep 17 00:00:00 2001 From: Jake McDermott Date: Tue, 16 Oct 2018 11:52:14 -0400 Subject: [PATCH 1/8] don't render playbook_on_notify or runner_on_ok events if they have no stdout --- awx/ui/client/features/output/constants.js | 2 ++ awx/ui/client/features/output/render.service.js | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/awx/ui/client/features/output/constants.js b/awx/ui/client/features/output/constants.js index e8880587b1..5db41c31d4 100644 --- a/awx/ui/client/features/output/constants.js +++ b/awx/ui/client/features/output/constants.js @@ -1,6 +1,8 @@ export const API_MAX_PAGE_SIZE = 200; export const API_ROOT = '/api/v2/'; +export const EVENT_NOTIFY_PLAYBOOK = 'playbook_on_notify'; +export const EVENT_RUNNER_OK = 'runner_on_ok'; export const EVENT_START_TASK = 'playbook_on_task_start'; export const EVENT_START_PLAY = 'playbook_on_play_start'; export const EVENT_START_PLAYBOOK = 'playbook_on_start'; diff --git a/awx/ui/client/features/output/render.service.js b/awx/ui/client/features/output/render.service.js index 6111cbbe8d..386a19fe05 100644 --- a/awx/ui/client/features/output/render.service.js +++ b/awx/ui/client/features/output/render.service.js @@ -2,6 +2,8 @@ import Ansi from 'ansi-to-html'; import Entities from 'html-entities'; import { + EVENT_NOTIFY_PLAYBOOK, + EVENT_RUNNER_OK, EVENT_START_PLAY, EVENT_START_PLAYBOOK, EVENT_STATS_PLAY, @@ -213,6 +215,14 @@ function JobRenderService ($q, $sce, $window) { return { html: '', count: 0 }; } + if (event.stdout === '' && event.event === EVENT_NOTIFY_PLAYBOOK) { + return { html: '', count: 0 }; + } + + if (event.stdout === '' && event.event === EVENT_RUNNER_OK) { + return { html: '', count: 0 }; + } + let html = ''; let count = lines.length; let ln = event.start_line; From f28f1e434d2e502efb729a9693fed5918519eb4f Mon Sep 17 00:00:00 2001 From: Jake McDermott Date: Tue, 16 Oct 2018 12:32:05 -0400 Subject: [PATCH 2/8] adjust output line wrapping --- awx/ui/client/features/output/_index.less | 1 - 1 file changed, 1 deletion(-) diff --git a/awx/ui/client/features/output/_index.less b/awx/ui/client/features/output/_index.less index 4684bb8b16..d1132d9ec2 100644 --- a/awx/ui/client/features/output/_index.less +++ b/awx/ui/client/features/output/_index.less @@ -175,7 +175,6 @@ } .at-mixin-event() { - flex: 1; padding: 0 10px; white-space: pre-wrap; word-break: break-all; From c25af96c56177ae0bb589f7c4b5a7d2bcb3d6573 Mon Sep 17 00:00:00 2001 From: Jake McDermott Date: Mon, 5 Nov 2018 14:59:15 -0500 Subject: [PATCH 3/8] don't render events if stdout is zero-length string --- awx/ui/client/features/output/render.service.js | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/awx/ui/client/features/output/render.service.js b/awx/ui/client/features/output/render.service.js index 386a19fe05..a10beb29b2 100644 --- a/awx/ui/client/features/output/render.service.js +++ b/awx/ui/client/features/output/render.service.js @@ -2,10 +2,7 @@ import Ansi from 'ansi-to-html'; import Entities from 'html-entities'; import { - EVENT_NOTIFY_PLAYBOOK, - EVENT_RUNNER_OK, EVENT_START_PLAY, - EVENT_START_PLAYBOOK, EVENT_STATS_PLAY, EVENT_START_TASK, OUTPUT_ANSI_COLORMAP, @@ -211,15 +208,7 @@ function JobRenderService ($q, $sce, $window) { const lines = stdout.split('\r\n'); const record = this.createRecord(event, lines); - if (event.event === EVENT_START_PLAYBOOK) { - return { html: '', count: 0 }; - } - - if (event.stdout === '' && event.event === EVENT_NOTIFY_PLAYBOOK) { - return { html: '', count: 0 }; - } - - if (event.stdout === '' && event.event === EVENT_RUNNER_OK) { + if (lines.length === 1 && lines[0] === '') { return { html: '', count: 0 }; } From 3a929919a36c6636ef6beb8e14de5cc37b0ba721 Mon Sep 17 00:00:00 2001 From: Jake McDermott Date: Mon, 5 Nov 2018 18:54:09 -0500 Subject: [PATCH 4/8] enable expanded details for dynamic host events --- awx/ui/client/features/output/render.service.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/awx/ui/client/features/output/render.service.js b/awx/ui/client/features/output/render.service.js index a10beb29b2..9ef41e3351 100644 --- a/awx/ui/client/features/output/render.service.js +++ b/awx/ui/client/features/output/render.service.js @@ -259,17 +259,17 @@ function JobRenderService ($q, $sce, $window) { return this.records[event.counter]; } - let isHost = false; - if (typeof event.host === 'number') { - isHost = true; + let isClickable = false; + if (typeof event.host === 'number' || event.event_data && event.event_data.res) { + isClickable = true; } else if (event.type === 'project_update_event' && event.event !== 'runner_on_skipped' && event.event_data.host) { - isHost = true; + isClickable = true; } const record = { - isHost, + isClickable, id: event.id, line: event.start_line + 1, name: event.event, @@ -369,7 +369,7 @@ function JobRenderService ($q, $sce, $window) { tdToggle = `
`; } - if (record.isHost) { + if (record.isClickable) { tdEvent = `
${content}
`; } From 4c74c8c40c80e6ccea7240714ba13e5f64bee0e2 Mon Sep 17 00:00:00 2001 From: Jake McDermott Date: Mon, 5 Nov 2018 19:03:51 -0500 Subject: [PATCH 5/8] delete contents of slide array before reassigning --- awx/ui/client/features/output/slide.service.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/awx/ui/client/features/output/slide.service.js b/awx/ui/client/features/output/slide.service.js index e4f410b1b3..da1d9a4047 100644 --- a/awx/ui/client/features/output/slide.service.js +++ b/awx/ui/client/features/output/slide.service.js @@ -114,6 +114,9 @@ function SlidingWindowService ($q) { } } + this.buffer.events.length = 0; + delete this.buffer.events; + this.buffer.events = frames; this.buffer.min = min; this.buffer.max = max; From 0c2b1b7747ed4d7d69f244e172910b8029d739be Mon Sep 17 00:00:00 2001 From: Jake McDermott Date: Mon, 5 Nov 2018 19:20:07 -0500 Subject: [PATCH 6/8] don't compile html in real time --- .../features/output/index.controller.js | 21 ++++++------ .../client/features/output/render.service.js | 34 +++++++++++-------- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/awx/ui/client/features/output/index.controller.js b/awx/ui/client/features/output/index.controller.js index 40f66dbf1b..51a4ba39ca 100644 --- a/awx/ui/client/features/output/index.controller.js +++ b/awx/ui/client/features/output/index.controller.js @@ -6,7 +6,6 @@ import { OUTPUT_PAGE_SIZE, } from './constants'; -let $compile; let $q; let $scope; let $state; @@ -97,6 +96,7 @@ function firstRange () { .then(() => render.pushFront(results)); }) .finally(() => { + render.compile(); scroll.resume(); lockFollow = false; }); @@ -124,6 +124,7 @@ function nextRange () { .then(() => render.pushFront(results)); }) .finally(() => { + render.compile(); scroll.resume(); lockFrames = false; @@ -162,6 +163,7 @@ function previousRange () { return $q.resolve(); }) .finally(() => { + render.compile(); scroll.resume(); lockFrames = false; @@ -189,6 +191,7 @@ function lastRange () { return $q.resolve(); }) .finally(() => { + render.compile(); scroll.resume(); return $q.resolve(); @@ -280,6 +283,7 @@ function firstPage () { .then(() => render.pushFront(results)); }) .finally(() => { + render.compile(); scroll.resume(); return $q.resolve(); @@ -309,6 +313,7 @@ function lastPage () { return $q.resolve(); }) .finally(() => { + render.compile(); scroll.resume(); return $q.resolve(); @@ -330,6 +335,7 @@ function nextPage () { .then(() => render.pushFront(results)); }) .finally(() => { + render.compile(); scroll.resume(); }); } @@ -363,6 +369,7 @@ function previousPage () { return $q.resolve(); }) .finally(() => { + render.compile(); scroll.resume(); return $q.resolve(); @@ -546,10 +553,6 @@ function toggleTaskCollapse (uuid) { render.records[uuid].isCollapsed = !isCollapsed; } -function compile (html) { - return $compile(html)($scope); -} - function showHostDetails (id, uuid) { $state.go('output.host-event.json', { eventId: id, taskUuid: uuid }); } @@ -599,7 +602,7 @@ function showMissingEvents (uuid) { delete render.records[uuid]; } }) - .then(() => render.compile(elements)) + .then(() => render.compile()) .then(() => lines); }); } @@ -709,7 +712,6 @@ function clear () { } function OutputIndexController ( - _$compile_, _$q_, _$scope_, _$state_, @@ -727,7 +729,6 @@ function OutputIndexController ( const { isPanelExpanded, _debug } = $stateParams; const isProcessingFinished = !_debug && _resource_.model.get('event_processing_finished'); - $compile = _$compile_; $q = _$q_; $scope = _$scope_; $state = _$state_; @@ -765,7 +766,7 @@ function OutputIndexController ( vm.debug = _debug; render.requestAnimationFrame(() => { - render.init({ compile, toggles: vm.toggleLineEnabled }); + render.init($scope, { toggles: vm.toggleLineEnabled }); status.init(resource); page.init(resource.events); @@ -815,6 +816,7 @@ function OutputIndexController ( status.sync(); scroll.unlock(); scroll.unhide(); + render.compile(); } }); @@ -850,7 +852,6 @@ function OutputIndexController ( } OutputIndexController.$inject = [ - '$compile', '$q', '$scope', '$state', diff --git a/awx/ui/client/features/output/render.service.js b/awx/ui/client/features/output/render.service.js index 9ef41e3351..3f23f449ed 100644 --- a/awx/ui/client/features/output/render.service.js +++ b/awx/ui/client/features/output/render.service.js @@ -33,9 +33,13 @@ const pattern = [ const re = new RegExp(pattern); const hasAnsi = input => re.test(input); -function JobRenderService ($q, $sce, $window) { - this.init = ({ compile, toggles }) => { - this.hooks = { compile }; +let $scope; + +function JobRenderService ($q, $compile, $sce, $window) { + this.init = (_$scope_, { toggles }) => { + $scope = _$scope_; + this.setScope(); + this.el = $(OUTPUT_ELEMENT_TBODY); this.parent = null; @@ -434,8 +438,16 @@ function JobRenderService ($q, $sce, $window) { }); }); - this.compile = content => { - this.hooks.compile(content); + this.setScope = () => { + if (this.scope) this.scope.$destroy(); + delete this.scope; + + this.scope = $scope.$new(); + }; + + this.compile = () => { + this.setScope(); + $compile(this.el)(this.scope); return this.requestAnimationFrame(); }; @@ -471,10 +483,7 @@ function JobRenderService ($q, $sce, $window) { const result = this.prependEventGroup(events); const html = this.trustHtml(result.html); - const newElements = angular.element(html); - - return this.requestAnimationFrame(() => this.el.prepend(newElements)) - .then(() => this.compile(newElements)) + return this.requestAnimationFrame(() => this.el.prepend(html)) .then(() => result.lines); }; @@ -486,10 +495,7 @@ function JobRenderService ($q, $sce, $window) { const result = this.appendEventGroup(events); const html = this.trustHtml(result.html); - const newElements = angular.element(html); - - return this.requestAnimationFrame(() => this.el.append(newElements)) - .then(() => this.compile(newElements)) + return this.requestAnimationFrame(() => this.el.append(html)) .then(() => result.lines); }; @@ -600,6 +606,6 @@ function JobRenderService ($q, $sce, $window) { this.getCapacity = () => OUTPUT_EVENT_LIMIT - (this.getTailCounter() - this.getHeadCounter()); } -JobRenderService.$inject = ['$q', '$sce', '$window']; +JobRenderService.$inject = ['$q', '$compile', '$sce', '$window']; export default JobRenderService; From 76e887f46d820651057cab3a59ff0c3399ba9bbb Mon Sep 17 00:00:00 2001 From: Jake McDermott Date: Mon, 5 Nov 2018 20:04:16 -0500 Subject: [PATCH 7/8] highlight entire row on hover --- awx/ui/client/features/output/_index.less | 14 ++++++++------ awx/ui/client/features/output/render.service.js | 14 ++++++++------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/awx/ui/client/features/output/_index.less b/awx/ui/client/features/output/_index.less index d1132d9ec2..b6110eb773 100644 --- a/awx/ui/client/features/output/_index.less +++ b/awx/ui/client/features/output/_index.less @@ -72,11 +72,19 @@ &-row { display: flex; + &:hover { + background-color: white; + } + &:hover div { background-color: white; } } + &-row--clickable { + cursor: pointer; + } + &-toggle { background-color: @at-gray-eb; color: @at-gray-848992; @@ -112,12 +120,6 @@ .at-mixin-event(); } - &-event--host { - .at-mixin-event(); - - cursor: pointer; - } - &-time { padding-right: 2ch; font-size: 12px; diff --git a/awx/ui/client/features/output/render.service.js b/awx/ui/client/features/output/render.service.js index 3f23f449ed..8598d6ba3e 100644 --- a/awx/ui/client/features/output/render.service.js +++ b/awx/ui/client/features/output/render.service.js @@ -347,6 +347,7 @@ function JobRenderService ($q, $compile, $sce, $window) { let tdToggle = ''; let tdEvent = ''; let classList = ''; + let directives = ''; if (record.isMissing) { return `
@@ -373,10 +374,6 @@ function JobRenderService ($q, $compile, $sce, $window) { tdToggle = `
`; } - if (record.isClickable) { - tdEvent = `
${content}
`; - } - if (record.time && record.line === ln) { timestamp = `${record.time}`; } @@ -404,11 +401,16 @@ function JobRenderService ($q, $compile, $sce, $window) { } } + if (record && record.isClickable) { + classList += ' at-Stdout-row--clickable'; + directives = `ng-click="vm.showHostDetails('${record.id}', '${record.uuid}')"`; + } + return ` -
+
${tdToggle}
${ln}
- ${tdEvent} +
${content}
${timestamp}
`; }; From 95190c55090dc011ecde0cc6d57f84c245d482bf Mon Sep 17 00:00:00 2001 From: Jake McDermott Date: Mon, 5 Nov 2018 20:06:08 -0500 Subject: [PATCH 8/8] remove unused constants --- awx/ui/client/features/output/constants.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/awx/ui/client/features/output/constants.js b/awx/ui/client/features/output/constants.js index 5db41c31d4..e8880587b1 100644 --- a/awx/ui/client/features/output/constants.js +++ b/awx/ui/client/features/output/constants.js @@ -1,8 +1,6 @@ export const API_MAX_PAGE_SIZE = 200; export const API_ROOT = '/api/v2/'; -export const EVENT_NOTIFY_PLAYBOOK = 'playbook_on_notify'; -export const EVENT_RUNNER_OK = 'runner_on_ok'; export const EVENT_START_TASK = 'playbook_on_task_start'; export const EVENT_START_PLAY = 'playbook_on_play_start'; export const EVENT_START_PLAYBOOK = 'playbook_on_start';