mirror of
https://github.com/ansible/awx.git
synced 2026-01-14 03:10:42 -03:30
event processing for details panel and initial stats bar integration
This commit is contained in:
parent
f65d170cab
commit
b577f50930
@ -199,3 +199,85 @@
|
||||
width: 100%;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
|
||||
// Status Bar -----------------------------------------------------------------------------
|
||||
.HostStatusBar {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
width: 100%;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.HostStatusBar-ok,
|
||||
.HostStatusBar-changed,
|
||||
.HostStatusBar-unreachable,
|
||||
.HostStatusBar-failed,
|
||||
.HostStatusBar-skipped,
|
||||
.HostStatusBar-noData {
|
||||
height: 15px;
|
||||
border-top: 5px solid @default-bg;
|
||||
border-bottom: 5px solid @default-bg;
|
||||
}
|
||||
|
||||
.HostStatusBar-ok {
|
||||
background-color: @default-succ;
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.HostStatusBar-changed {
|
||||
background-color: @default-warning;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.HostStatusBar-unreachable {
|
||||
background-color: @default-unreachable;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.HostStatusBar-failed {
|
||||
background-color: @default-err;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.HostStatusBar-skipped {
|
||||
background-color: @default-link;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.HostStatusBar-noData {
|
||||
background-color: @default-icon-hov;
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
|
||||
.HostStatusBar-tooltipLabel {
|
||||
text-transform: uppercase;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.HostStatusBar-tooltipBadge {
|
||||
border-radius: 5px;
|
||||
border: 1px solid @default-bg;
|
||||
}
|
||||
|
||||
.HostStatusBar-tooltipBadge--ok {
|
||||
background-color: @default-succ;
|
||||
}
|
||||
|
||||
.HostStatusBar-tooltipBadge--unreachable {
|
||||
background-color: @default-unreachable;
|
||||
}
|
||||
|
||||
.HostStatusBar-tooltipBadge--skipped {
|
||||
background-color: @default-link;
|
||||
}
|
||||
|
||||
.HostStatusBar-tooltipBadge--changed {
|
||||
background-color: @default-warning;
|
||||
}
|
||||
|
||||
.HostStatusBar-tooltipBadge--failed {
|
||||
background-color: @default-err;
|
||||
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ const templateUrl = require('~features/output/details.partial.html');
|
||||
|
||||
let $http;
|
||||
let $filter;
|
||||
let $scope;
|
||||
let $state;
|
||||
|
||||
let error;
|
||||
@ -12,68 +13,86 @@ let strings;
|
||||
let wait;
|
||||
|
||||
function mapChoices (choices) {
|
||||
return Object.assign(...choices.map(([k, v]) => ({[k]: v})));
|
||||
if (!choices) return {};
|
||||
return Object.assign(...choices.map(([k, v]) => ({ [k]: v })));
|
||||
}
|
||||
|
||||
function getStatusDetails (status) {
|
||||
const value = status || resource.model.get('status');
|
||||
const label = 'Status';
|
||||
const unmapped = status || resource.model.get('status');
|
||||
|
||||
if (!unmapped) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const choices = mapChoices(resource.model.options('actions.GET.status.choices'));
|
||||
|
||||
const displayValue = choices[value];
|
||||
const label = 'Status';
|
||||
const icon = `fa icon-job-${unmapped}`;
|
||||
const value = choices[unmapped];
|
||||
|
||||
return { displayValue, label, value };
|
||||
return { label, icon, value };
|
||||
}
|
||||
|
||||
function getStartTimeDetails (started) {
|
||||
const value = started || resource.model.get('started');
|
||||
const unfiltered = started || resource.model.get('started');
|
||||
|
||||
const label = 'Started';
|
||||
|
||||
let displayValue;
|
||||
let value;
|
||||
|
||||
if (value) {
|
||||
displayValue = $filter('longDate')(value);
|
||||
if (unfiltered) {
|
||||
value = $filter('longDate')(unfiltered);
|
||||
} else {
|
||||
displayValue = 'Not Started';
|
||||
value = 'Not Started';
|
||||
}
|
||||
|
||||
return { displayValue, label, value };
|
||||
return { label, value };
|
||||
}
|
||||
|
||||
function getFinishTimeDetails (finished) {
|
||||
const value = finished || resource.model.get('finished');
|
||||
const unfiltered = finished || resource.model.get('finished');
|
||||
|
||||
const label = 'Finished';
|
||||
|
||||
let displayValue;
|
||||
let value;
|
||||
|
||||
if (value) {
|
||||
displayValue = $filter('longDate')(value);
|
||||
if (unfiltered) {
|
||||
value = $filter('longDate')(unfiltered);
|
||||
} else {
|
||||
displayValue = 'Not Finished';
|
||||
value = 'Not Finished';
|
||||
}
|
||||
|
||||
return { displayValue, label, value };
|
||||
return { label, value };
|
||||
}
|
||||
|
||||
function getJobTypeDetails () {
|
||||
const value = resource.model.get('job_type');
|
||||
const label = 'Job Type';
|
||||
const unmapped = resource.model.get('job_type');
|
||||
|
||||
if (!unmapped) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const choices = mapChoices(resource.model.options('actions.GET.job_type.choices'));
|
||||
|
||||
const displayValue = choices[value];
|
||||
const label = 'Job Type';
|
||||
const value = choices[unmapped];
|
||||
|
||||
return { displayValue, label, value };
|
||||
return { label, value };
|
||||
}
|
||||
|
||||
|
||||
function getVerbosityDetails () {
|
||||
const value = resource.model.get('verbosity');
|
||||
const verbosity = resource.model.get('verbosity');
|
||||
|
||||
if (!verbosity) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const choices = mapChoices(resource.model.options('actions.GET.verbosity.choices'));
|
||||
|
||||
const displayValue = choices[value];
|
||||
const label = 'Verbosity';
|
||||
const value = choices[value];
|
||||
|
||||
return { displayValue, label, value };
|
||||
return { label, value };
|
||||
}
|
||||
|
||||
function getSourceWorkflowJobDetails () {
|
||||
@ -273,7 +292,6 @@ function getLimitDetails () {
|
||||
}
|
||||
|
||||
function getInstanceGroupDetails () {
|
||||
|
||||
const instanceGroup = resource.model.get('summary_fields.instance_group');
|
||||
|
||||
if (!instanceGroup) {
|
||||
@ -336,9 +354,9 @@ function getLabelDetails () {
|
||||
}
|
||||
|
||||
const label = 'Labels';
|
||||
const value = jobLabels.map(({ name }) => name).map($filter('sanitize'));
|
||||
const more = false;
|
||||
|
||||
let more = false;
|
||||
const value = jobLabels.map(({ name }) => name).map($filter('sanitize'));
|
||||
|
||||
return { label, more, value };
|
||||
}
|
||||
@ -396,9 +414,7 @@ function cancelJob () {
|
||||
prompt({ hdr, resourceName, body, actionText, action });
|
||||
}
|
||||
|
||||
function deleteJob () {
|
||||
return;
|
||||
}
|
||||
function deleteJob () {}
|
||||
|
||||
function AtDetailsController (
|
||||
_$http_,
|
||||
@ -418,21 +434,18 @@ function AtDetailsController (
|
||||
$state = _$state_;
|
||||
|
||||
error = _error_;
|
||||
// resource = _resource_;
|
||||
parse = ParseVariableString;
|
||||
prompt = _prompt_;
|
||||
strings = _strings_;
|
||||
wait = _wait_;
|
||||
|
||||
// statusChoices = mapChoices(resource.options('status.choices'));
|
||||
vm.init = _$scope_ => {
|
||||
$scope = _$scope_;
|
||||
resource = $scope.resource;
|
||||
|
||||
vm.init = scope => {
|
||||
vm.job = scope.job || {};
|
||||
resource = scope.resource;
|
||||
|
||||
vm.status = getStatusDetails(scope.status);
|
||||
vm.startTime = getStartTimeDetails();
|
||||
vm.finishTime = getFinishTimeDetails();
|
||||
vm.status = getStatusDetails();
|
||||
vm.started = getStartTimeDetails();
|
||||
vm.finished = getFinishTimeDetails();
|
||||
vm.jobType = getJobTypeDetails();
|
||||
vm.jobTemplate = getJobTemplateDetails();
|
||||
vm.sourceWorkflowJob = getSourceWorkflowJobDetails();
|
||||
@ -457,12 +470,24 @@ function AtDetailsController (
|
||||
vm.deleteJob = deleteJob;
|
||||
vm.toggleLabels = toggleLabels;
|
||||
|
||||
// codemirror
|
||||
const cm = { parseType: 'yaml', variables: vm.extraVars.value, $apply: scope.$apply };
|
||||
ParseTypeChange({ scope: cm, field_id: 'cm-extra-vars', readOnly: true });
|
||||
const observe = (key, transform) => {
|
||||
$scope.$watch(key, value => { this[key] = transform(value); });
|
||||
};
|
||||
|
||||
scope.$watch('status', value => { vm.status = getStatusDetails(value); });
|
||||
}
|
||||
observe('status', getStatusDetails);
|
||||
observe('started', getStartTimeDetails);
|
||||
observe('finished', getFinishTimeDetails);
|
||||
|
||||
// relaunch component
|
||||
$scope.job = _.get(resource.model, 'model.GET', {});
|
||||
this.job = $scope.job;
|
||||
|
||||
// codemirror
|
||||
if (this.extraVars) {
|
||||
const cm = { parseType: 'yaml', variables: this.extraVars.value, $apply: $scope.$apply };
|
||||
ParseTypeChange({ scope: cm, field_id: 'cm-extra-vars', readOnly: true });
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
AtDetailsController.$inject = [
|
||||
@ -492,9 +517,10 @@ function atDetails () {
|
||||
link: atDetailsLink,
|
||||
controller: AtDetailsController,
|
||||
scope: {
|
||||
job: '=',
|
||||
status: '=',
|
||||
resource: '=',
|
||||
status: '=',
|
||||
started: '=',
|
||||
finished: '=',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@ -36,25 +36,25 @@
|
||||
<div class="JobResults-resultRow">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.status.label}}</label>
|
||||
<div class="JobResults-resultRowText">
|
||||
<i class="JobResults-statusResultIcon fa icon-job-{{ vm.status.value }}"></i>
|
||||
{{ vm.status.displayValue | translate }}
|
||||
<i class="JobResults-statusResultIcon {{ vm.status.icon }}"></i>
|
||||
{{ vm.status.value }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- START TIME DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-if="vm.startTime">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.startTime.label }}</label>
|
||||
<div class="JobResults-resultRow" ng-if="vm.started">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.started.label }}</label>
|
||||
<div class="JobResults-resultRowText">
|
||||
{{ vm.startTime.displayValue }}
|
||||
{{ vm.started.value }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- FINISHED TIME DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-show="vm.startTime">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.finishTime.label }}</label>
|
||||
<div class="JobResults-resultRow" ng-show="vm.started">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.finished.label }}</label>
|
||||
<div class="JobResults-resultRowText">
|
||||
{{ vm.finishTime.displayValue }}
|
||||
{{ vm.finished.value }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -81,7 +81,7 @@
|
||||
<!-- JOB TYPE DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-if="vm.jobType">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.jobType.label }}</label>
|
||||
<div class="JobResults-resultRowText">{{ vm.jobType.displayValue }}</div>
|
||||
<div class="JobResults-resultRowText">{{ vm.jobType.value }}</div>
|
||||
</div>
|
||||
|
||||
<!-- LAUNCHED BY DETAIL -->
|
||||
@ -164,7 +164,7 @@
|
||||
<!-- VERBOSITY DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-if="vm.verbosity">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.verbosity.label }}</label>
|
||||
<div class="JobResults-resultRowText">{{ vm.verbosity.displayValue }}</div>
|
||||
<div class="JobResults-resultRowText">{{ vm.verbosity.value }}</div>
|
||||
</div>
|
||||
|
||||
<!-- IG DETAIL -->
|
||||
|
||||
@ -10,6 +10,8 @@ let resource;
|
||||
let $state;
|
||||
let qs;
|
||||
|
||||
let hack;
|
||||
|
||||
function JobsIndexController (
|
||||
_resource_,
|
||||
_page_,
|
||||
@ -51,7 +53,7 @@ function JobsIndexController (
|
||||
vm.expand = expand;
|
||||
vm.isExpanded = true;
|
||||
|
||||
// search
|
||||
// Search
|
||||
$state = _$state_;
|
||||
qs = _qs_;
|
||||
|
||||
@ -67,17 +69,47 @@ function JobsIndexController (
|
||||
vm.removeSearchTag = removeSearchTag;
|
||||
vm.searchTags = getSearchTags(getCurrentQueryset());
|
||||
|
||||
// details
|
||||
// Host Status Bar
|
||||
vm.status = {
|
||||
running: Boolean(resource.model.get('started')) && !resource.model.get('finished'),
|
||||
stats: resource.stats,
|
||||
}
|
||||
|
||||
// Details
|
||||
vm.details = {
|
||||
job: resource.model.model.GET,
|
||||
status: resource.model.model.GET.status,
|
||||
resource,
|
||||
started: resource.model.get('started'),
|
||||
finished: resource.model.get('finished'),
|
||||
status: resource.model.get('status'),
|
||||
};
|
||||
|
||||
render.requestAnimationFrame(() => init());
|
||||
}
|
||||
|
||||
function onStreamStart (data) {
|
||||
const status = _.get(data, 'summary_fields.job.status');
|
||||
|
||||
if (!hack) {
|
||||
hack = true;
|
||||
vm.details.status = status;
|
||||
vm.details.started = data.created;
|
||||
|
||||
vm.status.running = true;
|
||||
}
|
||||
}
|
||||
|
||||
function onStreamFinish (data) {
|
||||
const failed = _.get(data, 'summary_fields.job.failed');
|
||||
|
||||
vm.details.status = failed ? 'failed' : 'successful';
|
||||
vm.details.finished = data.created;
|
||||
|
||||
vm.status = { stats: data, running: false };
|
||||
};
|
||||
|
||||
function init (pageMode) {
|
||||
hack = false;
|
||||
|
||||
page.init({
|
||||
resource,
|
||||
});
|
||||
@ -98,10 +130,12 @@ function init (pageMode) {
|
||||
page,
|
||||
scroll,
|
||||
resource,
|
||||
onStreamStart,
|
||||
onStreamFinish,
|
||||
render: events => shift().then(() => append(events, true)),
|
||||
listen: (namespace, listener) => {
|
||||
$scope.$on(namespace, (scope, data) => listener(data));
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
if (pageMode) {
|
||||
|
||||
@ -6,13 +6,16 @@ import Controller from '~features/output/index.controller';
|
||||
import PageService from '~features/output/page.service';
|
||||
import RenderService from '~features/output/render.service';
|
||||
import ScrollService from '~features/output/scroll.service';
|
||||
import SearchKeyDirective from '~features/output/search-key.directive';
|
||||
import StreamService from '~features/output/stream.service';
|
||||
import DetailsDirective from '~features/output/details.directive.js';
|
||||
|
||||
import DetailsDirective from '~features/output/details.directive';
|
||||
import SearchKeyDirective from '~features/output/search-key.directive';
|
||||
import StatusDirective from '~features/output/status.directive';
|
||||
|
||||
const Template = require('~features/output/index.view.html');
|
||||
|
||||
const MODULE_NAME = 'at.features.output';
|
||||
|
||||
const PAGE_CACHE = true;
|
||||
const PAGE_LIMIT = 5;
|
||||
const PAGE_SIZE = 50;
|
||||
@ -66,13 +69,21 @@ function resolveResource (
|
||||
|
||||
Wait('start');
|
||||
return new Resource(['get', 'options'], [id, id])
|
||||
.then(model => Promise.all([
|
||||
model.extend('labels'),
|
||||
model.extend(related, config)
|
||||
]))
|
||||
.then(([ model ]) => ({
|
||||
.then(model => {
|
||||
const promises = [model.getStats()];
|
||||
|
||||
if (model.has('related.labels')) {
|
||||
promises.push(model.extend('labels'));
|
||||
}
|
||||
|
||||
promises.push(model.extend(related, config));
|
||||
|
||||
return Promise.all(promises);
|
||||
})
|
||||
.then(([stats, model]) => ({
|
||||
id,
|
||||
type,
|
||||
stats,
|
||||
model,
|
||||
related,
|
||||
ws: {
|
||||
@ -200,6 +211,7 @@ angular
|
||||
.service('JobStreamService', StreamService)
|
||||
.directive('atDetails', DetailsDirective)
|
||||
.directive('atSearchKey', SearchKeyDirective)
|
||||
.directive('atStatus', StatusDirective)
|
||||
.run(JobsRun);
|
||||
|
||||
export default MODULE_NAME;
|
||||
|
||||
@ -1,14 +1,20 @@
|
||||
<div class="container-fluid">
|
||||
<div class="col-md-4">
|
||||
<at-panel>
|
||||
<at-details job="vm.details.job" status="vm.details.status" resource="vm.details.resource"></at-details>
|
||||
<p><button class="btn" ng-click="vm.clear(true)">Page Mode</button></p>
|
||||
<at-details
|
||||
resource="vm.details.resource"
|
||||
status="vm.details.status"
|
||||
started="vm.details.started"
|
||||
finished="vm.details.finished">
|
||||
</at-details>
|
||||
<!-- --><p><button class="btn" ng-click="vm.clear(true)">Page Mode</button></p>
|
||||
</at-panel>
|
||||
</div>
|
||||
|
||||
<div class="col-md-8">
|
||||
<at-panel class="at-Stdout">
|
||||
<!-- search ============================================================================================================= -->
|
||||
<at-status running="vm.status.running" stats="vm.status.stats"></at-status>
|
||||
<!-- search ===================================================================================== -->
|
||||
<form ng-submit="vm.search()">
|
||||
<div class="input-group">
|
||||
<input type="text"
|
||||
@ -52,7 +58,7 @@
|
||||
|
||||
<at-search-key ng-show="vm.searchKey" fields="vm.searchKeyFields" examples="vm.searchKeyExamples"></at-search-key>
|
||||
|
||||
<!-- ==================================================================================================================== -->
|
||||
<!-- ============================================================================================ -->
|
||||
<div class="at-Stdout-menuTop">
|
||||
<div class="pull-left" ng-click="vm.expand()">
|
||||
<i class="at-Stdout-menuIcon fa"
|
||||
|
||||
@ -12,6 +12,11 @@ function JobsStrings (BaseString) {
|
||||
CANCEL_BODY: t.s('Are you sure you want to cancel this job?'),
|
||||
CANCEL_HEADER: t.s('Cancel Job'),
|
||||
};
|
||||
|
||||
ns.status = {
|
||||
RUNNING: t.s('The host status bar will update when the job is complete.'),
|
||||
UNAVAILABLE: t.s('Host status information for this job unavailable.'),
|
||||
};
|
||||
}
|
||||
|
||||
JobsStrings.$inject = ['BaseStringService'];
|
||||
|
||||
92
awx/ui/client/features/output/status.directive.js
Normal file
92
awx/ui/client/features/output/status.directive.js
Normal file
@ -0,0 +1,92 @@
|
||||
const templateUrl = require('~features/output/status.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]++;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return counts;
|
||||
}
|
||||
|
||||
function createStatusBarTooltip (key, count) {
|
||||
const label = `<span class='HostStatusBar-tooltipLabel'>${key}</span>`;
|
||||
const badge = `<span class='badge HostStatusBar-tooltipBadge HostStatusBar-tooltipBadge--${key}'>${count}</span>`;
|
||||
|
||||
return `${label}${badge}`;
|
||||
}
|
||||
|
||||
function atStatusLink (scope, el, attrs, controllers) {
|
||||
const [atStatusController] = controllers;
|
||||
|
||||
atStatusController.init(scope);
|
||||
}
|
||||
|
||||
function AtStatusController (strings) {
|
||||
const vm = this || {};
|
||||
|
||||
vm.tooltips = {
|
||||
running: strings.get('status.RUNNING'),
|
||||
unavailable: strings.get('status.UNAVAILABLE'),
|
||||
};
|
||||
|
||||
vm.init = scope => {
|
||||
const { running, stats } = scope;
|
||||
|
||||
vm.running = running || false;
|
||||
vm.setStats(stats);
|
||||
|
||||
scope.$watch('running', value => { vm.running = value; });
|
||||
scope.$watch('stats', vm.setStats);
|
||||
};
|
||||
|
||||
vm.setStats = stats => {
|
||||
const counts = getHostStatusCounts(stats);
|
||||
|
||||
HOST_STATUS_KEYS.forEach(key => {
|
||||
const count = counts[key];
|
||||
const statusBarElement = $(`.HostStatusBar-${key}`);
|
||||
|
||||
statusBarElement.css('flex', `${count} 0 auto`);
|
||||
|
||||
vm.tooltips[key] = createStatusBarTooltip(key, count);
|
||||
});
|
||||
|
||||
vm.statsAreAvailable = Boolean(stats);
|
||||
};
|
||||
}
|
||||
|
||||
function atStatus () {
|
||||
return {
|
||||
templateUrl,
|
||||
restrict: 'E',
|
||||
require: ['atStatus'],
|
||||
controllerAs: 'vm',
|
||||
link: atStatusLink,
|
||||
controller: [
|
||||
'JobStrings',
|
||||
AtStatusController
|
||||
],
|
||||
scope: {
|
||||
running: '=',
|
||||
stats: '=',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default atStatus;
|
||||
37
awx/ui/client/features/output/status.partial.html
Normal file
37
awx/ui/client/features/output/status.partial.html
Normal file
@ -0,0 +1,37 @@
|
||||
<div class="HostStatusBar">
|
||||
<div class="HostStatusBar-ok"
|
||||
data-placement="top"
|
||||
aw-tool-tip="{{ vm.tooltips.ok }}"
|
||||
data-tip-watch="vm.tooltips.ok">
|
||||
</div>
|
||||
<div class="HostStatusBar-skipped"
|
||||
data-placement="top"
|
||||
aw-tool-tip="{{ vm.tooltips.skipped }}"
|
||||
data-tip-watch="vm.tooltips.skipped">
|
||||
</div>
|
||||
<div class="HostStatusBar-changed"
|
||||
data-placement="top"
|
||||
aw-tool-tip="{{ vm.tooltips.changed }}"
|
||||
data-tip-watch="vm.tooltips.changed">
|
||||
</div>
|
||||
<div class="HostStatusBar-failures"
|
||||
data-placement="top"
|
||||
aw-tool-tip="{{ vm.tooltips.failures }}"
|
||||
data-tip-watch="vm.tooltips.failures">
|
||||
</div>
|
||||
<div class="HostStatusBar-unreachable"
|
||||
data-placement="top"
|
||||
aw-tool-tip="{{ vm.tooltips.unreachable }}"
|
||||
data-tip-watch="vm.tooltips.unreachable">
|
||||
</div>
|
||||
<div class="HostStatusBar-noData"
|
||||
ng-show="vm.running"
|
||||
data-placement="top"
|
||||
aw-tool-tip="{{:: vm.tooltips.running }}">
|
||||
</div>
|
||||
<div class="HostStatusBar-noData"
|
||||
ng-show="!vm.running && !vm.statsAreAvailable"
|
||||
data-placement="top"
|
||||
aw-tool-tip="{{:: vm.tooltips.unavailable }}">
|
||||
</div>
|
||||
</div>
|
||||
@ -3,7 +3,7 @@ const JOB_END = 'playbook_on_stats';
|
||||
const MAX_LAG = 120;
|
||||
|
||||
function JobStreamService ($q) {
|
||||
this.init = ({ resource, scroll, page, render, listen }) => {
|
||||
this.init = ({ resource, scroll, page, onStreamStart, onStreamFinish, render, listen }) => {
|
||||
this.resource = resource;
|
||||
this.scroll = scroll;
|
||||
this.page = page;
|
||||
@ -23,8 +23,10 @@ function JobStreamService ($q) {
|
||||
};
|
||||
|
||||
this.hooks = {
|
||||
onStreamStart,
|
||||
onStreamFinish,
|
||||
render,
|
||||
listen
|
||||
listen,
|
||||
};
|
||||
|
||||
this.lines = {
|
||||
@ -35,7 +37,7 @@ function JobStreamService ($q) {
|
||||
max: 0
|
||||
};
|
||||
|
||||
this.hooks.listen(resource.ws.namespace, this.listen);
|
||||
this.hooks.listen(resource.ws.namespace, this.listener);
|
||||
};
|
||||
|
||||
this.getBatchFactors = size => {
|
||||
@ -105,19 +107,25 @@ function JobStreamService ($q) {
|
||||
}
|
||||
};
|
||||
|
||||
this.listen = data => {
|
||||
this.listener = data => {
|
||||
this.lag++;
|
||||
|
||||
this.chain = this.chain
|
||||
.then(() => {
|
||||
// console.log(data);
|
||||
if (!this.isActive()) {
|
||||
this.start();
|
||||
if (!this.isEnding()) {
|
||||
this.hooks.onStreamStart(data);
|
||||
}
|
||||
} else if (data.event === JOB_END) {
|
||||
if (this.isPaused()) {
|
||||
this.end(true);
|
||||
} else {
|
||||
this.end();
|
||||
}
|
||||
|
||||
this.hooks.onStreamFinish(data);
|
||||
}
|
||||
|
||||
this.checkLines(data);
|
||||
|
||||
@ -23,26 +23,54 @@ function postRelaunch (params) {
|
||||
return $http(req);
|
||||
}
|
||||
|
||||
function getStats () {
|
||||
if (!this.has('GET', 'id')) {
|
||||
return Promise.reject(new Error('No property, id, exists'));
|
||||
}
|
||||
|
||||
if (!this.has('GET', 'related.job_events')) {
|
||||
return Promise.reject(new Error('No related property, job_events, exists'));
|
||||
}
|
||||
|
||||
const req = {
|
||||
method: 'GET',
|
||||
url: `${this.path}${this.get('id')}/job_events/`,
|
||||
params: { event: 'playbook_on_stats' },
|
||||
};
|
||||
|
||||
return $http(req)
|
||||
.then(({ data }) => {
|
||||
if (data.results.length > 0) {
|
||||
return data.results[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function JobModel (method, resource, config) {
|
||||
BaseModel.call(this, 'jobs');
|
||||
|
||||
this.Constructor = JobModel;
|
||||
|
||||
this.postRelaunch = postRelaunch.bind(this);
|
||||
this.getRelaunch = getRelaunch.bind(this);
|
||||
this.getStats = getStats.bind(this);
|
||||
|
||||
return this.create(method, resource, config);
|
||||
}
|
||||
|
||||
function JobModelLoader (_BaseModel_, _$http_) {
|
||||
BaseModel = _BaseModel_;
|
||||
function JobModelLoader (_$http_, _BaseModel_) {
|
||||
$http = _$http_;
|
||||
BaseModel = _BaseModel_;
|
||||
|
||||
return JobModel;
|
||||
}
|
||||
|
||||
JobModelLoader.$inject = [
|
||||
'$http',
|
||||
'BaseModel',
|
||||
'$http'
|
||||
];
|
||||
|
||||
export default JobModelLoader;
|
||||
|
||||
@ -1,19 +1,54 @@
|
||||
let $http;
|
||||
let BaseModel;
|
||||
|
||||
function getStats () {
|
||||
if (!this.has('GET', 'id')) {
|
||||
return Promise.reject(new Error('No property, id, exists'));
|
||||
}
|
||||
|
||||
if (!this.has('GET', 'related.events')) {
|
||||
return Promise.reject(new Error('No related property, events, exists'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
const req = {
|
||||
method: 'GET',
|
||||
url: `${this.path}${this.get('id')}/events/`,
|
||||
params: { event: 'playbook_on_stats' },
|
||||
};
|
||||
|
||||
return $http(req)
|
||||
.then(({ data }) => {
|
||||
console.log(data);
|
||||
if (data.results.length > 0) {
|
||||
return data.results[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
}
|
||||
|
||||
function ProjectUpdateModel (method, resource, config) {
|
||||
BaseModel.call(this, 'project_updates');
|
||||
|
||||
this.getStats = getStats;
|
||||
|
||||
this.Constructor = ProjectUpdateModel;
|
||||
|
||||
return this.create(method, resource, config);
|
||||
}
|
||||
|
||||
function ProjectUpdateModelLoader (_BaseModel_) {
|
||||
function ProjectUpdateModelLoader (_$http_, _BaseModel_) {
|
||||
$http = _$http_;
|
||||
BaseModel = _BaseModel_;
|
||||
|
||||
return ProjectUpdateModel;
|
||||
}
|
||||
|
||||
ProjectUpdateModelLoader.$inject = ['BaseModel'];
|
||||
ProjectUpdateModelLoader.$inject = [
|
||||
'$http',
|
||||
'BaseModel'
|
||||
];
|
||||
|
||||
export default ProjectUpdateModelLoader;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user