diff --git a/awx/ui/client/features/output/details.directive.js b/awx/ui/client/features/output/details.component.js similarity index 90% rename from awx/ui/client/features/output/details.directive.js rename to awx/ui/client/features/output/details.component.js index f13de2821b..d74cea977a 100644 --- a/awx/ui/client/features/output/details.directive.js +++ b/awx/ui/client/features/output/details.component.js @@ -2,7 +2,6 @@ const templateUrl = require('~features/output/details.partial.html'); let $http; let $filter; -let $scope; let $state; let error; @@ -10,7 +9,6 @@ let parse; let prompt; let resource; let strings; -let status; let wait; let vm; @@ -372,7 +370,7 @@ function getJobTagDetails () { let jobTags; if (tagString) { - jobTags = tagString.split(','); + jobTags = tagString.split(',').filter(tag => tag !== ''); } else { jobTags = []; } @@ -384,7 +382,7 @@ function getJobTagDetails () { const label = 'Job Tags'; const more = false; - const value = jobTags.filter(tag => tag !== '').map($filter('sanitize')); + const value = jobTags.map($filter('sanitize')); return { label, more, value }; } @@ -395,7 +393,7 @@ function getSkipTagDetails () { let skipTags; if (tagString) { - skipTags = tagString.split(','); + skipTags = tagString.split(',').filter(tag => tag !== ''); } else { skipTags = []; } @@ -406,7 +404,7 @@ function getSkipTagDetails () { const label = 'Skip Tags'; const more = false; - const value = skipTags.filter(tag => tag !== '').map($filter('sanitize')); + const value = skipTags.map($filter('sanitize')); return { label, more, value }; } @@ -446,7 +444,7 @@ function createErrorHandler (path, action) { const hdr = strings.get('error.HEADER'); const msg = strings.get('error.CALL', { path, action, status: res.status }); - error($scope, res.data, res.status, null, { hdr, msg }); + error(null, res.data, res.status, null, { hdr, msg }); }; } @@ -546,33 +544,33 @@ function deleteJob () { prompt({ hdr, resourceName, body, actionText, action }); } -function AtJobDetailsController ( +function JobDetailsController ( _$http_, _$filter_, _$state_, _error_, _prompt_, _strings_, - _status_, _wait_, _parse_, + { subscribe }, ) { vm = this || {}; $http = _$http_; $filter = _$filter_; $state = _$state_; - error = _error_; + parse = _parse_; prompt = _prompt_; strings = _strings_; - status = _status_; wait = _wait_; - vm.init = _$scope_ => { - $scope = _$scope_; - resource = $scope.resource; // eslint-disable-line prefer-destructuring + let unsubscribe; + + vm.$onInit = () => { + resource = this.resource; // eslint-disable-line prefer-destructuring vm.status = getStatusDetails(); vm.started = getStartDetails(); @@ -606,54 +604,42 @@ function AtJobDetailsController ( vm.cancelJob = cancelJob; vm.deleteJob = deleteJob; - vm.toggleLabels = toggleLabels; vm.toggleJobTags = toggleJobTags; vm.toggleSkipTags = toggleSkipTags; + vm.toggleLabels = toggleLabels; - const observe = (getter, transform, key) => { - $scope.$watch(getter, value => { vm[key] = transform(value); }); - }; - - observe(status.getStarted, getStartDetails, 'started'); - observe(status.getFinished, getFinishDetails, 'finished'); - observe(status.getProjectUpdateId, getProjectUpdateDetails, 'projectUpdate'); - observe(status.getProjectStatus, getProjectStatusDetails, 'projectStatus'); - - $scope.$watch(status.getJobStatus, jobStatus => { - vm.status = getStatusDetails(jobStatus); - vm.job.status = jobStatus; + unsubscribe = subscribe(({ status, started, finished, scm }) => { + vm.started = getStartDetails(started); + vm.finished = getFinishDetails(finished); + vm.projectUpdate = getProjectUpdateDetails(scm.id); + vm.projectStatus = getProjectStatusDetails(scm.status); + vm.status = getStatusDetails(status); + vm.job.status = status; }); }; + + vm.$onDestroy = () => { + unsubscribe(); + }; } -AtJobDetailsController.$inject = [ +JobDetailsController.$inject = [ '$http', '$filter', '$state', 'ProcessErrors', 'Prompt', 'JobStrings', - 'JobStatusService', 'Wait', 'ParseVariableString', + 'JobStatusService', ]; -function atJobDetailsLink (scope, el, attrs, controllers) { - const [atDetailsController] = controllers; - - atDetailsController.init(scope); -} - -function atJobDetails () { - return { - templateUrl, - restrict: 'E', - require: ['atJobDetails'], - controllerAs: 'vm', - link: atJobDetailsLink, - controller: AtJobDetailsController, - scope: { resource: '=', }, - }; -} - -export default atJobDetails; +export default { + templateUrl, + controller: JobDetailsController, + controllerAs: 'vm', + bindings: { + resource: '<' + }, +}; diff --git a/awx/ui/client/features/output/index.controller.js b/awx/ui/client/features/output/index.controller.js index 488d994dc2..e84c93d708 100644 --- a/awx/ui/client/features/output/index.controller.js +++ b/awx/ui/client/features/output/index.controller.js @@ -38,9 +38,8 @@ function JobsIndexController ( vm.clear = devClear; // Expand/collapse - // vm.toggle = toggle; - // vm.expand = expand; - vm.isExpanded = true; + vm.expanded = false; + vm.toggleExpanded = toggleExpanded; // Panel vm.resource = resource; @@ -55,10 +54,6 @@ function JobsIndexController ( up: scrollPageUp }; - vm.fullscreen = { - isFullscreen: false - }; - render.requestAnimationFrame(() => init()); } @@ -96,13 +91,14 @@ function init () { }, onStop () { status.updateStats(); + status.dispatch(); } }); $scope.$on(resource.ws.events, handleJobEvent); $scope.$on(resource.ws.status, handleStatusEvent); - if (!status.isRunning()) { + if (!status.state.running) { next(); } } @@ -281,9 +277,9 @@ function scrollIsAtRest (isAtRest) { vm.scroll.showBackToTop = !isAtRest; } -// function expand () { -// vm.toggle(parent, true); -// } +function toggleExpanded () { + vm.expanded = !vm.expanded; +} // function showHostDetails (id) { // jobEvent.request('get', id) diff --git a/awx/ui/client/features/output/index.js b/awx/ui/client/features/output/index.js index 0bb295a714..6b14296553 100644 --- a/awx/ui/client/features/output/index.js +++ b/awx/ui/client/features/output/index.js @@ -8,11 +8,12 @@ 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 MessageService from '~features/output/message.service'; import LegacyRedirect from '~features/output/legacy.route'; -import DetailsDirective from '~features/output/details.directive'; -import SearchDirective from '~features/output/search.directive'; -import StatsDirective from '~features/output/stats.directive'; +import DetailsComponent from '~features/output/details.component'; +import SearchComponent from '~features/output/search.component'; +import StatsComponent from '~features/output/stats.component'; import HostEvent from './host-event/index'; const Template = require('~features/output/index.view.html'); @@ -175,7 +176,7 @@ function JobsRun ($stateRegistry, strings) { templateUrl: Template, controller: Controller, controllerAs: 'vm' - } + }, }, resolve: { webSocketConnection: [ @@ -221,9 +222,10 @@ angular .service('JobRenderService', RenderService) .service('JobEventEngine', EngineService) .service('JobStatusService', StatusService) - .directive('atJobDetails', DetailsDirective) - .directive('atJobSearch', SearchDirective) - .directive('atJobStats', StatsDirective) + .service('JobMessageService', MessageService) + .component('atJobSearch', SearchComponent) + .component('atJobStats', StatsComponent) + .component('atJobDetails', DetailsComponent) .run(JobsRun) .run(LegacyRedirect); diff --git a/awx/ui/client/features/output/index.view.html b/awx/ui/client/features/output/index.view.html index f25171f9f2..cb932fafd3 100644 --- a/awx/ui/client/features/output/index.view.html +++ b/awx/ui/client/features/output/index.view.html @@ -1,23 +1,25 @@