diff --git a/awx/ui/client/features/output/details.directive.js b/awx/ui/client/features/output/details.directive.js index b34a80982f..3c0e677d9b 100644 --- a/awx/ui/client/features/output/details.directive.js +++ b/awx/ui/client/features/output/details.directive.js @@ -10,6 +10,7 @@ let parse; let prompt; let resource; let strings; +let status; let wait; let vm; @@ -19,8 +20,8 @@ function mapChoices (choices) { return Object.assign(...choices.map(([k, v]) => ({ [k]: v }))); } -function getStatusDetails (status) { - const unmapped = status || resource.model.get('status'); +function getStatusDetails (jobStatus) { + const unmapped = jobStatus || resource.model.get('status'); if (!unmapped) { return null; @@ -373,11 +374,11 @@ function getLabelDetails () { } function createErrorHandler (path, action) { - return ({ data, status }) => { + return res => { const hdr = strings.get('error.HEADER'); - const msg = strings.get('error.CALL', { path, action, status }); + const msg = strings.get('error.CALL', { path, action, status: res.status }); - error($scope, data, status, null, { hdr, msg }); + error($scope, res.data, res.status, null, { hdr, msg }); }; } @@ -454,24 +455,14 @@ function deleteJob () { prompt({ hdr, resourceName, body, actionText, action }); } -function handleSocketEvent (data) { - const project = resource.model.get('project'); - - if (resource.model.get('id') === data.unified_job_id) { - vm.status = getStatusDetails(data.status); - } else if (project && (project === data.project_id)) { - vm.project.update = vm.project.update || {}; - vm.project.update.status = data.status; - } -} - -function AtDetailsController ( +function AtJobDetailsController ( _$http_, _$filter_, _$state_, _error_, _prompt_, _strings_, + _status_, _wait_, ParseTypeChange, ParseVariableString, @@ -486,6 +477,7 @@ function AtDetailsController ( parse = ParseVariableString; prompt = _prompt_; strings = _strings_; + status = _status_; wait = _wait_; vm.init = _$scope_ => { @@ -538,47 +530,48 @@ function AtDetailsController ( vm.deleteJob = deleteJob; vm.toggleLabels = toggleLabels; - $scope.$watch('started', value => { vm.started = getStartDetails(value); }); - $scope.$watch('status', value => { vm.status = getStatusDetails(value); }); - $scope.$watch('finished', value => { vm.finished = getFinishDetails(value); }); + $scope.$watch(status.getStarted, value => { vm.started = getStartDetails(value); }); + $scope.$watch(status.getJobStatus, value => { vm.status = getStatusDetails(value); }); + $scope.$watch(status.getFinished, value => { vm.finished = getFinishDetails(value); }); - $scope.$on(resource.ws.status, (e, data) => handleSocketEvent(data)); + $scope.$watch(status.getProjectStatus, value => { + if (!value) return; + + vm.project.update = vm.project.update || {}; + vm.project.update.status = value; + }); }; } -AtDetailsController.$inject = [ +AtJobDetailsController.$inject = [ '$http', '$filter', '$state', 'ProcessErrors', 'Prompt', 'JobStrings', + 'JobStatusService', 'Wait', 'ParseTypeChange', 'ParseVariableString', ]; -function atDetailsLink (scope, el, attrs, controllers) { +function atJobDetailsLink (scope, el, attrs, controllers) { const [atDetailsController] = controllers; atDetailsController.init(scope); } -function atDetails () { +function atJobDetails () { return { templateUrl, restrict: 'E', - require: ['atDetails'], + require: ['atJobDetails'], controllerAs: 'vm', - link: atDetailsLink, - controller: AtDetailsController, - scope: { - finished: '=', - started: '=', - resource: '=', - status: '=', - }, + link: atJobDetailsLink, + controller: AtJobDetailsController, + scope: { resource: '=', }, }; } -export default atDetails; +export default atJobDetails; diff --git a/awx/ui/client/features/output/engine.service.js b/awx/ui/client/features/output/engine.service.js index c8b0fd662a..1f74a90c59 100644 --- a/awx/ui/client/features/output/engine.service.js +++ b/awx/ui/client/features/output/engine.service.js @@ -105,7 +105,7 @@ function JobEventEngine ($q) { } }; - this.pushEvent = data => { + this.pushJobEvent = data => { this.lag++; this.chain = this.chain diff --git a/awx/ui/client/features/output/index.controller.js b/awx/ui/client/features/output/index.controller.js index 51cfdeaea7..0c3a149679 100644 --- a/awx/ui/client/features/output/index.controller.js +++ b/awx/ui/client/features/output/index.controller.js @@ -1,25 +1,17 @@ -const JOB_START = 'playbook_on_start'; -const JOB_END = 'playbook_on_stats'; -const PLAY_START = 'playbook_on_play_start'; -const TASK_START = 'playbook_on_task_start'; - let $compile; let $q; let $scope; let $state; -let moment; let page; let qs; let render; let resource; let scroll; let engine; +let status; let vm; -let eventCounter; -let statsEvent; - function JobsIndexController ( _resource_, _page_, @@ -31,7 +23,7 @@ function JobsIndexController ( _$q_, _$state_, _qs_, - _moment_, + _status_, ) { vm = this || {}; @@ -44,8 +36,7 @@ function JobsIndexController ( scroll = _scroll_; render = _render_; engine = _engine_; - - moment = _moment_; + status = _status_; // Development helper(s) vm.clear = devClear; @@ -55,31 +46,10 @@ function JobsIndexController ( vm.expand = expand; vm.isExpanded = true; - // Events - eventCounter = null; - statsEvent = resource.stats; - // Panel + vm.resource = resource; vm.title = resource.model.get('name'); - // Stats - vm.stats = { - event: statsEvent, - elapsed: resource.model.get('elapsed'), - download: resource.model.get('related.stdout'), - running: Boolean(resource.model.get('started')) && !resource.model.get('finished'), - plays: null, - tasks: null, - }; - - // Details - vm.details = { - resource, - status: resource.model.get('status'), - started: resource.model.get('started'), - finished: resource.model.get('finished'), - }; - // Search $state = _$state_; qs = _qs_; @@ -107,10 +77,14 @@ function JobsIndexController ( up: scrollPageUp }; - render.requestAnimationFrame(() => init(!vm.stats.running)); + render.requestAnimationFrame(() => init()); } -function init (pageMode) { +function init () { + status.init({ + resource, + }); + page.init({ resource, }); @@ -118,7 +92,7 @@ function init (pageMode) { render.init({ get: () => resource.model.get(`related.${resource.related}.results`), compile: html => $compile(html)($scope), - isStreamActive: engine.isActive + isStreamActive: engine.isActive, }); scroll.init({ @@ -135,60 +109,34 @@ function init (pageMode) { return shift().then(() => append(events, true)); }, onStart () { - vm.stats.plays = 0; - vm.stats.tasks = 0; - vm.stats.running = true; + status.resetCounts(); + status.setJobStatus('running'); vm.search.disabled = true; - vm.details.status = 'running'; }, onStop () { - vm.stats.event = statsEvent; - vm.stats.running = false; + status.updateStats(); vm.search.disabled = false; - - vm.details.status = statsEvent.failed ? 'failed' : 'successful'; - vm.details.finished = statsEvent.created; } }); $scope.$on(resource.ws.events, handleSocketEvent); + $scope.$on(resource.ws.status, handleStatusEvent); - if (pageMode) { + if (!status.isRunning()) { next(); } } +function handleStatusEvent (scope, data) { + status.pushStatusEvent(data); +} + function handleSocketEvent (scope, data) { - const isLatest = ((!eventCounter) || (data.counter > eventCounter)); + engine.pushJobEvent(data); - if (isLatest) { - eventCounter = data.counter; - - vm.details.status = _.get(data, 'summary_fields.job.status'); - - vm.stats.elapsed = moment(data.created) - .diff(resource.model.get('created'), 'seconds'); - } - - if (data.event === JOB_START) { - vm.details.started = data.created; - } - - if (data.event === PLAY_START) { - vm.stats.plays++; - } - - if (data.event === TASK_START) { - vm.stats.tasks++; - } - - if (data.event === JOB_END) { - statsEvent = data; - } - - engine.pushEvent(data); + status.pushJobEvent(data); } function devClear (pageMode) { @@ -466,7 +414,7 @@ JobsIndexController.$inject = [ '$q', '$state', 'QuerySet', - 'moment', + 'JobStatusService', ]; module.exports = JobsIndexController; diff --git a/awx/ui/client/features/output/index.js b/awx/ui/client/features/output/index.js index 33c67d6f11..d9cc3a140d 100644 --- a/awx/ui/client/features/output/index.js +++ b/awx/ui/client/features/output/index.js @@ -7,6 +7,7 @@ import PageService from '~features/output/page.service'; import RenderService from '~features/output/render.service'; import ScrollService from '~features/output/scroll.service'; import EngineService from '~features/output/engine.service'; +import StatusService from '~features/output/status.service'; import DetailsDirective from '~features/output/details.directive'; import SearchKeyDirective from '~features/output/search-key.directive'; @@ -217,9 +218,10 @@ angular .service('JobScrollService', ScrollService) .service('JobRenderService', RenderService) .service('JobEventEngine', EngineService) - .directive('atDetails', DetailsDirective) + .service('JobStatusService', StatusService) + .directive('atJobDetails', DetailsDirective) .directive('atSearchKey', SearchKeyDirective) - .directive('atStats', StatsDirective) + .directive('atJobStats', StatsDirective) .run(JobsRun); export default MODULE_NAME; diff --git a/awx/ui/client/features/output/index.view.html b/awx/ui/client/features/output/index.view.html index 1cac800a7d..089fcd1ce5 100644 --- a/awx/ui/client/features/output/index.view.html +++ b/awx/ui/client/features/output/index.view.html @@ -1,28 +1,14 @@