Add component-based stdout for host modal

This commit is contained in:
gconsidine 2017-12-12 16:26:12 -05:00 committed by Jake McDermott
parent 21e74fc5eb
commit a7f29aac3a
11 changed files with 189 additions and 37 deletions

View File

@ -1,3 +1,3 @@
@import 'credentials/_index';
@import 'jobs/_index';
@import 'output/_index';
@import 'users/tokens/_index';

View File

@ -3,6 +3,7 @@ import hasAnsi from 'has-ansi';
let vm;
let ansi;
let jobEvent;
let $timeout;
let $sce;
let $compile;
@ -26,19 +27,19 @@ const TIME_EVENTS = [
EVENT_STATS_PLAY
];
function JobsIndexController (job, _$sce_, _$timeout_, _$scope_, _$compile_) {
function JobsIndexController (job, JobEventModel, _$sce_, _$timeout_, _$scope_, _$compile_) {
$timeout = _$timeout_;
$sce = _$sce_;
$compile = _$compile_;
$scope = _$scope_;
ansi = new Ansi();
jobEvent = new JobEventModel();
const events = job.get('related.job_events.results');
const html = $sce.trustAsHtml(parseEvents(events));
vm = this || {};
$scope.ns = 'jobs';
vm = this || {}; $scope.ns = 'jobs';
$scope.jobs = {
modal: {}
};
@ -256,7 +257,17 @@ function getTime (created) {
}
function showHostDetails (id) {
$scope.jobs.modal.show('title', `test${id}`);
jobEvent.request('get', id)
.then(() => {
const title = jobEvent.get('host_name');
vm.host = {
menu: true,
stdout: jobEvent.get('stdout')
};
$scope.jobs.modal.show(title);
});
}
function toggle (uuid) {
@ -280,6 +291,6 @@ function toggle (uuid) {
}
}
JobsIndexController.$inject = ['job', '$sce', '$timeout', '$scope', '$compile'];
JobsIndexController.$inject = ['job', 'JobEventModel', '$sce', '$timeout', '$scope', '$compile'];
module.exports = JobsIndexController;

View File

@ -1,3 +1,8 @@
import JobsStrings from '~features/output/jobs.strings';
import IndexController from '~features/output/index.controller';
import atLibModels from '~models';
import atLibComponents from '~components';
import JobsStrings from '~features/output/jobs.strings';
import IndexController from '~features/output/index.controller';
@ -24,7 +29,7 @@ function JobsRun ($stateExtender, strings) {
}
},
resolve: {
job: ['JobsModel', '$stateParams', (Jobs, $stateParams) => {
job: ['JobModel', '$stateParams', (Jobs, $stateParams) => {
const { id } = $stateParams;
return new Jobs('get', id)
@ -42,7 +47,10 @@ function JobsRun ($stateExtender, strings) {
JobsRun.$inject = ['$stateExtender', 'JobsStrings'];
angular
.module(MODULE_NAME, [])
.module(MODULE_NAME, [
atLibModels,
atLibComponents
])
.controller('indexController', IndexController)
.service('JobsStrings', JobsStrings)
.run(JobsRun);

View File

@ -1,7 +1,7 @@
<div class="container-fluid">
<div class="col-md-4">
<at-panel>
<p>left</p>
<p></p>
</at-panel>
</div>
@ -31,5 +31,8 @@
</at-panel>
</div>
<at-modal></at-modal>
<at-modal>
<br />
<at-output-stdout state="vm.host"></at-output-stdout>
</at-modal>
</div>

View File

@ -20,6 +20,7 @@ import launchTemplate from '~components/launchTemplateButton/launchTemplateButto
import layout from '~components/layout/layout.directive';
import list from '~components/list/list.directive';
import modal from '~components/modal/modal.directive';
import outputStdout from '~components/output/stdout.directive';
import panel from '~components/panel/panel.directive';
import panelBody from '~components/panel/body.directive';
import panelHeading from '~components/panel/heading.directive';
@ -68,6 +69,7 @@ angular
.directive('atRowItem', rowItem)
.directive('atRowAction', rowAction)
.directive('atModal', modal)
.directive('atOutputStdout', outputStdout)
.directive('atPanel', panel)
.directive('atPanelBody', panelBody)
.directive('atPanelHeading', panelHeading)

View File

@ -0,0 +1,105 @@
import Ansi from 'ansi-to-html';
import hasAnsi from 'has-ansi';
const templateUrl = require('~components/output/stdout.partial.html');
let $sce;
let $timeout;
let ansi;
function atOutputStdoutLink (scope, element, attrs, controller) {
controller.init(scope, element);
}
function AtOutputStdoutController (_$sce_, _$timeout_) {
const vm = this || {};
$timeout = _$timeout_;
$sce = _$sce_;
ansi = new Ansi();
let scope;
let element;
vm.init = (_scope_, _element_) => {
scope = _scope_;
element = _element_;
scope.$watch('state.stdout', curr => {
if (!curr) {
return;
}
render(scope.state.stdout);
});
};
vm.scroll = position => {
const container = element.find('.at-Stdout-container')[0];
if (position === 'bottom') {
container.scrollTop = container.scrollHeight;
} else {
container.scrollTop = 0;
}
};
}
AtOutputStdoutController.$inject = [
'$sce',
'$timeout',
];
function render (stdout) {
console.log('render');
const html = $sce.trustAsHtml(parseStdout(stdout));
$timeout(() => {
const table = $('#atStdoutTBody');
table.html($sce.getTrustedHtml(html));
});
}
function parseStdout (stdout) {
const lines = stdout.split('\r\n');
let ln = 0;
return lines.reduce((html, line) => {
ln++;
return `${html}${createRow(ln, line)}`;
}, '');
}
function createRow (ln, content) {
content = content || '';
if (hasAnsi(content)) {
content = ansi.toHtml(content);
}
return `
<tr>
<td class="at-Stdout-line">${ln}</td>
<td class="at-Stdout-event">${content}</td>
</tr>`;
}
function atOutputStdout () {
return {
restrict: 'E',
transclude: true,
replace: true,
require: 'atOutputStdout',
templateUrl,
controller: AtOutputStdoutController,
controllerAs: 'vm',
link: atOutputStdoutLink,
scope: {
state: '=',
}
};
}
export default atOutputStdout;

View File

@ -0,0 +1,19 @@
<div class="at-Stdout">
<div ng-if="state.menu" class="at-Stdout-menuTop">
<div class="pull-right" ng-click="vm.scroll('bottom')">
<i class="at-Stdout-menuIcon fa fa-arrow-down"></i>
</div>
<div class="at-u-clear"></div>
</div>
<pre class="at-Stdout-container"><table><thead><tr><th class="at-Stdout-line"></th><th class="at-Stdout-event"></th></tr></thead><tbody id="atStdoutTBody"></tbody></table></pre>
<div ng-if="state-menu" class="at-Stdout-menuBottom">
<div class="pull-right" ng-click="vm.scroll('top')">
<i class="at-Stdout-menuIcon fa fa-arrow-up"></i>
</div>
<div class="at-u-clear"></div>
</div>
</div>

View File

@ -1,5 +1,5 @@
let Base;
let $http;
let BaseModel;
function getRelaunch (params) {
const req = {
@ -24,7 +24,7 @@ function postRelaunch (params) {
}
function JobModel (method, resource, config) {
Base.call(this, 'jobs');
BaseModel.call(this, 'jobs');
this.Constructor = JobModel;
this.postRelaunch = postRelaunch.bind(this);
@ -33,8 +33,8 @@ function JobModel (method, resource, config) {
return this.create(method, resource, config);
}
function JobModelLoader (BaseModel, _$http_) {
Base = BaseModel;
function JobModelLoader (_BaseModel_, _$http_) {
BaseModel = _BaseModel_;
$http = _$http_;
return JobModel;

View File

@ -0,0 +1,19 @@
let BaseModel;
function JobEventModel (method, resource, config) {
BaseModel.call(this, 'job_events');
this.Constructor = JobEventModel;
return this.create(method, resource, config);
}
function JobEventModelLoader (_BaseModel_) {
BaseModel = _BaseModel_;
return JobEventModel;
}
JobEventModel.$inject = ['BaseModel'];
export default JobEventModelLoader;

View File

@ -1,19 +0,0 @@
let BaseModel;
function JobsModel (method, resource, config) {
BaseModel.call(this, 'jobs');
this.Constructor = JobsModel;
return this.create(method, resource, config);
}
function JobsModelLoader (_BaseModel_) {
BaseModel = _BaseModel_;
return JobsModel;
}
JobsModelLoader.$inject = ['BaseModel'];
export default JobsModelLoader;

View File

@ -12,10 +12,10 @@ import Inventory from '~models/Inventory';
import InventoryScript from '~models/InventoryScript';
import InventorySource from '~models/InventorySource';
import Job from '~models/Job';
import JobEvent from '~models/JobEvent';
import JobTemplate from '~models/JobTemplate';
import Jobs from '~models/Jobs';
import Me from '~models/Me';
import ModelsStrings from '~models/models.strings';
import NotificationTemplate from '~models/NotificationTemplate';
import Organization from '~models/Organization';
import Project from '~models/Project';
@ -26,6 +26,8 @@ import WorkflowJobTemplate from '~models/WorkflowJobTemplate';
import WorkflowJobTemplateNode from '~models/WorkflowJobTemplateNode';
import UnifiedJob from '~models/UnifiedJob';
import ModelsStrings from '~models/models.strings';
const MODULE_NAME = 'at.lib.models';
angular
@ -43,11 +45,11 @@ angular
.service('InventoryModel', Inventory)
.service('InventoryScriptModel', InventoryScript)
.service('InventorySourceModel', InventorySource)
.service('JobEventModel', JobEvent)
.service('JobModel', Job)
.service('JobTemplateModel', JobTemplate)
.service('JobsModel', Jobs)
.service('MeModel', Me)
.service('ModelsStrings', ModelsStrings)
.service('NotificationTemplate', NotificationTemplate)
.service('OrganizationModel', Organization)
.service('ProjectModel', Project)
@ -56,6 +58,8 @@ angular
.service('UnifiedJobTemplateModel', UnifiedJobTemplate)
.service('WorkflowJobModel', WorkflowJob)
.service('WorkflowJobTemplateModel', WorkflowJobTemplate)
.service('WorkflowJobTemplateNodeModel', WorkflowJobTemplateNode);
.service('WorkflowJobTemplateNodeModel', WorkflowJobTemplateNode)
.service('WorkflowJobTemplateNodeModel', WorkflowJobTemplateNode)
.service('ModelsStrings', ModelsStrings);
export default MODULE_NAME;