mirror of
https://github.com/ansible/awx.git
synced 2026-01-19 13:41:28 -03:30
use status service in details and stats components
This commit is contained in:
parent
bdd36341ae
commit
1f9b325f38
@ -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;
|
||||
|
||||
@ -105,7 +105,7 @@ function JobEventEngine ($q) {
|
||||
}
|
||||
};
|
||||
|
||||
this.pushEvent = data => {
|
||||
this.pushJobEvent = data => {
|
||||
this.lag++;
|
||||
|
||||
this.chain = this.chain
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -1,28 +1,14 @@
|
||||
<div class="container-fluid">
|
||||
<div class="col-md-4">
|
||||
<at-panel>
|
||||
<at-details
|
||||
resource="vm.details.resource"
|
||||
started="vm.details.started"
|
||||
finished="vm.details.finished"
|
||||
status="vm.details.status">
|
||||
</at-details>
|
||||
<!-- <p><button class="btn" ng-click="vm.clear(true)">Page Mode</button></p> -->
|
||||
<at-job-details resource="vm.resource"></at-job-details>
|
||||
</at-panel>
|
||||
</div>
|
||||
|
||||
<div class="col-md-8">
|
||||
<at-panel class="at-Stdout">
|
||||
<div class="at-Panel-headingTitle">{{ vm.title }}</div>
|
||||
<at-stats
|
||||
download="vm.stats.download"
|
||||
elapsed="vm.stats.elapsed"
|
||||
running="vm.stats.running"
|
||||
event="vm.stats.event"
|
||||
title="vm.stats.title"
|
||||
plays="vm.stats.plays"
|
||||
tasks="vm.stats.tasks">
|
||||
</at-stats>
|
||||
<at-job-stats resource="vm.resource"></at-job-stats>
|
||||
<!-- search ===================================================================================== -->
|
||||
<form ng-submit="vm.search.submitSearch()">
|
||||
<div class="input-group">
|
||||
|
||||
@ -1,30 +1,7 @@
|
||||
const templateUrl = require('~features/output/stats.partial.html');
|
||||
|
||||
const HOST_STATUS_KEYS = ['dark', 'failures', 'changed', 'ok', 'skipped'];
|
||||
|
||||
function getHostStatusCounts (statsEvent) {
|
||||
const countedHostNames = [];
|
||||
|
||||
const counts = Object.assign(...HOST_STATUS_KEYS.map(key => ({ [key]: 0 })));
|
||||
|
||||
HOST_STATUS_KEYS.forEach(key => {
|
||||
const hostData = _.get(statsEvent, ['event_data', key], {});
|
||||
|
||||
Object.keys(hostData).forEach(hostName => {
|
||||
const isAlreadyCounted = (countedHostNames.indexOf(hostName) > -1);
|
||||
const shouldBeCounted = ((!isAlreadyCounted) && hostData[hostName] > 0);
|
||||
|
||||
if (shouldBeCounted) {
|
||||
countedHostNames.push(hostName);
|
||||
counts[key]++;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
counts.hosts = countedHostNames.length;
|
||||
|
||||
return counts;
|
||||
}
|
||||
let status;
|
||||
let strings;
|
||||
|
||||
function createStatsBarTooltip (key, count) {
|
||||
const label = `<span class='HostStatusBar-tooltipLabel'>${key}</span>`;
|
||||
@ -33,13 +10,16 @@ function createStatsBarTooltip (key, count) {
|
||||
return `${label}${badge}`;
|
||||
}
|
||||
|
||||
function atStatsLink (scope, el, attrs, controllers) {
|
||||
const [atStatsController] = controllers;
|
||||
function atJobStatsLink (scope, el, attrs, controllers) {
|
||||
const [atJobStatsController] = controllers;
|
||||
|
||||
atStatsController.init(scope);
|
||||
atJobStatsController.init(scope);
|
||||
}
|
||||
|
||||
function AtStatsController (strings) {
|
||||
function AtJobStatsController (_strings_, _status_) {
|
||||
status = _status_;
|
||||
strings = _strings_;
|
||||
|
||||
const vm = this || {};
|
||||
|
||||
vm.tooltips = {
|
||||
@ -48,28 +28,23 @@ function AtStatsController (strings) {
|
||||
};
|
||||
|
||||
vm.init = scope => {
|
||||
const { download, elapsed, running, event, plays, tasks } = scope;
|
||||
const { resource } = scope;
|
||||
|
||||
vm.download = download;
|
||||
vm.plays = plays;
|
||||
vm.tasks = tasks;
|
||||
vm.elapsed = elapsed;
|
||||
vm.running = running || false;
|
||||
vm.download = resource.model.get('related.stdout');
|
||||
|
||||
vm.setStats(event);
|
||||
vm.setHostStatusCounts(status.getHostStatusCounts());
|
||||
|
||||
scope.$watch('elapsed', value => { vm.elapsed = value; });
|
||||
scope.$watch('running', value => { vm.running = value; });
|
||||
scope.$watch('plays', value => { vm.plays = value; });
|
||||
scope.$watch('tasks', value => { vm.tasks = value; });
|
||||
scope.$watch(status.getPlayCount, value => { vm.plays = value; });
|
||||
scope.$watch(status.getTaskCount, value => { vm.tasks = value; });
|
||||
scope.$watch(status.getElapsed, value => { vm.elapsed = value; });
|
||||
scope.$watch(status.getHostCount, value => { vm.hosts = value; });
|
||||
scope.$watch(status.isRunning, value => { vm.running = value; });
|
||||
|
||||
scope.$watch('event', vm.setStats);
|
||||
scope.$watchCollection(status.getHostStatusCounts, vm.setHostStatusCounts);
|
||||
};
|
||||
|
||||
vm.setStats = statsEvent => {
|
||||
const counts = getHostStatusCounts(statsEvent);
|
||||
|
||||
HOST_STATUS_KEYS.forEach(key => {
|
||||
vm.setHostStatusCounts = counts => {
|
||||
Object.keys(counts).forEach(key => {
|
||||
const count = counts[key];
|
||||
const statusBarElement = $(`.HostStatusBar-${key}`);
|
||||
|
||||
@ -78,31 +53,24 @@ function AtStatsController (strings) {
|
||||
vm.tooltips[key] = createStatsBarTooltip(key, count);
|
||||
});
|
||||
|
||||
vm.hosts = counts.hosts;
|
||||
vm.statsAreAvailable = Boolean(statsEvent);
|
||||
vm.statsAreAvailable = Boolean(status.getStatsEvent());
|
||||
};
|
||||
}
|
||||
|
||||
function atStats () {
|
||||
function atJobStats () {
|
||||
return {
|
||||
templateUrl,
|
||||
restrict: 'E',
|
||||
require: ['atStats'],
|
||||
require: ['atJobStats'],
|
||||
controllerAs: 'vm',
|
||||
link: atStatsLink,
|
||||
link: atJobStatsLink,
|
||||
controller: [
|
||||
'JobStrings',
|
||||
AtStatsController
|
||||
'JobStatusService',
|
||||
AtJobStatsController
|
||||
],
|
||||
scope: {
|
||||
download: '=',
|
||||
elapsed: '=',
|
||||
running: '=',
|
||||
event: '=',
|
||||
plays: '=',
|
||||
tasks: '=',
|
||||
},
|
||||
scope: { resource: '=', },
|
||||
};
|
||||
}
|
||||
|
||||
export default atStats;
|
||||
export default atJobStats;
|
||||
|
||||
@ -40,26 +40,31 @@
|
||||
|
||||
<div class="HostStatusBar">
|
||||
<div class="HostStatusBar-ok"
|
||||
ng-show="!vm.running"
|
||||
data-placement="top"
|
||||
aw-tool-tip="{{ vm.tooltips.ok }}"
|
||||
data-tip-watch="vm.tooltips.ok">
|
||||
</div>
|
||||
<div class="HostStatusBar-skipped"
|
||||
ng-show="!vm.running"
|
||||
data-placement="top"
|
||||
aw-tool-tip="{{ vm.tooltips.skipped }}"
|
||||
data-tip-watch="vm.tooltips.skipped">
|
||||
</div>
|
||||
<div class="HostStatusBar-changed"
|
||||
ng-show="!vm.running"
|
||||
data-placement="top"
|
||||
aw-tool-tip="{{ vm.tooltips.changed }}"
|
||||
data-tip-watch="vm.tooltips.changed">
|
||||
</div>
|
||||
<div class="HostStatusBar-failures"
|
||||
ng-show="!vm.running"
|
||||
data-placement="top"
|
||||
aw-tool-tip="{{ vm.tooltips.failures }}"
|
||||
data-tip-watch="vm.tooltips.failures">
|
||||
</div>
|
||||
<div class="HostStatusBar-dark"
|
||||
ng-show="!vm.running"
|
||||
data-placement="top"
|
||||
aw-tool-tip="{{ vm.tooltips.dark }}"
|
||||
data-tip-watch="vm.tooltips.dark">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user