1
0
mirror of https://github.com/ansible/awx.git synced 2024-10-31 23:51:09 +03:00

add basic output expand-collapse

This commit is contained in:
Jake McDermott 2018-06-11 10:51:09 -04:00
parent ce411a21c6
commit eb39fcfeaf
No known key found for this signature in database
GPG Key ID: 3B02CAD476EECB35
4 changed files with 113 additions and 45 deletions

View File

@ -67,14 +67,6 @@ function onFrames (events) {
const capacity = slide.getCapacity();
if (capacity >= events.length) {
return slide.pushFront(events);
}
delete render.record;
render.record = {};
return slide.popBack(events.length - capacity)
.then(() => slide.pushFront(events))
.then(() => {
@ -131,10 +123,6 @@ function last () {
});
}
function compile (html) {
return $compile(html)($scope);
}
function follow () {
scroll.pause();
// scroll.hide();
@ -149,6 +137,69 @@ function unfollow () {
scroll.resume();
}
function togglePanelExpand () {
vm.isPanelExpanded = !vm.isPanelExpanded;
}
function toggleMenuExpand () {
if (scroll.isPaused()) return;
const recordList = Object.keys(render.record).map(key => render.record[key]);
const minLevel = Math.min(...recordList.map(({ level }) => level));
const toggled = recordList
.filter(({ level }) => level === minLevel)
.map(({ uuid }) => getToggleElements(uuid))
.filter(({ icon }) => icon.length > 0)
.map(({ icon, lines }) => setExpanded(icon, lines, !vm.isMenuExpanded));
if (toggled.length > 0) {
vm.isMenuExpanded = !vm.isMenuExpanded;
}
}
function toggleLineExpand (uuid) {
if (scroll.isPaused()) return;
const { icon, lines } = getToggleElements(uuid);
const isExpanded = icon.hasClass('fa-angle-down');
setExpanded(icon, lines, !isExpanded);
vm.isMenuExpanded = !isExpanded;
}
function getToggleElements (uuid) {
const record = render.record[uuid];
const lines = $(`.child-of-${uuid}`);
const iconSelector = '.at-Stdout-toggle > i';
const additionalSelector = `#${(record.children || []).join(', #')}`;
let icon = $(`#${uuid} ${iconSelector}`);
if (additionalSelector) {
icon = icon.add($(additionalSelector).find(iconSelector));
}
return { icon, lines };
}
function setExpanded (icon, lines, expanded) {
if (expanded) {
icon.removeClass('fa-angle-right');
icon.addClass('fa-angle-down');
lines.removeClass('hidden');
} else {
icon.removeClass('fa-angle-down');
icon.addClass('fa-angle-right');
lines.addClass('hidden');
}
}
function compile (html) {
return $compile(html)($scope);
}
function showHostDetails (id, uuid) {
$state.go('output.host-event.json', { eventId: id, taskUuid: uuid });
}
@ -203,13 +254,11 @@ function OutputIndexController (
vm = this || {};
// Panel
vm.title = $filter('sanitize')(resource.model.get('name'));
vm.strings = strings;
vm.resource = resource;
vm.title = $filter('sanitize')(resource.model.get('name'));
vm.expanded = false;
vm.showHostDetails = showHostDetails;
vm.toggleExpanded = () => { vm.expanded = !vm.expanded; };
vm.isPanelExpanded = false;
vm.togglePanelExpand = togglePanelExpand;
// Stdout Navigation
vm.menu = {
@ -218,6 +267,11 @@ function OutputIndexController (
up: previous,
down: next,
};
vm.isMenuExpanded = true;
vm.toggleMenuExpand = toggleMenuExpand;
vm.toggleLineExpand = toggleLineExpand;
vm.showHostDetails = showHostDetails;
vm.toggleLineEnabled = resource.model.get('type') === 'job';
render.requestAnimationFrame(() => {
bufferInit();
@ -225,7 +279,7 @@ function OutputIndexController (
status.init(resource);
slide.init(render, resource.events);
render.init({ compile });
render.init({ compile, toggles: vm.toggleLineEnabled });
scroll.init({ previous, next });
stream.init({

View File

@ -1,25 +1,25 @@
<div ui-view></div>
<div class="JobResults-container">
<at-panel ng-show="!vm.expanded">
<at-panel ng-show="!vm.isPanelExpanded">
<at-job-details
resource="vm.resource">
</at-job-details>
</at-panel>
<at-panel class="at-Stdout" ng-class="{'at-Stdout--fullscreen': vm.expanded}">
<at-panel class="at-Stdout" ng-class="{'at-Stdout--fullscreen': vm.isPanelExpanded}">
<div class="at-Panel-headingTitle">
{{ vm.title }}
</div>
<at-job-stats
resource="vm.resource"
expanded="vm.expanded">
expanded="vm.isPanelExpanded">
</at-job-stats>
<at-job-search></at-job-search>
<div class="at-Stdout-menuTop">
<div class="pull-left" ng-click="vm.toggleExpand()">
<i class="at-Stdout-menuIcon fa"
ng-class="{ 'fa-minus': vm.expanded, 'fa-plus': !vm.expanded }"></i>
<div class="pull-left" ng-click="vm.toggleMenuExpand()">
<i class="at-Stdout-menuIcon fa" ng-if="vm.toggleLineEnabled"
ng-class="{ 'fa-minus': vm.isMenuExpanded, 'fa-plus': !vm.isMenuExpanded }"></i>
</div>
<div class="pull-right" ng-click="vm.menu.end()">

View File

@ -30,13 +30,13 @@ const re = new RegExp(pattern);
const hasAnsi = input => re.test(input);
function JobRenderService ($q, $sce, $window) {
this.init = ({ compile }) => {
this.init = ({ compile, toggles }) => {
this.parent = null;
this.record = {};
this.el = $(ELEMENT_TBODY);
this.hooks = { compile };
this.createToggles = false;
this.createToggles = toggles;
};
this.sortByLineNumber = (a, b) => {
@ -164,6 +164,24 @@ function JobRenderService ($q, $sce, $window) {
return info;
};
this.deleteRecord = uuid => {
delete this.record[uuid];
};
this.getParentEvents = (uuid, list) => {
list = list || [];
if (this.record[uuid]) {
list.push(uuid);
if (this.record[uuid].parents) {
list = list.concat(this.record[uuid].parents);
}
}
return list;
};
this.createRow = (current, ln, content) => {
let id = '';
let timestamp = '';
@ -180,7 +198,7 @@ function JobRenderService ($q, $sce, $window) {
if (current) {
if (this.createToggles && current.isParent && current.line === ln) {
id = current.uuid;
tdToggle = `<td class="at-Stdout-toggle" ng-click="vm.toggle('${id}')"><i class="fa fa-angle-down can-toggle"></i></td>`;
tdToggle = `<td class="at-Stdout-toggle" ng-click="vm.toggleLineExpand('${id}')"><i class="fa fa-angle-down can-toggle"></i></td>`;
}
if (current.isHost) {
@ -226,20 +244,6 @@ function JobRenderService ($q, $sce, $window) {
return `${hour}:${minute}:${second}`;
};
this.getParentEvents = (uuid, list) => {
list = list || [];
if (this.record[uuid]) {
list.push(uuid);
if (this.record[uuid].parents) {
list = list.concat(this.record[uuid].parents);
}
}
return list;
};
this.remove = elements => this.requestAnimationFrame(() => elements.remove());
this.requestAnimationFrame = fn => $q(resolve => {

View File

@ -60,7 +60,7 @@ function getOverlapArray (range, other) {
function SlidingWindowService ($q) {
this.init = (storage, api) => {
const { prepend, append, shift, pop } = storage;
const { prepend, append, shift, pop, deleteRecord } = storage;
const { getMaxCounter, getRange, getFirst, getLast } = api;
this.api = {
@ -74,10 +74,12 @@ function SlidingWindowService ($q) {
prepend,
append,
shift,
pop
pop,
deleteRecord,
};
this.records = {};
this.uuids = {};
this.chain = $q.resolve();
};
@ -87,8 +89,9 @@ function SlidingWindowService ($q) {
return this.storage.append(newEvents)
.then(() => {
newEvents.forEach(({ counter, start_line, end_line }) => {
newEvents.forEach(({ counter, start_line, end_line, uuid }) => {
this.records[counter] = { start_line, end_line };
this.uuids[counter] = uuid;
});
return $q.resolve();
@ -102,8 +105,9 @@ function SlidingWindowService ($q) {
return this.storage.prepend(newEvents)
.then(() => {
newEvents.forEach(({ counter, start_line, end_line }) => {
newEvents.forEach(({ counter, start_line, end_line, uuid }) => {
this.records[counter] = { start_line, end_line };
this.uuids[counter] = uuid;
});
return $q.resolve();
@ -130,6 +134,9 @@ function SlidingWindowService ($q) {
.then(() => {
for (let i = max; i >= min; --i) {
delete this.records[i];
this.storage.deleteRecord(this.uuids[i]);
delete this.uuids[i];
}
return $q.resolve();
@ -156,6 +163,9 @@ function SlidingWindowService ($q) {
.then(() => {
for (let i = min; i <= max; ++i) {
delete this.records[i];
this.storage.deleteRecord(this.uuids[i]);
delete this.uuids[i];
}
return $q.resolve();