mirror of
https://github.com/ZwareBear/awx.git
synced 2026-03-25 18:23:37 -05:00
874 lines
20 KiB
JavaScript
874 lines
20 KiB
JavaScript
/* eslint camelcase: 0 */
|
|
import {
|
|
EVENT_START_PLAY,
|
|
EVENT_START_TASK,
|
|
OUTPUT_ELEMENT_LAST,
|
|
OUTPUT_PAGE_SIZE,
|
|
} from './constants';
|
|
|
|
let $q;
|
|
let $scope;
|
|
let $state;
|
|
|
|
let resource;
|
|
let render;
|
|
let scroll;
|
|
let status;
|
|
let slide;
|
|
let stream;
|
|
let page;
|
|
|
|
let vm;
|
|
const listeners = [];
|
|
let lockFrames = false;
|
|
|
|
function onFrames (events) {
|
|
events = slide.pushFrames(events);
|
|
|
|
if (lockFrames) {
|
|
return $q.resolve();
|
|
}
|
|
|
|
const popCount = events.length - render.getCapacity();
|
|
|
|
if (!vm.isFollowing && canStartFollowing()) {
|
|
startFollowing();
|
|
}
|
|
|
|
if (!vm.isFollowing && popCount > 0) {
|
|
return $q.resolve();
|
|
}
|
|
|
|
scroll.pause();
|
|
|
|
if (vm.isFollowing) {
|
|
scroll.scrollToBottom();
|
|
}
|
|
|
|
return render.popBack(popCount)
|
|
.then(() => {
|
|
if (vm.isFollowing) {
|
|
scroll.scrollToBottom();
|
|
}
|
|
|
|
return render.pushFront(events);
|
|
})
|
|
.then(() => {
|
|
if (vm.isFollowing) {
|
|
scroll.scrollToBottom();
|
|
}
|
|
|
|
scroll.resume();
|
|
|
|
return $q.resolve();
|
|
});
|
|
}
|
|
|
|
//
|
|
// Menu Controls (Running)
|
|
//
|
|
|
|
function firstRange () {
|
|
if (scroll.isPaused()) {
|
|
return $q.resolve();
|
|
}
|
|
|
|
stopFollowing();
|
|
lockFollow = true;
|
|
|
|
if (slide.isOnFirstPage()) {
|
|
scroll.resetScrollPosition();
|
|
|
|
return $q.resolve();
|
|
}
|
|
|
|
scroll.pause();
|
|
lockFrames = true;
|
|
|
|
return render.clear()
|
|
.then(() => slide.getFirst())
|
|
.then(results => render.pushFront(results))
|
|
.then(() => slide.getNext())
|
|
.then(results => {
|
|
const popCount = results.length - render.getCapacity();
|
|
|
|
return render.popBack(popCount)
|
|
.then(() => render.pushFront(results));
|
|
})
|
|
.finally(() => {
|
|
render.compile();
|
|
scroll.resume();
|
|
lockFollow = false;
|
|
});
|
|
}
|
|
|
|
function nextRange () {
|
|
if (vm.isFollowing) {
|
|
scroll.scrollToBottom();
|
|
|
|
return $q.resolve();
|
|
}
|
|
|
|
if (scroll.isPaused()) {
|
|
return $q.resolve();
|
|
}
|
|
|
|
scroll.pause();
|
|
lockFrames = true;
|
|
|
|
return slide.getNext()
|
|
.then(results => {
|
|
const popCount = results.length - render.getCapacity();
|
|
|
|
return render.popBack(popCount)
|
|
.then(() => render.pushFront(results));
|
|
})
|
|
.finally(() => {
|
|
render.compile();
|
|
scroll.resume();
|
|
lockFrames = false;
|
|
|
|
return $q.resolve();
|
|
});
|
|
}
|
|
|
|
function previousRange () {
|
|
if (scroll.isPaused()) {
|
|
return $q.resolve();
|
|
}
|
|
|
|
scroll.pause();
|
|
stopFollowing();
|
|
lockFrames = true;
|
|
|
|
let initialPosition;
|
|
let popHeight;
|
|
|
|
return slide.getPrevious()
|
|
.then(results => {
|
|
const popCount = results.length - render.getCapacity();
|
|
initialPosition = scroll.getScrollPosition();
|
|
|
|
return render.popFront(popCount)
|
|
.then(() => {
|
|
popHeight = scroll.getScrollHeight();
|
|
|
|
return render.pushBack(results);
|
|
});
|
|
})
|
|
.then(() => {
|
|
const currentHeight = scroll.getScrollHeight();
|
|
scroll.setScrollPosition(currentHeight - popHeight + initialPosition);
|
|
|
|
return $q.resolve();
|
|
})
|
|
.finally(() => {
|
|
render.compile();
|
|
scroll.resume();
|
|
lockFrames = false;
|
|
|
|
return $q.resolve();
|
|
});
|
|
}
|
|
|
|
function lastRange () {
|
|
if (scroll.isPaused()) {
|
|
return $q.resolve();
|
|
}
|
|
|
|
scroll.pause();
|
|
lockFrames = true;
|
|
|
|
return render.clear()
|
|
.then(() => slide.getLast())
|
|
.then(results => render.pushFront(results))
|
|
.then(() => {
|
|
stream.setMissingCounterThreshold(slide.getTailCounter() + 1);
|
|
|
|
scroll.scrollToBottom();
|
|
lockFrames = false;
|
|
|
|
return $q.resolve();
|
|
})
|
|
.finally(() => {
|
|
render.compile();
|
|
scroll.resume();
|
|
|
|
return $q.resolve();
|
|
});
|
|
}
|
|
|
|
function menuLastRange () {
|
|
if (vm.isFollowing) {
|
|
lockFollow = true;
|
|
stopFollowing();
|
|
|
|
return $q.resolve();
|
|
}
|
|
|
|
lockFollow = false;
|
|
|
|
return lastRange()
|
|
.then(() => {
|
|
startFollowing();
|
|
|
|
return $q.resolve();
|
|
});
|
|
}
|
|
|
|
let followOnce;
|
|
let lockFollow;
|
|
function canStartFollowing () {
|
|
if (lockFollow) {
|
|
return false;
|
|
}
|
|
|
|
if (slide.isOnLastPage() && scroll.isBeyondLowerThreshold()) {
|
|
followOnce = false;
|
|
|
|
return true;
|
|
}
|
|
|
|
if (followOnce && // one-time activation from top of first page
|
|
scroll.isBeyondUpperThreshold() &&
|
|
slide.getTailCounter() - slide.getHeadCounter() >= OUTPUT_PAGE_SIZE) {
|
|
followOnce = false;
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function startFollowing () {
|
|
if (vm.isFollowing) {
|
|
return;
|
|
}
|
|
|
|
vm.isFollowing = true;
|
|
vm.followTooltip = vm.strings.get('tooltips.MENU_FOLLOWING');
|
|
}
|
|
|
|
function stopFollowing () {
|
|
if (!vm.isFollowing) {
|
|
return;
|
|
}
|
|
|
|
scroll.unlock();
|
|
scroll.unhide();
|
|
|
|
vm.isFollowing = false;
|
|
vm.followTooltip = vm.strings.get('tooltips.MENU_LAST');
|
|
}
|
|
|
|
//
|
|
// Menu Controls (Page Mode)
|
|
//
|
|
|
|
function firstPage () {
|
|
if (scroll.isPaused()) {
|
|
return $q.resolve();
|
|
}
|
|
|
|
scroll.pause();
|
|
|
|
return render.clear()
|
|
.then(() => page.getFirst())
|
|
.then(results => render.pushFront(results))
|
|
.then(() => page.getNext())
|
|
.then(results => {
|
|
const popCount = page.trimHead();
|
|
|
|
return render.popBack(popCount)
|
|
.then(() => render.pushFront(results));
|
|
})
|
|
.finally(() => {
|
|
render.compile();
|
|
scroll.resume();
|
|
|
|
return $q.resolve();
|
|
});
|
|
}
|
|
|
|
function lastPage () {
|
|
if (scroll.isPaused()) {
|
|
return $q.resolve();
|
|
}
|
|
|
|
scroll.pause();
|
|
|
|
return render.clear()
|
|
.then(() => page.getLast())
|
|
.then(results => render.pushBack(results))
|
|
.then(() => page.getPrevious())
|
|
.then(results => {
|
|
const popCount = page.trimTail();
|
|
|
|
return render.popFront(popCount)
|
|
.then(() => render.pushBack(results));
|
|
})
|
|
.then(() => {
|
|
scroll.scrollToBottom();
|
|
|
|
return $q.resolve();
|
|
})
|
|
.finally(() => {
|
|
render.compile();
|
|
scroll.resume();
|
|
|
|
return $q.resolve();
|
|
});
|
|
}
|
|
|
|
function nextPage () {
|
|
if (scroll.isPaused()) {
|
|
return $q.resolve();
|
|
}
|
|
|
|
scroll.pause();
|
|
|
|
return page.getNext()
|
|
.then(results => {
|
|
const popCount = page.trimHead();
|
|
|
|
return render.popBack(popCount)
|
|
.then(() => render.pushFront(results));
|
|
})
|
|
.finally(() => {
|
|
render.compile();
|
|
scroll.resume();
|
|
});
|
|
}
|
|
|
|
function previousPage () {
|
|
if (scroll.isPaused()) {
|
|
return $q.resolve();
|
|
}
|
|
|
|
scroll.pause();
|
|
|
|
let initialPosition;
|
|
let popHeight;
|
|
|
|
return page.getPrevious()
|
|
.then(results => {
|
|
const popCount = page.trimTail();
|
|
initialPosition = scroll.getScrollPosition();
|
|
|
|
return render.popFront(popCount)
|
|
.then(() => {
|
|
popHeight = scroll.getScrollHeight();
|
|
|
|
return render.pushBack(results);
|
|
});
|
|
})
|
|
.then(() => {
|
|
const currentHeight = scroll.getScrollHeight();
|
|
scroll.setScrollPosition(currentHeight - popHeight + initialPosition);
|
|
|
|
return $q.resolve();
|
|
})
|
|
.finally(() => {
|
|
render.compile();
|
|
scroll.resume();
|
|
|
|
return $q.resolve();
|
|
});
|
|
}
|
|
|
|
//
|
|
// Menu Controls
|
|
//
|
|
|
|
function first () {
|
|
if (vm.isProcessingFinished) {
|
|
return firstPage();
|
|
}
|
|
|
|
return firstRange();
|
|
}
|
|
|
|
function last () {
|
|
if (vm.isProcessingFinished) {
|
|
return lastPage();
|
|
}
|
|
|
|
return lastRange();
|
|
}
|
|
|
|
function next () {
|
|
if (vm.isProcessingFinished) {
|
|
return nextPage();
|
|
}
|
|
|
|
return nextRange();
|
|
}
|
|
|
|
function previous () {
|
|
if (vm.isProcessingFinished) {
|
|
return previousPage();
|
|
}
|
|
|
|
return previousRange();
|
|
}
|
|
|
|
function menuLast () {
|
|
if (vm.isProcessingFinished) {
|
|
return lastPage();
|
|
}
|
|
|
|
return menuLastRange();
|
|
}
|
|
|
|
function down () {
|
|
scroll.moveDown();
|
|
}
|
|
|
|
function up () {
|
|
scroll.moveUp();
|
|
}
|
|
|
|
function togglePanelExpand () {
|
|
vm.isPanelExpanded = !vm.isPanelExpanded;
|
|
}
|
|
|
|
//
|
|
// Line Interaction
|
|
//
|
|
|
|
const iconCollapsed = 'fa-angle-right';
|
|
const iconExpanded = 'fa-angle-down';
|
|
const iconSelector = '.at-Stdout-toggle > i';
|
|
const lineCollapsed = 'at-Stdout-row--hidden';
|
|
|
|
function toggleCollapseAll () {
|
|
if (scroll.isPaused()) return;
|
|
|
|
const records = Object.keys(render.records).map(key => render.records[key]);
|
|
const plays = records.filter(({ name }) => name === EVENT_START_PLAY);
|
|
const tasks = records.filter(({ name }) => name === EVENT_START_TASK);
|
|
|
|
const orphanLines = records
|
|
.filter(({ level }) => level === 3)
|
|
.filter(({ parents }) => !records[parents[0]]);
|
|
|
|
const orphanLineParents = orphanLines
|
|
.map(({ parents }) => ({ uuid: parents[0] }));
|
|
|
|
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.records[uuid];
|
|
|
|
if (record.name === EVENT_START_PLAY) {
|
|
togglePlayCollapse(uuid);
|
|
}
|
|
|
|
if (record.name === EVENT_START_TASK) {
|
|
toggleTaskCollapse(uuid);
|
|
}
|
|
}
|
|
|
|
function togglePlayCollapse (uuid) {
|
|
const record = render.records[uuid];
|
|
const descendants = record.children || [];
|
|
|
|
const icon = $(`#${uuid} ${iconSelector}`);
|
|
const lines = $(`.child-of-${uuid}`);
|
|
const taskIcons = $(`#${descendants.join(', #')}`).find(iconSelector);
|
|
|
|
const isCollapsed = icon.hasClass(iconCollapsed);
|
|
|
|
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 => $(`.child-of-${item}`))
|
|
.forEach(line => line.addClass(lineCollapsed));
|
|
}
|
|
|
|
descendants
|
|
.map(item => render.records[item])
|
|
.filter((descRecord) => descRecord && descRecord.name === EVENT_START_TASK)
|
|
.forEach(rec => { render.records[rec.uuid].isCollapsed = true; });
|
|
|
|
render.records[uuid].isCollapsed = !isCollapsed;
|
|
}
|
|
|
|
function toggleTaskCollapse (uuid) {
|
|
const icon = $(`#${uuid} ${iconSelector}`);
|
|
const lines = $(`.child-of-${uuid}`);
|
|
|
|
const isCollapsed = icon.hasClass(iconCollapsed);
|
|
|
|
if (isCollapsed) {
|
|
icon.removeClass(iconCollapsed);
|
|
icon.addClass(iconExpanded);
|
|
lines.removeClass(lineCollapsed);
|
|
} else {
|
|
icon.removeClass(iconExpanded);
|
|
icon.addClass(iconCollapsed);
|
|
lines.addClass(lineCollapsed);
|
|
}
|
|
|
|
render.records[uuid].isCollapsed = !isCollapsed;
|
|
}
|
|
|
|
function showHostDetails (id, uuid) {
|
|
$state.go('output.host-event.json', { eventId: id, taskUuid: uuid });
|
|
}
|
|
|
|
function showMissingEvents (uuid) {
|
|
const record = render.records[uuid];
|
|
|
|
const min = Math.min(...record.counters);
|
|
const max = Math.min(Math.max(...record.counters), min + OUTPUT_PAGE_SIZE);
|
|
|
|
const selector = `#${uuid}`;
|
|
const clicked = $(selector);
|
|
|
|
return resource.events.getRange([min, max])
|
|
.then(results => {
|
|
const counters = results.map(({ counter }) => counter);
|
|
|
|
for (let i = min; i <= max; i++) {
|
|
if (counters.indexOf(i) < 0) {
|
|
results = results.filter(({ counter }) => counter < i);
|
|
break;
|
|
}
|
|
}
|
|
|
|
let lines = 0;
|
|
let untrusted = '';
|
|
|
|
for (let i = 0; i <= results.length - 1; i++) {
|
|
const { html, count } = render.transformEvent(results[i]);
|
|
|
|
lines += count;
|
|
untrusted += html;
|
|
|
|
const shifted = render.records[uuid].counters.shift();
|
|
delete render.uuids[shifted];
|
|
}
|
|
|
|
const trusted = render.trustHtml(untrusted);
|
|
const elements = angular.element(trusted);
|
|
|
|
return render
|
|
.requestAnimationFrame(() => {
|
|
elements.insertBefore(clicked);
|
|
|
|
if (render.records[uuid].counters.length === 0) {
|
|
clicked.remove();
|
|
delete render.records[uuid];
|
|
}
|
|
})
|
|
.then(() => render.compile())
|
|
.then(() => lines);
|
|
});
|
|
}
|
|
|
|
//
|
|
// Event Handling
|
|
//
|
|
|
|
let streaming;
|
|
function stopListening () {
|
|
streaming = null;
|
|
|
|
listeners.forEach(deregister => deregister());
|
|
listeners.length = 0;
|
|
}
|
|
|
|
function startListening () {
|
|
stopListening();
|
|
|
|
listeners.push($scope.$on(resource.ws.events, (scope, data) => handleJobEvent(data)));
|
|
listeners.push($scope.$on(resource.ws.status, (scope, data) => handleStatusEvent(data)));
|
|
|
|
if (resource.model.get('type') === 'job') return;
|
|
if (resource.model.get('type') === 'project_update') return;
|
|
|
|
listeners.push($scope.$on(resource.ws.summary, (scope, data) => handleSummaryEvent(data)));
|
|
}
|
|
|
|
function handleJobEvent (data) {
|
|
streaming = streaming || resource.events
|
|
.getRange([Math.max(1, data.counter - 50), data.counter + 50])
|
|
.then(results => {
|
|
results.push(data);
|
|
|
|
const counters = results.map(({ counter }) => counter);
|
|
const min = Math.min(...counters);
|
|
const max = Math.max(...counters);
|
|
|
|
const missing = [];
|
|
for (let i = min; i <= max; i++) {
|
|
if (counters.indexOf(i) < 0) {
|
|
missing.push(i);
|
|
}
|
|
}
|
|
|
|
if (missing.length > 0) {
|
|
const maxMissing = Math.max(...missing);
|
|
results = results.filter(({ counter }) => counter > maxMissing);
|
|
}
|
|
|
|
results.forEach(item => {
|
|
stream.pushJobEvent(item);
|
|
status.pushJobEvent(item);
|
|
});
|
|
|
|
stream.setMissingCounterThreshold(min);
|
|
|
|
return $q.resolve();
|
|
});
|
|
|
|
streaming
|
|
.then(() => {
|
|
stream.pushJobEvent(data);
|
|
status.pushJobEvent(data);
|
|
});
|
|
}
|
|
|
|
function handleStatusEvent (data) {
|
|
status.pushStatusEvent(data);
|
|
}
|
|
|
|
function handleSummaryEvent (data) {
|
|
if (resource.model.get('id') !== data.unified_job_id) return;
|
|
if (!data.final_counter) return;
|
|
|
|
stream.setFinalCounter(data.final_counter);
|
|
}
|
|
|
|
//
|
|
// Search
|
|
//
|
|
|
|
function reloadState (params) {
|
|
params.isPanelExpanded = vm.isPanelExpanded;
|
|
|
|
return $state.transitionTo($state.current, params, { inherit: false, location: 'replace' });
|
|
}
|
|
|
|
//
|
|
// Debug Mode
|
|
//
|
|
|
|
function clear () {
|
|
stopListening();
|
|
render.clear();
|
|
|
|
followOnce = true;
|
|
lockFollow = false;
|
|
lockFrames = false;
|
|
|
|
stream.bufferInit();
|
|
status.init(resource);
|
|
slide.init(resource.events, render);
|
|
status.subscribe(data => { vm.status = data.status; });
|
|
|
|
startListening();
|
|
}
|
|
|
|
function OutputIndexController (
|
|
_$q_,
|
|
_$scope_,
|
|
_$state_,
|
|
_resource_,
|
|
_scroll_,
|
|
_page_,
|
|
_render_,
|
|
_status_,
|
|
_slide_,
|
|
_stream_,
|
|
$filter,
|
|
strings,
|
|
$stateParams,
|
|
) {
|
|
const { isPanelExpanded, _debug } = $stateParams;
|
|
const isProcessingFinished = !_debug && _resource_.model.get('event_processing_finished');
|
|
|
|
$q = _$q_;
|
|
$scope = _$scope_;
|
|
$state = _$state_;
|
|
|
|
resource = _resource_;
|
|
scroll = _scroll_;
|
|
render = _render_;
|
|
status = _status_;
|
|
stream = _stream_;
|
|
slide = _slide_;
|
|
page = _page_;
|
|
|
|
vm = this || {};
|
|
|
|
// Panel
|
|
vm.title = $filter('sanitize')(resource.model.get('name'));
|
|
vm.status = resource.model.get('status');
|
|
vm.strings = strings;
|
|
vm.resource = resource;
|
|
vm.reloadState = reloadState;
|
|
vm.isPanelExpanded = isPanelExpanded;
|
|
vm.isProcessingFinished = isProcessingFinished;
|
|
vm.togglePanelExpand = togglePanelExpand;
|
|
|
|
// Stdout Navigation
|
|
vm.menu = { last: menuLast, first, down, up, clear };
|
|
vm.isMenuCollapsed = false;
|
|
vm.isFollowing = false;
|
|
vm.toggleCollapseAll = toggleCollapseAll;
|
|
vm.toggleCollapse = toggleCollapse;
|
|
vm.showHostDetails = showHostDetails;
|
|
vm.showMissingEvents = showMissingEvents;
|
|
vm.toggleLineEnabled = resource.model.get('type') === 'job';
|
|
vm.followTooltip = vm.strings.get('tooltips.MENU_LAST');
|
|
vm.debug = _debug;
|
|
|
|
render.requestAnimationFrame(() => {
|
|
render.init($scope, { toggles: vm.toggleLineEnabled });
|
|
|
|
status.init(resource);
|
|
page.init(resource.events);
|
|
slide.init(resource.events, render);
|
|
|
|
scroll.init({
|
|
next,
|
|
previous,
|
|
onThresholdLeave () {
|
|
followOnce = false;
|
|
lockFollow = false;
|
|
stopFollowing();
|
|
|
|
return $q.resolve();
|
|
},
|
|
});
|
|
|
|
let showFollowTip = true;
|
|
const rates = [];
|
|
stream.init({
|
|
onFrames,
|
|
onFrameRate (rate) {
|
|
rates.push(rate);
|
|
rates.splice(0, rates.length - 5);
|
|
|
|
if (rates.every(value => value === 1)) {
|
|
scroll.unlock();
|
|
scroll.unhide();
|
|
}
|
|
|
|
if (rate > 1 && vm.isFollowing) {
|
|
scroll.lock();
|
|
scroll.hide();
|
|
|
|
if (showFollowTip) {
|
|
showFollowTip = false;
|
|
$(OUTPUT_ELEMENT_LAST).trigger('mouseenter');
|
|
}
|
|
}
|
|
},
|
|
onStop () {
|
|
lockFollow = true;
|
|
stopFollowing();
|
|
status.updateStats();
|
|
status.dispatch();
|
|
status.sync();
|
|
scroll.unlock();
|
|
scroll.unhide();
|
|
render.compile();
|
|
}
|
|
});
|
|
|
|
if (isProcessingFinished) {
|
|
followOnce = false;
|
|
lockFollow = true;
|
|
lockFrames = true;
|
|
stopListening();
|
|
} else {
|
|
followOnce = true;
|
|
lockFollow = false;
|
|
lockFrames = false;
|
|
resource.events.clearCache();
|
|
status.subscribe(data => { vm.status = data.status; });
|
|
startListening();
|
|
}
|
|
|
|
if (_debug) {
|
|
return render.clear();
|
|
}
|
|
|
|
return last();
|
|
});
|
|
|
|
$scope.$on('$destroy', () => {
|
|
stopListening();
|
|
|
|
render.clear();
|
|
render.el.remove();
|
|
slide.clear();
|
|
stream.bufferInit();
|
|
});
|
|
}
|
|
|
|
OutputIndexController.$inject = [
|
|
'$q',
|
|
'$scope',
|
|
'$state',
|
|
'resource',
|
|
'OutputScrollService',
|
|
'OutputPageService',
|
|
'OutputRenderService',
|
|
'OutputStatusService',
|
|
'OutputSlideService',
|
|
'OutputStreamService',
|
|
'$filter',
|
|
'OutputStrings',
|
|
'$stateParams',
|
|
];
|
|
|
|
module.exports = OutputIndexController;
|