Add WIP prepend/previous on scroll

This commit is contained in:
gconsidine
2018-01-23 17:05:59 -05:00
committed by Jake McDermott
parent 745e547e34
commit cc36ee6bed
3 changed files with 172 additions and 152 deletions

View File

@@ -10,6 +10,7 @@ let $timeout;
let $sce; let $sce;
let $compile; let $compile;
let $scope; let $scope;
let $q;
const record = {}; const record = {};
const meta = { const meta = {
@@ -18,7 +19,7 @@ const meta = {
const ROW_LIMIT = 200; const ROW_LIMIT = 200;
const SCROLL_BUFFER = 250; const SCROLL_BUFFER = 250;
const SCROLL_LOAD_DELAY = 100; // const SCROLL_LOAD_DELAY = 100;
const EVENT_START_TASK = 'playbook_on_task_start'; const EVENT_START_TASK = 'playbook_on_task_start';
const EVENT_START_PLAY = 'playbook_on_play_start'; const EVENT_START_PLAY = 'playbook_on_play_start';
const EVENT_STATS_PLAY = 'playbook_on_stats'; const EVENT_STATS_PLAY = 'playbook_on_stats';
@@ -36,11 +37,20 @@ const TIME_EVENTS = [
EVENT_STATS_PLAY EVENT_STATS_PLAY
]; ];
function JobsIndexController (_job_, JobEventModel, _$sce_, _$timeout_, _$scope_, _$compile_) { function JobsIndexController (
_job_,
JobEventModel,
_$sce_,
_$timeout_,
_$scope_,
_$compile_,
_$q_
) {
$timeout = _$timeout_; $timeout = _$timeout_;
$sce = _$sce_; $sce = _$sce_;
$compile = _$compile_; $compile = _$compile_;
$scope = _$scope_; $scope = _$scope_;
$q = _$q_;
job = _job_; job = _job_;
ansi = new Ansi(); ansi = new Ansi();
@@ -80,10 +90,6 @@ function JobsIndexController (_job_, JobEventModel, _$sce_, _$timeout_, _$scope_
table.html($sce.getTrustedHtml(html)); table.html($sce.getTrustedHtml(html));
$compile(table.contents())($scope); $compile(table.contents())($scope);
meta.next = job.get('related.job_events.next');
meta.prev = job.get('related.job_events.previous');
meta.cursor = job.get('related.job_events.results').length;
container.scroll(onScroll); container.scroll(onScroll);
}); });
} }
@@ -96,10 +102,13 @@ function next () {
} }
}; };
job.next(config) console.log('[2] getting next page');
.then(cursor => { return job.next(config)
meta.next = job.get('related.job_events.next'); .then(events => {
meta.prev = job.get('related.job_events.previous'); console.log(events);
if (!events) {
return $q.resolve();
}
console.log(ROW_LIMIT); console.log(ROW_LIMIT);
console.log(getRowCount()); console.log(getRowCount());
@@ -108,15 +117,21 @@ function next () {
console.log('above:', getRowsAbove()); console.log('above:', getRowsAbove());
console.log('below:', getRowsBelow()); console.log('below:', getRowsBelow());
append(cursor); return shift()
shift(); .then(() => append(events));
}); });
} }
function prev () { function prev () {
job.prev({ related: 'job_events' }) console.log('[2] getting previous page');
.then(cursor => { return job.prev({ related: 'job_events' })
console.log(cursor); .then(events => {
if (!events) {
return $q.resolve();
}
return pop()
.then(() => prepend(events));
}); });
} }
@@ -163,29 +178,66 @@ function getRowsInView () {
return Math.floor(viewHeight / rowHeight); return Math.floor(viewHeight / rowHeight);
} }
function append (cursor) { function append (events) {
const events = job.get('related.job_events.results').slice(cursor); console.log('[4] appending next page');
const rows = $($sce.getTrustedHtml($sce.trustAsHtml(parseEvents(events))));
const table = $(ELEMENT_TBODY);
table.append(rows); return $q(resolve => {
$compile(rows.contents())($scope); const rows = $($sce.getTrustedHtml($sce.trustAsHtml(parseEvents(events))));
const table = $(ELEMENT_TBODY);
table.append(rows);
$compile(rows.contents())($scope);
$timeout(() => {
resolve();
});
});
}
function prepend (events) {
console.log('[4] prepending next page');
return $q(resolve => {
const rows = $($sce.getTrustedHtml($sce.trustAsHtml(parseEvents(events))));
const table = $(ELEMENT_TBODY);
table.prepend(rows);
$compile(rows.contents())($scope);
$timeout(() => {
resolve();
});
});
}
function pop () {
console.log('[3] popping old page');
return $q(resolve => {
const count = getRowCount() - ROW_LIMIT;
const rows = $(ELEMENT_TBODY).children().slice(-count);
rows.empty();
rows.remove();
$timeout(() => {
resolve();
});
});
} }
/*
*function prepend (cursor) {
*
*}
*
*/
function shift () { function shift () {
const count = getRowCount() - ROW_LIMIT; console.log('[3] shifting old page');
const rows = $(ELEMENT_TBODY).children().slice(0, count); return $q(resolve => {
const count = getRowCount() - ROW_LIMIT;
const rows = $(ELEMENT_TBODY).children().slice(0, count);
console.log(count, rows); rows.empty();
rows.remove();
rows.empty(); $timeout(() => {
rows.remove(); resolve();
});
});
} }
function expand () { function expand () {
@@ -419,28 +471,43 @@ function onScroll () {
meta.scroll.inProgress = true; meta.scroll.inProgress = true;
$timeout(() => { const top = container[0].scrollTop;
const top = container[0].scrollTop; const bottom = top + SCROLL_BUFFER + container[0].offsetHeight;
const bottom = top + SCROLL_BUFFER + container[0].offsetHeight;
meta.scroll.inProgress = false; if (top === 0) {
console.log('[1] scroll to top');
vm.menu.scroll.display = false;
if (top === 0) { prev()
vm.menu.scroll.display = false; .then(() => {
console.log('[5] scroll reset');
meta.scroll.inProgress = false;
});
prev(); return;
}
return; vm.menu.scroll.display = true;
}
vm.menu.scroll.display = true; if (bottom >= container[0].scrollHeight) {
console.log('[1] scroll to bottom');
if (bottom >= container[0].scrollHeight && meta.next) { next()
next(); .then(() => {
} console.log('[5] scroll reset');
}, SCROLL_LOAD_DELAY); meta.scroll.inProgress = false;
});
}
} }
JobsIndexController.$inject = ['job', 'JobEventModel', '$sce', '$timeout', '$scope', '$compile']; JobsIndexController.$inject = [
'job',
'JobEventModel',
'$sce',
'$timeout',
'$scope',
'$compile',
'$q'
];
module.exports = JobsIndexController; module.exports = JobsIndexController;

View File

@@ -35,9 +35,9 @@ function JobsRun ($stateExtender, strings) {
return new Jobs('get', id) return new Jobs('get', id)
.then(job => job.extend('job_events', { .then(job => job.extend('job_events', {
pageCache: true, pageCache: true,
pageLimit: 2, pageLimit: 4,
params: { params: {
page_size: 1000, page_size: 100,
order_by: 'start_line' order_by: 'start_line'
}, },
})); }));

View File

@@ -110,11 +110,17 @@ function httpGet (config = {}) {
this.page.current = 1; this.page.current = 1;
if (config.pageCache) { if (config.pageCache) {
this.page.cache = { this.page.cachedPages = this.page.cachedPages || {};
root: {} this.page.cache = this.page.cache || {};
};
this.page.limit = config.pageLimit || false; this.page.limit = config.pageLimit || false;
if (!_.has(this.page.cachedPages, 'root')) {
this.page.cachedPages.root = [];
}
if (!_.has(this.page.cache, 'root')) {
this.page.cache.root = {};
}
} }
} }
} }
@@ -132,7 +138,10 @@ function httpGet (config = {}) {
this.model.GET = res.data; this.model.GET = res.data;
if (config.pageCache) { if (config.pageCache) {
this.page.cache[this.page.current] = res.data.results; this.page.cache.root[this.page.current] = res.data.results;
this.page.cachedPages.root.push(this.page.current);
this.page.count = res.data.count;
this.page.last = Math.ceil(res.data.count / this.page.size);
} }
return res; return res;
@@ -352,8 +361,17 @@ function extend (related, config) {
this.page.current = 1; this.page.current = 1;
if (config.pageCache) { if (config.pageCache) {
this.page.cachedPages = this.page.cachedPages || {};
this.page.cache = this.page.cache || {}; this.page.cache = this.page.cache || {};
this.page.limit = config.pageLimit || false; this.page.limit = config.pageLimit || false;
if (!_.has(this.page.cachedPages, `related.${related}`)) {
_.set(this.page.cachedPages, `related.${related}`, []);
}
if (!_.has(this.page.cache, `related.${related}`)) {
_.set(this.page.cache, `related.${related}`, []);
}
} }
} }
@@ -367,9 +385,10 @@ function extend (related, config) {
this.set(req.method, `related.${related}`, data); this.set(req.method, `related.${related}`, data);
if (config.pageCache) { if (config.pageCache) {
const key = `related.${related}.${this.page.current}`; this.page.cache.related[related][this.page.current] = data.results;
this.page.cachedPages.related[related].push(this.page.current);
_.set(this.page.cache, key, data.results); this.page.count = data.count;
this.page.last = Math.ceil(data.count / this.page.size);
} }
return this; return this;
@@ -383,16 +402,15 @@ function goToPage (config, page) {
const params = config.params || {}; const params = config.params || {};
let url; let url;
let count;
let key; let key;
let pageNumber; let pageNumber;
let pageCache;
let pagesInCache;
if (config.related) { if (config.related) {
count = this.get(`related.${config.related}.count`);
url = `${this.endpoint}${config.related}/`; url = `${this.endpoint}${config.related}/`;
key = `related.${config.related}`; key = `related.${config.related}`;
} else { } else {
count = this.get('count');
url = this.endpoint; url = this.endpoint;
key = 'root'; key = 'root';
} }
@@ -400,29 +418,34 @@ function goToPage (config, page) {
params.page_size = this.page.size; params.page_size = this.page.size;
if (page === 'next') { if (page === 'next') {
// if (at max)
pageNumber = this.page.current + 1; pageNumber = this.page.current + 1;
} else if (page === 'previous') { } else if (page === 'previous') {
// if (at min)
pageNumber = this.page.current - 1; pageNumber = this.page.current - 1;
} else if (page === 'first') { } else if (page === 'first') {
// if (at min)
pageNumber = 1; pageNumber = 1;
} else if (page === 'last') { } else if (page === 'last') {
// if (at min) pageNumber = this.page.last;
} else {
pageNumber = Math.floor(count / this.page.size);
} else if (typeof pageNumber === 'number') {
pageNumber = page; pageNumber = page;
} }
if (this.page.cache && this.page.cache[pageNumber]) { this.page.current = pageNumber;
return Promise.resolve(this.page.cache[pageNumber]);
if (pageNumber < 1 || pageNumber > this.page.last) {
return Promise.resolve(null);
}
if (this.page.cache) {
pageCache = _.get(this.page.cache, key);
pagesInCache = _.get(this.page.cachedPages, key);
if (_.has(pageCache, pageNumber)) {
return Promise.resolve(pageCache[pageNumber]);
}
} }
params.page_size = this.page.size; params.page_size = this.page.size;
params.page = this.page.current; params.page = pageNumber;
const req = { const req = {
method: 'GET', method: 'GET',
@@ -432,98 +455,28 @@ function goToPage (config, page) {
return $http(req) return $http(req)
.then(({ data }) => { .then(({ data }) => {
if (this.page.cache) { if (pageCache) {
_.set(this.page.cache, `${key}.${pageNumber}`, data.results); pageCache[pageNumber] = data.results;
pagesInCache.push(pageNumber);
if (pagesInCache.length > this.page.limit) {
const pageToDelete = pagesInCache.shift();
delete pageCache[pageToDelete];
}
} }
console.log('cache', this.page.cache); return data.results;
}); });
} }
function next (config = {}) { function next (config = {}) {
return this.goToPage(config, 'next'); return this.goToPage(config, 'next');
/*
* .then(({ data }) => {
* let cursor = 0;
*
* if (this.pageCache) {
* results = results || [];
* data.results = results.concat(data.results);
* cursor = results.length;
*
* if (this.pageLimit && this.pageLimit * this.pageSize < data.results.length) {
* const removeCount = data.results.length - this.pageLimit * this.pageSize;
*
* data.results.splice(0, removeCount);
* cursor -= removeCount;
* }
* }
*
* if (config.related) {
* this.set('get', `related.${config.related}`, data);
* } else {
* this.set('get', data);
* }
*
* this.page.current++;
*
* return cursor <= 0 ? 0 : cursor;
* });
*/
} }
function prev (config = {}) { function prev (config = {}) {
return this.goToPage(config, 'prev'); return this.goToPage(config, 'previous');
} }
/*
* let url;
* let results;
*
* console.log(config, config.cursor)
* if (config.related) {
* url = this.get(`related.${config.related}.next`);
* results = this.get(`related.${config.related}.results`) || [];
* } else {
* url = this.get('next');
* results = this.get('results');
* }
*
* if (!url) {
* return Promise.resolve(null);
* }
*
* const req = {
* method: 'GET',
* url
* };
*
* return $http(req)
* .then(({ data }) => {
* let cursor = 0;
*
* if (this.pageCache) {
* results = results || [];
* data.results = results.concat(data.results);
* cursor = results.length;
*
* if (this.pageLimit && this.pageLimit * this.pageSize < data.results.length) {
* const removeCount = data.results.length - this.pageLimit * this.pageSize;
*
* data.results.splice(0, removeCount);
* cursor -= removeCount;
* }
* }
*
* if (config.related) {
* this.set('get', `related.${config.related}`, data);
* } else {
* this.set('get', data);
* }
*
* return cursor <= 0 ? 0 : cursor;
* });
*}
*/
function normalizePath (resource) { function normalizePath (resource) {
const version = '/api/v2/'; const version = '/api/v2/';