mirror of
https://github.com/ansible/awx.git
synced 2026-02-28 08:18:43 -03:30
Merge pull request #2306 from jakemcdermott/job-results/static-pager
improve job output search
This commit is contained in:
@@ -14,10 +14,22 @@ function JobEventsApiService ($http, $q) {
|
|||||||
this.endpoint = endpoint;
|
this.endpoint = endpoint;
|
||||||
this.params = merge(BASE_PARAMS, params);
|
this.params = merge(BASE_PARAMS, params);
|
||||||
|
|
||||||
this.state = { current: 0, count: 0 };
|
this.state = { count: 0, maxCounter: 0 };
|
||||||
|
this.cache = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
this.fetch = () => this.getLast().then(() => this);
|
this.clearCache = () => {
|
||||||
|
Object.keys(this.cache).forEach(key => {
|
||||||
|
delete this.cache[key];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
this.fetch = () => this.getLast()
|
||||||
|
.then(results => {
|
||||||
|
this.cache.last = results;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
});
|
||||||
|
|
||||||
this.getFirst = () => {
|
this.getFirst = () => {
|
||||||
const page = 1;
|
const page = 1;
|
||||||
@@ -26,14 +38,72 @@ function JobEventsApiService ($http, $q) {
|
|||||||
return $http.get(this.endpoint, { params })
|
return $http.get(this.endpoint, { params })
|
||||||
.then(({ data }) => {
|
.then(({ data }) => {
|
||||||
const { results, count } = data;
|
const { results, count } = data;
|
||||||
|
const maxCounter = Math.max(...results.map(({ counter }) => counter));
|
||||||
|
|
||||||
this.state.count = count;
|
this.state.count = count;
|
||||||
this.state.current = page;
|
|
||||||
|
if (maxCounter > this.state.maxCounter) {
|
||||||
|
this.state.maxCounter = maxCounter;
|
||||||
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.getPage = number => {
|
||||||
|
if (number < 1 || number > this.getLastPageNumber()) {
|
||||||
|
return $q.resolve([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const params = merge(this.params, { page: number });
|
||||||
|
|
||||||
|
return $http.get(this.endpoint, { params })
|
||||||
|
.then(({ data }) => {
|
||||||
|
const { results, count } = data;
|
||||||
|
const maxCounter = Math.max(...results.map(({ counter }) => counter));
|
||||||
|
|
||||||
|
this.state.count = count;
|
||||||
|
|
||||||
|
if (maxCounter > this.state.maxCounter) {
|
||||||
|
this.state.maxCounter = maxCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getLast = () => {
|
||||||
|
if (this.cache.last) {
|
||||||
|
return $q.resolve(this.cache.last);
|
||||||
|
}
|
||||||
|
|
||||||
|
const params = merge(this.params, { page: 1, order_by: `-${ORDER_BY}` });
|
||||||
|
|
||||||
|
return $http.get(this.endpoint, { params })
|
||||||
|
.then(({ data }) => {
|
||||||
|
const { results, count } = data;
|
||||||
|
const maxCounter = Math.max(...results.map(({ counter }) => counter));
|
||||||
|
|
||||||
|
let rotated = results;
|
||||||
|
|
||||||
|
if (count > PAGE_SIZE) {
|
||||||
|
rotated = results.splice(count % PAGE_SIZE);
|
||||||
|
|
||||||
|
if (results.length > 0) {
|
||||||
|
rotated = results;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.state.count = count;
|
||||||
|
|
||||||
|
if (maxCounter > this.state.maxCounter) {
|
||||||
|
this.state.maxCounter = maxCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rotated;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
this.getRange = range => {
|
this.getRange = range => {
|
||||||
if (!range) {
|
if (!range) {
|
||||||
return $q.resolve([]);
|
return $q.resolve([]);
|
||||||
@@ -47,46 +117,18 @@ function JobEventsApiService ($http, $q) {
|
|||||||
return $http.get(this.endpoint, { params })
|
return $http.get(this.endpoint, { params })
|
||||||
.then(({ data }) => {
|
.then(({ data }) => {
|
||||||
const { results } = data;
|
const { results } = data;
|
||||||
const maxCounter = Math.max(results.map(({ counter }) => counter));
|
const maxCounter = Math.max(...results.map(({ counter }) => counter));
|
||||||
|
|
||||||
this.state.current = Math.ceil(maxCounter / PAGE_SIZE);
|
if (maxCounter > this.state.maxCounter) {
|
||||||
|
this.state.maxCounter = maxCounter;
|
||||||
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getLast = () => {
|
|
||||||
const params = merge(this.params, { page: 1, order_by: `-${ORDER_BY}` });
|
|
||||||
|
|
||||||
return $http.get(this.endpoint, { params })
|
|
||||||
.then(({ data }) => {
|
|
||||||
const { results } = data;
|
|
||||||
const count = Math.max(...results.map(({ counter }) => counter));
|
|
||||||
|
|
||||||
let rotated = results;
|
|
||||||
|
|
||||||
if (count > PAGE_SIZE) {
|
|
||||||
rotated = results.splice(count % PAGE_SIZE);
|
|
||||||
|
|
||||||
if (results.length > 0) {
|
|
||||||
rotated = results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.state.count = count;
|
|
||||||
this.state.current = Math.ceil(count / PAGE_SIZE);
|
|
||||||
|
|
||||||
return rotated;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getCurrentPageNumber = () => this.state.current;
|
|
||||||
this.getLastPageNumber = () => Math.ceil(this.state.count / PAGE_SIZE);
|
this.getLastPageNumber = () => Math.ceil(this.state.count / PAGE_SIZE);
|
||||||
this.getPreviousPageNumber = () => Math.max(1, this.state.current - 1);
|
this.getMaxCounter = () => this.state.maxCounter;
|
||||||
this.getNextPageNumber = () => Math.min(this.state.current + 1, this.getLastPageNumber());
|
|
||||||
this.getMaxCounter = () => this.state.count;
|
|
||||||
|
|
||||||
this.getNext = () => this.getPage(this.getNextPageNumber());
|
|
||||||
this.getPrevious = () => this.getPage(this.getPreviousPageNumber());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JobEventsApiService.$inject = ['$http', '$q'];
|
JobEventsApiService.$inject = ['$http', '$q'];
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ function first () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function next () {
|
function next () {
|
||||||
return slide.slideDown();
|
return slide.getNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
function previous () {
|
function previous () {
|
||||||
@@ -100,7 +100,7 @@ function previous () {
|
|||||||
|
|
||||||
const initialPosition = scroll.getScrollPosition();
|
const initialPosition = scroll.getScrollPosition();
|
||||||
|
|
||||||
return slide.slideUp()
|
return slide.getPrevious()
|
||||||
.then(popHeight => {
|
.then(popHeight => {
|
||||||
const currentHeight = scroll.getScrollHeight();
|
const currentHeight = scroll.getScrollHeight();
|
||||||
scroll.setScrollPosition(currentHeight - popHeight + initialPosition);
|
scroll.setScrollPosition(currentHeight - popHeight + initialPosition);
|
||||||
@@ -255,6 +255,7 @@ function OutputIndexController (
|
|||||||
_$state_,
|
_$state_,
|
||||||
_resource_,
|
_resource_,
|
||||||
_scroll_,
|
_scroll_,
|
||||||
|
_page_,
|
||||||
_render_,
|
_render_,
|
||||||
_status_,
|
_status_,
|
||||||
_slide_,
|
_slide_,
|
||||||
@@ -263,6 +264,8 @@ function OutputIndexController (
|
|||||||
strings,
|
strings,
|
||||||
$stateParams,
|
$stateParams,
|
||||||
) {
|
) {
|
||||||
|
const { isPanelExpanded } = $stateParams;
|
||||||
|
|
||||||
$compile = _$compile_;
|
$compile = _$compile_;
|
||||||
$q = _$q_;
|
$q = _$q_;
|
||||||
$scope = _$scope_;
|
$scope = _$scope_;
|
||||||
@@ -271,9 +274,9 @@ function OutputIndexController (
|
|||||||
resource = _resource_;
|
resource = _resource_;
|
||||||
scroll = _scroll_;
|
scroll = _scroll_;
|
||||||
render = _render_;
|
render = _render_;
|
||||||
slide = _slide_;
|
|
||||||
status = _status_;
|
status = _status_;
|
||||||
stream = _stream_;
|
stream = _stream_;
|
||||||
|
slide = resource.model.get('event_processing_finished') ? _page_ : _slide_;
|
||||||
|
|
||||||
vm = this || {};
|
vm = this || {};
|
||||||
|
|
||||||
@@ -281,8 +284,6 @@ function OutputIndexController (
|
|||||||
vm.title = $filter('sanitize')(resource.model.get('name'));
|
vm.title = $filter('sanitize')(resource.model.get('name'));
|
||||||
vm.strings = strings;
|
vm.strings = strings;
|
||||||
vm.resource = resource;
|
vm.resource = resource;
|
||||||
|
|
||||||
const { isPanelExpanded } = $stateParams;
|
|
||||||
vm.reloadState = reloadState;
|
vm.reloadState = reloadState;
|
||||||
vm.isPanelExpanded = isPanelExpanded;
|
vm.isPanelExpanded = isPanelExpanded;
|
||||||
vm.togglePanelExpand = togglePanelExpand;
|
vm.togglePanelExpand = togglePanelExpand;
|
||||||
@@ -334,6 +335,7 @@ OutputIndexController.$inject = [
|
|||||||
'$state',
|
'$state',
|
||||||
'resource',
|
'resource',
|
||||||
'OutputScrollService',
|
'OutputScrollService',
|
||||||
|
'OutputPageService',
|
||||||
'OutputRenderService',
|
'OutputRenderService',
|
||||||
'OutputStatusService',
|
'OutputStatusService',
|
||||||
'OutputSlideService',
|
'OutputSlideService',
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import StreamService from '~features/output/stream.service';
|
|||||||
import StatusService from '~features/output/status.service';
|
import StatusService from '~features/output/status.service';
|
||||||
import MessageService from '~features/output/message.service';
|
import MessageService from '~features/output/message.service';
|
||||||
import EventsApiService from '~features/output/api.events.service';
|
import EventsApiService from '~features/output/api.events.service';
|
||||||
|
import PageService from '~features/output/page.service';
|
||||||
import SlideService from '~features/output/slide.service';
|
import SlideService from '~features/output/slide.service';
|
||||||
import LegacyRedirect from '~features/output/legacy.route';
|
import LegacyRedirect from '~features/output/legacy.route';
|
||||||
|
|
||||||
@@ -108,11 +109,6 @@ function resolveResource (
|
|||||||
status: `${WS_PREFIX}-${name}`,
|
status: `${WS_PREFIX}-${name}`,
|
||||||
summary: `${WS_PREFIX}-${name}-summary`,
|
summary: `${WS_PREFIX}-${name}-summary`,
|
||||||
},
|
},
|
||||||
page: {
|
|
||||||
cache: PAGE_CACHE,
|
|
||||||
size: PAGE_SIZE,
|
|
||||||
pageLimit: PAGE_LIMIT
|
|
||||||
}
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (!handleErrors) {
|
if (!handleErrors) {
|
||||||
@@ -250,6 +246,7 @@ angular
|
|||||||
.service('OutputStatusService', StatusService)
|
.service('OutputStatusService', StatusService)
|
||||||
.service('OutputMessageService', MessageService)
|
.service('OutputMessageService', MessageService)
|
||||||
.service('JobEventsApiService', EventsApiService)
|
.service('JobEventsApiService', EventsApiService)
|
||||||
|
.service('OutputPageService', PageService)
|
||||||
.service('OutputSlideService', SlideService)
|
.service('OutputSlideService', SlideService)
|
||||||
.component('atJobSearch', SearchComponent)
|
.component('atJobSearch', SearchComponent)
|
||||||
.component('atJobStats', StatsComponent)
|
.component('atJobStats', StatsComponent)
|
||||||
|
|||||||
239
awx/ui/client/features/output/page.service.js
Normal file
239
awx/ui/client/features/output/page.service.js
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
/* eslint camelcase: 0 */
|
||||||
|
const PAGE_LIMIT = 5;
|
||||||
|
|
||||||
|
function PageService ($q) {
|
||||||
|
this.init = (storage, api, { getScrollHeight }) => {
|
||||||
|
const { prepend, append, shift, pop, deleteRecord } = storage;
|
||||||
|
const { getPage, getFirst, getLast, getLastPageNumber } = api;
|
||||||
|
|
||||||
|
this.api = {
|
||||||
|
getPage,
|
||||||
|
getFirst,
|
||||||
|
getLast,
|
||||||
|
getLastPageNumber,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.storage = {
|
||||||
|
prepend,
|
||||||
|
append,
|
||||||
|
shift,
|
||||||
|
pop,
|
||||||
|
deleteRecord,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.hooks = {
|
||||||
|
getScrollHeight,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.records = {};
|
||||||
|
this.uuids = {};
|
||||||
|
this.state = {
|
||||||
|
head: 0,
|
||||||
|
tail: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.chain = $q.resolve();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.pushFront = results => {
|
||||||
|
if (!results) {
|
||||||
|
return $q.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.storage.append(results)
|
||||||
|
.then(() => {
|
||||||
|
this.records[++this.state.tail] = {};
|
||||||
|
results.forEach(({ counter, start_line, end_line, uuid }) => {
|
||||||
|
this.records[this.state.tail][counter] = { start_line, end_line };
|
||||||
|
this.uuids[counter] = uuid;
|
||||||
|
});
|
||||||
|
|
||||||
|
return $q.resolve();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
this.pushBack = results => {
|
||||||
|
if (!results) {
|
||||||
|
return $q.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.storage.prepend(results)
|
||||||
|
.then(() => {
|
||||||
|
this.records[--this.state.head] = {};
|
||||||
|
results.forEach(({ counter, start_line, end_line, uuid }) => {
|
||||||
|
this.records[this.state.head][counter] = { start_line, end_line };
|
||||||
|
this.uuids[counter] = uuid;
|
||||||
|
});
|
||||||
|
|
||||||
|
return $q.resolve();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
this.popBack = () => {
|
||||||
|
if (this.getRecordCount() === 0) {
|
||||||
|
return $q.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageRecord = this.records[this.state.head] || {};
|
||||||
|
|
||||||
|
let lines = 0;
|
||||||
|
const counters = [];
|
||||||
|
|
||||||
|
Object.keys(pageRecord)
|
||||||
|
.forEach(counter => {
|
||||||
|
lines += pageRecord[counter].end_line - pageRecord[counter].start_line;
|
||||||
|
counters.push(counter);
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.storage.shift(lines)
|
||||||
|
.then(() => {
|
||||||
|
counters.forEach(counter => {
|
||||||
|
this.storage.deleteRecord(this.uuids[counter]);
|
||||||
|
delete this.uuids[counter];
|
||||||
|
});
|
||||||
|
|
||||||
|
delete this.records[this.state.head++];
|
||||||
|
|
||||||
|
return $q.resolve();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
this.popFront = () => {
|
||||||
|
if (this.getRecordCount() === 0) {
|
||||||
|
return $q.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageRecord = this.records[this.state.tail] || {};
|
||||||
|
|
||||||
|
let lines = 0;
|
||||||
|
const counters = [];
|
||||||
|
|
||||||
|
Object.keys(pageRecord)
|
||||||
|
.forEach(counter => {
|
||||||
|
lines += pageRecord[counter].end_line - pageRecord[counter].start_line;
|
||||||
|
counters.push(counter);
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.storage.pop(lines)
|
||||||
|
.then(() => {
|
||||||
|
counters.forEach(counter => {
|
||||||
|
this.storage.deleteRecord(this.uuids[counter]);
|
||||||
|
delete this.uuids[counter];
|
||||||
|
});
|
||||||
|
|
||||||
|
delete this.records[this.state.tail--];
|
||||||
|
|
||||||
|
return $q.resolve();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getNext = () => {
|
||||||
|
const lastPageNumber = this.api.getLastPageNumber();
|
||||||
|
const number = Math.min(this.state.tail + 1, lastPageNumber);
|
||||||
|
|
||||||
|
const isLoaded = (number >= this.state.head && number <= this.state.tail);
|
||||||
|
const isValid = (number >= 1 && number <= lastPageNumber);
|
||||||
|
|
||||||
|
let popHeight = this.hooks.getScrollHeight();
|
||||||
|
|
||||||
|
if (!isValid || isLoaded) {
|
||||||
|
this.chain = this.chain
|
||||||
|
.then(() => $q.resolve(popHeight));
|
||||||
|
|
||||||
|
return this.chain;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageCount = this.state.head - this.state.tail;
|
||||||
|
|
||||||
|
if (pageCount >= PAGE_LIMIT) {
|
||||||
|
this.chain = this.chain
|
||||||
|
.then(() => this.popBack())
|
||||||
|
.then(() => {
|
||||||
|
popHeight = this.hooks.getScrollHeight();
|
||||||
|
|
||||||
|
return $q.resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.chain = this.chain
|
||||||
|
.then(() => this.api.getPage(number))
|
||||||
|
.then(events => this.pushFront(events))
|
||||||
|
.then(() => $q.resolve(popHeight));
|
||||||
|
|
||||||
|
return this.chain;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getPrevious = () => {
|
||||||
|
const number = Math.max(this.state.head - 1, 1);
|
||||||
|
|
||||||
|
const isLoaded = (number >= this.state.head && number <= this.state.tail);
|
||||||
|
const isValid = (number >= 1 && number <= this.api.getLastPageNumber());
|
||||||
|
|
||||||
|
let popHeight = this.hooks.getScrollHeight();
|
||||||
|
|
||||||
|
if (!isValid || isLoaded) {
|
||||||
|
this.chain = this.chain
|
||||||
|
.then(() => $q.resolve(popHeight));
|
||||||
|
|
||||||
|
return this.chain;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageCount = this.state.head - this.state.tail;
|
||||||
|
|
||||||
|
if (pageCount >= PAGE_LIMIT) {
|
||||||
|
this.chain = this.chain
|
||||||
|
.then(() => this.popFront())
|
||||||
|
.then(() => {
|
||||||
|
popHeight = this.hooks.getScrollHeight();
|
||||||
|
|
||||||
|
return $q.resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.chain = this.chain
|
||||||
|
.then(() => this.api.getPage(number))
|
||||||
|
.then(events => this.pushBack(events))
|
||||||
|
.then(() => $q.resolve(popHeight));
|
||||||
|
|
||||||
|
return this.chain;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.clear = () => {
|
||||||
|
const count = this.getRecordCount();
|
||||||
|
|
||||||
|
for (let i = 0; i <= count; ++i) {
|
||||||
|
this.chain = this.chain.then(() => this.popBack());
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.chain;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getLast = () => this.clear()
|
||||||
|
.then(() => this.api.getLast())
|
||||||
|
.then(events => {
|
||||||
|
const lastPage = this.api.getLastPageNumber();
|
||||||
|
|
||||||
|
this.state.head = lastPage;
|
||||||
|
this.state.tail = lastPage;
|
||||||
|
|
||||||
|
return this.pushBack(events);
|
||||||
|
})
|
||||||
|
.then(() => this.getPrevious());
|
||||||
|
|
||||||
|
this.getFirst = () => this.clear()
|
||||||
|
.then(() => this.api.getFirst())
|
||||||
|
.then(events => {
|
||||||
|
this.state.head = 1;
|
||||||
|
this.state.tail = 1;
|
||||||
|
|
||||||
|
return this.pushBack(events);
|
||||||
|
})
|
||||||
|
.then(() => this.getNext());
|
||||||
|
|
||||||
|
this.getRecordCount = () => Object.keys(this.records).length;
|
||||||
|
this.getTailCounter = () => this.state.tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
PageService.$inject = ['$q'];
|
||||||
|
|
||||||
|
export default PageService;
|
||||||
@@ -77,7 +77,6 @@ function submitSearch () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const searchInputQueryset = qs.getSearchInputQueryset(vm.value, isFilterable);
|
const searchInputQueryset = qs.getSearchInputQueryset(vm.value, isFilterable);
|
||||||
|
|
||||||
const modifiedQueryset = qs.mergeQueryset(currentQueryset, searchInputQueryset);
|
const modifiedQueryset = qs.mergeQueryset(currentQueryset, searchInputQueryset);
|
||||||
|
|
||||||
reloadQueryset(modifiedQueryset, strings.get('search.REJECT_INVALID'));
|
reloadQueryset(modifiedQueryset, strings.get('search.REJECT_INVALID'));
|
||||||
|
|||||||
@@ -58,6 +58,23 @@ function getOverlapArray (range, other) {
|
|||||||
return [range[0] - other[0], other[1] - range[1]];
|
return [range[0] - other[0], other[1] - range[1]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply a minimum and maximum boundary to a range.
|
||||||
|
*
|
||||||
|
* @arg {Array} range - A [low, high] range array.
|
||||||
|
* @arg {Array} other - A [low, high] range array to be applied as a boundary.
|
||||||
|
*
|
||||||
|
* @returns {(Array)} - Returns a new range array by applying the second range
|
||||||
|
* as a boundary to the first.
|
||||||
|
*
|
||||||
|
* getBoundedRange([2, 6], [2, 8]) = [2, 6]
|
||||||
|
* getBoundedRange([1, 9], [2, 8]) = [2, 8]
|
||||||
|
* getBoundedRange([4, 9], [2, 8]) = [4, 8]
|
||||||
|
*/
|
||||||
|
function getBoundedRange (range, other) {
|
||||||
|
return [Math.max(range[0], other[0]), Math.min(range[1], other[1])];
|
||||||
|
}
|
||||||
|
|
||||||
function SlidingWindowService ($q) {
|
function SlidingWindowService ($q) {
|
||||||
this.init = (storage, api, { getScrollHeight }) => {
|
this.init = (storage, api, { getScrollHeight }) => {
|
||||||
const { prepend, append, shift, pop, deleteRecord } = storage;
|
const { prepend, append, shift, pop, deleteRecord } = storage;
|
||||||
@@ -67,7 +84,7 @@ function SlidingWindowService ($q) {
|
|||||||
getMaxCounter,
|
getMaxCounter,
|
||||||
getRange,
|
getRange,
|
||||||
getFirst,
|
getFirst,
|
||||||
getLast
|
getLast,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.storage = {
|
this.storage = {
|
||||||
@@ -85,6 +102,8 @@ function SlidingWindowService ($q) {
|
|||||||
this.records = {};
|
this.records = {};
|
||||||
this.uuids = {};
|
this.uuids = {};
|
||||||
this.chain = $q.resolve();
|
this.chain = $q.resolve();
|
||||||
|
|
||||||
|
api.clearCache();
|
||||||
};
|
};
|
||||||
|
|
||||||
this.pushFront = events => {
|
this.pushFront = events => {
|
||||||
@@ -176,47 +195,54 @@ function SlidingWindowService ($q) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getBoundedRange = ([low, high]) => {
|
|
||||||
const bounds = [1, this.getMaxCounter()];
|
|
||||||
|
|
||||||
return [Math.max(low, bounds[0]), Math.min(high, bounds[1])];
|
|
||||||
};
|
|
||||||
|
|
||||||
this.move = ([low, high]) => {
|
this.move = ([low, high]) => {
|
||||||
const [head, tail] = this.getRange();
|
const bounds = [1, this.getMaxCounter()];
|
||||||
const [newHead, newTail] = this.getBoundedRange([low, high]);
|
const [newHead, newTail] = getBoundedRange([low, high], bounds);
|
||||||
|
|
||||||
|
let popHeight = this.hooks.getScrollHeight();
|
||||||
|
|
||||||
if (newHead > newTail) {
|
if (newHead > newTail) {
|
||||||
return $q.resolve([0, 0]);
|
this.chain = this.chain
|
||||||
|
.then(() => $q.resolve(popHeight));
|
||||||
|
|
||||||
|
return this.chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Number.isFinite(newHead) || !Number.isFinite(newTail)) {
|
if (!Number.isFinite(newHead) || !Number.isFinite(newTail)) {
|
||||||
return $q.resolve([0, 0]);
|
this.chain = this.chain
|
||||||
|
.then(() => $q.resolve(popHeight));
|
||||||
|
|
||||||
|
return this.chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const [head, tail] = this.getRange();
|
||||||
const overlap = getOverlapArray([head, tail], [newHead, newTail]);
|
const overlap = getOverlapArray([head, tail], [newHead, newTail]);
|
||||||
|
|
||||||
if (!overlap) {
|
if (!overlap) {
|
||||||
this.chain = this.chain
|
this.chain = this.chain
|
||||||
.then(() => this.popBack(this.getRecordCount()))
|
.then(() => this.clear())
|
||||||
.then(() => this.api.getRange([newHead, newTail]))
|
.then(() => this.api.getRange([newHead, newTail]))
|
||||||
.then(events => this.pushFront(events));
|
.then(events => this.pushFront(events));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (overlap && overlap[0] < 0) {
|
if (overlap && overlap[0] < 0) {
|
||||||
this.chain = this.chain.then(() => this.popBack(Math.abs(overlap[0])));
|
const popBackCount = Math.abs(overlap[0]);
|
||||||
|
|
||||||
|
this.chain = this.chain.then(() => this.popBack(popBackCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (overlap && overlap[1] < 0) {
|
if (overlap && overlap[1] < 0) {
|
||||||
this.chain = this.chain.then(() => this.popFront(Math.abs(overlap[1])));
|
const popFrontCount = Math.abs(overlap[1]);
|
||||||
|
|
||||||
|
this.chain = this.chain.then(() => this.popFront(popFrontCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
let popHeight;
|
this.chain = this.chain
|
||||||
this.chain = this.chain.then(() => {
|
.then(() => {
|
||||||
popHeight = this.hooks.getScrollHeight();
|
popHeight = this.hooks.getScrollHeight();
|
||||||
|
|
||||||
return $q.resolve();
|
return $q.resolve();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (overlap && overlap[0] > 0) {
|
if (overlap && overlap[0] > 0) {
|
||||||
const pushBackRange = [head - overlap[0], head];
|
const pushBackRange = [head - overlap[0], head];
|
||||||
@@ -240,7 +266,7 @@ function SlidingWindowService ($q) {
|
|||||||
return this.chain;
|
return this.chain;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.slideDown = (displacement = PAGE_SIZE) => {
|
this.getNext = (displacement = PAGE_SIZE) => {
|
||||||
const [head, tail] = this.getRange();
|
const [head, tail] = this.getRange();
|
||||||
|
|
||||||
const tailRoom = this.getMaxCounter() - tail;
|
const tailRoom = this.getMaxCounter() - tail;
|
||||||
@@ -257,7 +283,7 @@ function SlidingWindowService ($q) {
|
|||||||
return this.move([head + headDisplacement, tail + tailDisplacement]);
|
return this.move([head + headDisplacement, tail + tailDisplacement]);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.slideUp = (displacement = PAGE_SIZE) => {
|
this.getPrevious = (displacement = PAGE_SIZE) => {
|
||||||
const [head, tail] = this.getRange();
|
const [head, tail] = this.getRange();
|
||||||
|
|
||||||
const headRoom = head - 1;
|
const headRoom = head - 1;
|
||||||
|
|||||||
@@ -23,6 +23,13 @@ function atRelaunchCtrl (
|
|||||||
const jobObj = new Job();
|
const jobObj = new Job();
|
||||||
const jobTemplate = new JobTemplate();
|
const jobTemplate = new JobTemplate();
|
||||||
|
|
||||||
|
const transitionOptions = { reload: true };
|
||||||
|
|
||||||
|
if ($state.includes('output')) {
|
||||||
|
transitionOptions.inherit = false;
|
||||||
|
transitionOptions.location = 'replace';
|
||||||
|
}
|
||||||
|
|
||||||
const updateTooltip = () => {
|
const updateTooltip = () => {
|
||||||
if (vm.job.type === 'job' && vm.job.status === 'failed') {
|
if (vm.job.type === 'job' && vm.job.status === 'failed') {
|
||||||
vm.tooltip = strings.get('relaunch.HOSTS');
|
vm.tooltip = strings.get('relaunch.HOSTS');
|
||||||
@@ -128,7 +135,7 @@ function atRelaunchCtrl (
|
|||||||
.then((launchRes) => {
|
.then((launchRes) => {
|
||||||
if (!$state.is('jobs')) {
|
if (!$state.is('jobs')) {
|
||||||
const relaunchType = launchRes.data.type === 'job' ? 'playbook' : launchRes.data.type;
|
const relaunchType = launchRes.data.type === 'job' ? 'playbook' : launchRes.data.type;
|
||||||
$state.go('output', { id: launchRes.data.id, type: relaunchType }, { reload: true });
|
$state.go('output', { id: launchRes.data.id, type: relaunchType }, transitionOptions);
|
||||||
}
|
}
|
||||||
}).catch(({ data, status, config }) => {
|
}).catch(({ data, status, config }) => {
|
||||||
ProcessErrors($scope, data, status, null, {
|
ProcessErrors($scope, data, status, null, {
|
||||||
@@ -173,7 +180,7 @@ function atRelaunchCtrl (
|
|||||||
inventorySource.postUpdate(vm.job.inventory_source)
|
inventorySource.postUpdate(vm.job.inventory_source)
|
||||||
.then((postUpdateRes) => {
|
.then((postUpdateRes) => {
|
||||||
if (!$state.is('jobs')) {
|
if (!$state.is('jobs')) {
|
||||||
$state.go('output', { id: postUpdateRes.data.id, type: 'inventory' }, { reload: true });
|
$state.go('output', { id: postUpdateRes.data.id, type: 'inventory' }, transitionOptions);
|
||||||
}
|
}
|
||||||
}).catch(({ data, status, config }) => {
|
}).catch(({ data, status, config }) => {
|
||||||
ProcessErrors($scope, data, status, null, {
|
ProcessErrors($scope, data, status, null, {
|
||||||
@@ -197,7 +204,7 @@ function atRelaunchCtrl (
|
|||||||
project.postUpdate(vm.job.project)
|
project.postUpdate(vm.job.project)
|
||||||
.then((postUpdateRes) => {
|
.then((postUpdateRes) => {
|
||||||
if (!$state.is('jobs')) {
|
if (!$state.is('jobs')) {
|
||||||
$state.go('output', { id: postUpdateRes.data.id, type: 'project' }, { reload: true });
|
$state.go('output', { id: postUpdateRes.data.id, type: 'project' }, transitionOptions);
|
||||||
}
|
}
|
||||||
}).catch(({ data, status, config }) => {
|
}).catch(({ data, status, config }) => {
|
||||||
ProcessErrors($scope, data, status, null, {
|
ProcessErrors($scope, data, status, null, {
|
||||||
@@ -219,7 +226,7 @@ function atRelaunchCtrl (
|
|||||||
id: vm.job.id
|
id: vm.job.id
|
||||||
}).then((launchRes) => {
|
}).then((launchRes) => {
|
||||||
if (!$state.is('jobs')) {
|
if (!$state.is('jobs')) {
|
||||||
$state.go('workflowResults', { id: launchRes.data.id }, { reload: true });
|
$state.go('workflowResults', { id: launchRes.data.id }, transitionOptions);
|
||||||
}
|
}
|
||||||
}).catch(({ data, status, config }) => {
|
}).catch(({ data, status, config }) => {
|
||||||
ProcessErrors($scope, data, status, null, {
|
ProcessErrors($scope, data, status, null, {
|
||||||
@@ -243,7 +250,7 @@ function atRelaunchCtrl (
|
|||||||
id: vm.job.id
|
id: vm.job.id
|
||||||
}).then((launchRes) => {
|
}).then((launchRes) => {
|
||||||
if (!$state.is('jobs')) {
|
if (!$state.is('jobs')) {
|
||||||
$state.go('output', { id: launchRes.data.id, type: 'command' }, { reload: true });
|
$state.go('output', { id: launchRes.data.id, type: 'command' }, transitionOptions);
|
||||||
}
|
}
|
||||||
}).catch(({ data, status, config }) => {
|
}).catch(({ data, status, config }) => {
|
||||||
ProcessErrors($scope, data, status, null, {
|
ProcessErrors($scope, data, status, null, {
|
||||||
@@ -268,7 +275,7 @@ function atRelaunchCtrl (
|
|||||||
relaunchData: PromptService.bundlePromptDataForRelaunch(vm.promptData)
|
relaunchData: PromptService.bundlePromptDataForRelaunch(vm.promptData)
|
||||||
}).then((launchRes) => {
|
}).then((launchRes) => {
|
||||||
if (!$state.is('jobs')) {
|
if (!$state.is('jobs')) {
|
||||||
$state.go('output', { id: launchRes.data.job, type: 'playbook' }, { reload: true });
|
$state.go('output', { id: launchRes.data.job, type: 'playbook' }, transitionOptions);
|
||||||
}
|
}
|
||||||
}).catch(({ data, status }) => {
|
}).catch(({ data, status }) => {
|
||||||
ProcessErrors($scope, data, status, null, {
|
ProcessErrors($scope, data, status, null, {
|
||||||
|
|||||||
Reference in New Issue
Block a user