Merge pull request #2860 from jakemcdermott/fix-2228

make line expand / collapse work for paginated scrollup
This commit is contained in:
Jake McDermott 2018-08-20 13:12:52 -04:00 committed by GitHub
commit eb0cf945cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 128 additions and 46 deletions

View File

@ -273,64 +273,121 @@ function togglePanelExpand () {
vm.isPanelExpanded = !vm.isPanelExpanded;
}
function toggleMenuExpand () {
const iconCollapsed = 'fa-angle-right';
const iconExpanded = 'fa-angle-down';
const iconSelector = '.at-Stdout-toggle > i';
const lineCollapsed = 'hidden';
function toggleCollapseAll () {
if (scroll.isPaused()) return;
const recordList = Object.keys(render.record).map(key => render.record[key]);
const playRecords = recordList.filter(({ name }) => name === EVENT_START_PLAY);
const playIds = playRecords.map(({ uuid }) => uuid);
const records = Object.keys(render.record).map(key => render.record[key]);
const plays = records.filter(({ name }) => name === EVENT_START_PLAY);
const tasks = records.filter(({ name }) => name === EVENT_START_TASK);
// get any task record that does not have a parent play record
const orphanTaskRecords = recordList
.filter(({ name }) => name === EVENT_START_TASK)
.filter(({ parents }) => !parents.some(uuid => playIds.indexOf(uuid) >= 0));
const orphanLines = records
.filter(({ level }) => level === 3)
.filter(({ parents }) => !records[parents[0]]);
const toggled = playRecords.concat(orphanTaskRecords)
.map(({ uuid }) => getToggleElements(uuid))
.filter(({ icon }) => icon.length > 0)
.map(({ icon, lines }) => setExpanded(icon, lines, !vm.isMenuExpanded));
const orphanLineParents = orphanLines
.map(({ parents }) => ({ uuid: parents[0] }));
if (toggled.length > 0) {
vm.isMenuExpanded = !vm.isMenuExpanded;
plays.concat(tasks).forEach(({ uuid }) => {
const icon = $(`#${uuid} ${iconSelector}`);
if (vm.isMenuCollapsed) {
icon.removeClass(iconCollapsed);
icon.addClass(iconExpanded);
} else {
icon.removeClass(iconExpanded);
icon.addClass(iconCollapsed);
}
});
tasks.concat(orphanLineParents).forEach(({ uuid }) => {
const lines = $(`.child-of-${uuid}`);
if (vm.isMenuCollapsed) {
lines.removeClass(lineCollapsed);
} else {
lines.addClass(lineCollapsed);
}
});
vm.isMenuCollapsed = !vm.isMenuCollapsed;
render.setCollapseAll(vm.isMenuCollapsed);
}
function toggleCollapse (uuid) {
if (scroll.isPaused()) return;
const record = render.record[uuid];
if (record.name === EVENT_START_PLAY) {
togglePlayCollapse(uuid);
}
if (record.name === EVENT_START_TASK) {
toggleTaskCollapse(uuid);
}
}
function toggleLineExpand (uuid) {
if (scroll.isPaused()) return;
function togglePlayCollapse (uuid) {
const record = render.record[uuid];
const descendants = record.children || [];
const { icon, lines } = getToggleElements(uuid);
const isExpanded = icon.hasClass('fa-angle-down');
const icon = $(`#${uuid} ${iconSelector}`);
const lines = $(`.child-of-${uuid}`);
const taskIcons = $(`#${descendants.join(', #')}`).find(iconSelector);
setExpanded(icon, lines, !isExpanded);
const isCollapsed = icon.hasClass(iconCollapsed);
vm.isMenuExpanded = !isExpanded;
if (isCollapsed) {
icon.removeClass(iconCollapsed);
icon.addClass(iconExpanded);
taskIcons.removeClass(iconExpanded);
taskIcons.addClass(iconCollapsed);
lines.removeClass(lineCollapsed);
descendants
.map(item => $(`.child-of-${item}`))
.forEach(line => line.addClass(lineCollapsed));
} else {
icon.removeClass(iconExpanded);
icon.addClass(iconCollapsed);
taskIcons.removeClass(iconExpanded);
taskIcons.addClass(iconCollapsed);
lines.addClass(lineCollapsed);
}
descendants
.map(item => render.record[item])
.filter(({ name }) => name === EVENT_START_TASK)
.forEach(rec => { render.record[rec.uuid].isCollapsed = true; });
render.record[uuid].isCollapsed = !isCollapsed;
}
function getToggleElements (uuid) {
const record = render.record[uuid];
function toggleTaskCollapse (uuid) {
const icon = $(`#${uuid} ${iconSelector}`);
const lines = $(`.child-of-${uuid}`);
const iconSelector = '.at-Stdout-toggle > i';
const additionalSelector = `#${(record.children || []).join(', #')}`;
const isCollapsed = icon.hasClass(iconCollapsed);
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');
if (isCollapsed) {
icon.removeClass(iconCollapsed);
icon.addClass(iconExpanded);
lines.removeClass(lineCollapsed);
} else {
icon.removeClass('fa-angle-down');
icon.addClass('fa-angle-right');
lines.addClass('hidden');
icon.removeClass(iconExpanded);
icon.addClass(iconCollapsed);
lines.addClass(lineCollapsed);
}
render.record[uuid].isCollapsed = !isCollapsed;
}
function compile (html) {
@ -476,10 +533,10 @@ function OutputIndexController (
// Stdout Navigation
vm.menu = { last: menuLast, first, down, up, clear };
vm.isMenuExpanded = true;
vm.isMenuCollapsed = false;
vm.isFollowing = false;
vm.toggleMenuExpand = toggleMenuExpand;
vm.toggleLineExpand = toggleLineExpand;
vm.toggleCollapseAll = toggleCollapseAll;
vm.toggleCollapse = toggleCollapse;
vm.showHostDetails = showHostDetails;
vm.toggleLineEnabled = resource.model.get('type') === 'job';
vm.followTooltip = vm.strings.get('tooltips.MENU_LAST');

View File

@ -21,9 +21,9 @@
reload="vm.reloadState">
</at-job-search>
<div class="at-Stdout-menuTop">
<div class="pull-left" ng-click="vm.toggleMenuExpand()">
<div class="pull-left" ng-click="vm.toggleCollapseAll()">
<i class="at-Stdout-menuIcon fa" ng-if="vm.toggleLineEnabled"
ng-class="{ 'fa-minus': vm.isMenuExpanded, 'fa-plus': !vm.isMenuExpanded }"></i>
ng-class="{ 'fa-minus': !vm.isMenuCollapsed, 'fa-plus': vm.isMenuCollapsed }"></i>
</div>
<div class="pull-right" ng-click="vm.menu.last()">
<i class="at-Stdout-menuIcon--lg fa fa-angle-double-down"

View File

@ -39,6 +39,13 @@ function JobRenderService ($q, $sce, $window) {
this.hooks = { compile };
this.createToggles = toggles;
this.state = {
collapseAll: false
};
};
this.setCollapseAll = value => {
this.state.collapseAll = value;
};
this.sortByLineNumber = (a, b) => {
@ -133,10 +140,14 @@ function JobRenderService ($q, $sce, $window) {
isTruncated: (event.end_line - event.start_line) > lines.length,
lineCount: lines.length,
isHost: this.isHostEvent(event),
isCollapsed: this.state.collapseAll,
};
if (event.parent_uuid) {
info.parents = this.getParentEvents(event.parent_uuid);
if (this.record[event.parent_uuid]) {
info.isCollapsed = this.record[event.parent_uuid].isCollapsed;
}
}
if (info.isTruncated) {
@ -192,6 +203,7 @@ function JobRenderService ($q, $sce, $window) {
this.createRow = (current, ln, content) => {
let id = '';
let icon = '';
let timestamp = '';
let tdToggle = '';
let tdEvent = '';
@ -206,7 +218,14 @@ function JobRenderService ($q, $sce, $window) {
if (current) {
if (this.createToggles && current.isParent && current.line === ln) {
id = current.uuid;
tdToggle = `<div class="at-Stdout-toggle" ng-click="vm.toggleLineExpand('${id}')"><i class="fa fa-angle-down can-toggle"></i></div>`;
if (current.isCollapsed) {
icon = 'fa-angle-right';
} else {
icon = 'fa-angle-down';
}
tdToggle = `<div class="at-Stdout-toggle" ng-click="vm.toggleCollapse('${id}')"><i class="fa ${icon} can-toggle"></i></div>`;
}
if (current.isHost) {
@ -234,6 +253,12 @@ function JobRenderService ($q, $sce, $window) {
ln = '...';
}
if (current && current.isCollapsed) {
if (current.level === 3 || current.level === 0) {
classList += ' hidden';
}
}
return `
<div id="${id}" class="at-Stdout-row ${classList}">
${tdToggle}