This is an automated email from the ASF dual-hosted git repository. heneveld pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/brooklyn-ui.git
commit 2e8de6c710db6f99698e9334625897accb29aa73 Author: Mykola Mandra <[email protected]> AuthorDate: Fri Jul 16 16:52:36 2021 +0100 Use lineId to tail the auto-query Signed-off-by: Mykola Mandra <[email protected]> --- ui-modules/utils/logbook/logbook.js | 73 +++++++++++++------------- ui-modules/utils/logbook/logbook.template.html | 2 +- 2 files changed, 37 insertions(+), 38 deletions(-) diff --git a/ui-modules/utils/logbook/logbook.js b/ui-modules/utils/logbook/logbook.js index 39cc2e7..f685921 100644 --- a/ui-modules/utils/logbook/logbook.js +++ b/ui-modules/utils/logbook/logbook.js @@ -37,13 +37,10 @@ export function logbook() { function controller($scope, $element, $interval, brBrandInfo, logbookApi) { - const DEFAULT_NUMBER_OF_ITEMS = 1000; - let vm = this; let refreshFunction = null; let autoScrollableElement = Array.from($element.find('pre')).find(item => item.classList.contains('auto-scrollable')); let isNewQueryParameters = true; // Fresh start, new parameters! - let dateTimeToAutoRefreshFrom = ''; let datetimeToScrollTo = null; // Set up cancellation of auto-scrolling down. @@ -81,7 +78,7 @@ export function logbook() { latest: true, dateTimeFrom: '', dateTimeTo: '', - numberOfItems: DEFAULT_NUMBER_OF_ITEMS, + numberOfItems: 1000, phrase: '' }; @@ -113,6 +110,7 @@ export function logbook() { if ($scope.search.latest) { scrollToMostRecentLogEntry(); } else { + $scope.isAutoScrollDown = false; scrollToFirstLogEntry(); } }, true); @@ -189,9 +187,9 @@ export function logbook() { */ function cacheDatetimeToScrollTo() { let element = Array.from($element.find('pre')).find(item => item.offsetTop > (autoScrollableElement.scrollTop + autoScrollableElement.offsetTop - 1)); - let firstLogEntryInTheVisibleArea = $scope.logEntries.find(item => item.id === element.id); + let firstLogEntryInTheVisibleArea = $scope.logEntries.find(logEntry => logEntry.lineId === element.id); if (firstLogEntryInTheVisibleArea) { - datetimeToScrollTo = firstLogEntryInTheVisibleArea.datetime; + datetimeToScrollTo = getLogEntryTimestamp(firstLogEntryInTheVisibleArea); } } @@ -219,43 +217,43 @@ export function logbook() { tail: $scope.search.latest, searchPhrase: $scope.search.phrase, numberOfItems: $scope.search.numberOfItems, - dateTimeFrom: isTail() && !isNewQueryParameters ? dateTimeToAutoRefreshFrom : $scope.search.dateTimeFrom, + dateTimeFrom: isTail() && !isNewQueryParameters ? getLogEntryTimestamp($scope.logEntries.slice(-1)[0]) : $scope.search.dateTimeFrom, dateTimeTo: $scope.search.dateTimeTo, } - logbookApi.logbookQuery(params, true).then((logEntries) => { - - // Assign unique IDs for new log entries. - logEntries.forEach(item => item.id = generateLogEntryId()); + logbookApi.logbookQuery(params, true).then((newLogEntries) => { - if (logEntries.length > 0 && isTail() && $scope.autoRefresh && !isNewQueryParameters) { + if (newLogEntries.length > 0 && isTail() && $scope.autoRefresh && !isNewQueryParameters) { - // Calculate date-time to display up to. Note, calendar does not take into account milliseconds, round down to seconds. - let dateTimeOfLastLogEntry = Math.floor(logEntries.slice(-1)[0].datetime / DEFAULT_NUMBER_OF_ITEMS) * DEFAULT_NUMBER_OF_ITEMS; - let dateTimeFrom = new Date($scope.search.dateTimeFrom).getTime(); + // Use line IDs to resolve the overlap, if any. + let lastLogEntryDisplayed = $scope.logEntries[$scope.logEntries.length - 1]; + let indexOfLogEntryInTheNewBatch = newLogEntries.findIndex(({lineId}) => lineId === lastLogEntryDisplayed.lineId); + if (indexOfLogEntryInTheNewBatch >= 0) { - if (dateTimeOfLastLogEntry > dateTimeFrom) { + // Append new log entries without overlap. + $scope.logEntries = $scope.logEntries.concat(newLogEntries.slice(indexOfLogEntryInTheNewBatch + 1)); - // Display new log entries. - let newLogEntries = logEntries.filter(({datetime}) => datetime <= dateTimeOfLastLogEntry); - $scope.logEntries = $scope.logEntries.concat(newLogEntries).slice(-DEFAULT_NUMBER_OF_ITEMS); - - // Optimize auto-refresh: cache next date-time to query tail from, if it is still a tail. - dateTimeToAutoRefreshFrom = dateTimeOfLastLogEntry; } else { - // Or re-set the cached value. - dateTimeToAutoRefreshFrom = ''; + + // Append all new log entries, there is no overlap. + $scope.logEntries = $scope.logEntries.concat(newLogEntries) } - } else { - $scope.logEntries = logEntries; + + // Display not more of lines than was requested. + $scope.logEntries.slice(-$scope.search.numberOfItems); + + } else if (isNewQueryParameters) { + + // New query, re-draw all entries. + $scope.logEntries = newLogEntries; } // Auto-scroll. if ($scope.logEntries.length > 0) { if ($scope.isAutoScrollDown) { scrollToMostRecentLogEntry(); - } else if (datetimeToScrollTo && datetimeToScrollTo >= $scope.logEntries[0].datetime) { + } else if (datetimeToScrollTo && datetimeToScrollTo >= getLogEntryTimestamp($scope.logEntries[0])) { scrollToLogEntryWithDateTime(datetimeToScrollTo); } } @@ -276,6 +274,16 @@ export function logbook() { } /** + * Extracts timestamp from the log entry. + * + * @param logEntry The log entry. + * @returns {number} The extracted date-time. + */ + function getLogEntryTimestamp(logEntry) { + return logEntry.datetime || Date.parse(logEntry.timestamp.replace(',', '.')) + } + + /** * Gets all checked boxes from the group of elements. * * @param {Object} checkBoxGroup The checkbox group. @@ -309,7 +317,6 @@ export function logbook() { function stopAutoRefresh() { if (refreshFunction) { $interval.cancel(refreshFunction); - dateTimeToAutoRefreshFrom = ''; } } @@ -340,7 +347,7 @@ export function logbook() { $scope.$applyAsync(() => { let logEntryWithDateTimeToScrollTo = $scope.logEntries.find(item => item.datetime >= datetime); if (logEntryWithDateTimeToScrollTo) { - let elementWithDateTimeToScrollTo = Array.from($element.find('pre')).find(item => item.id === logEntryWithDateTimeToScrollTo.id); + let elementWithDateTimeToScrollTo = Array.from($element.find('pre')).find(element => element.id === logEntryWithDateTimeToScrollTo.lineId); if (logEntryWithDateTimeToScrollTo) { autoScrollableElement.scrollTop = elementWithDateTimeToScrollTo.offsetTop - autoScrollableElement.offsetTop; } @@ -349,14 +356,6 @@ export function logbook() { } /** - * @returns {String} Randomly generated log book entry ID. - */ - function generateLogEntryId() { - const LOG_ENTRY_PREFIX = 'le-'; - return LOG_ENTRY_PREFIX + Math.random().toString(36).slice(2); - } - - /** * Pins the log entry. Pinned log entry is displayed even if it is not present in the new query, until unpinned. * * @param {Object} logEntry The log entry to pin. diff --git a/ui-modules/utils/logbook/logbook.template.html b/ui-modules/utils/logbook/logbook.template.html index 0c3e706..63db664 100644 --- a/ui-modules/utils/logbook/logbook.template.html +++ b/ui-modules/utils/logbook/logbook.template.html @@ -82,5 +82,5 @@ <div ng-show="logEntries.length > 0 || logtext"> <pre ng-show="logEntries.length === 0" class="logbook-text">{{logtext}}</pre> - <pre ng-show="logEntries.length > 0" class="logbook-text auto-scrollable" ng-class="{'word-wrap': wordwrap}"><pre class="logbook-item" ng-repeat="item in logEntries track by item.id" id="{{item.id}}" ng-click="vm.logEntryOnClick(item)" level="{{item.level}}" ng-class="{'pinned': item.isPinned}">{{vm.covertLogEntryToString(item)}}</pre></pre> + <pre ng-show="logEntries.length > 0" class="logbook-text auto-scrollable" ng-class="{'word-wrap': wordwrap}"><pre class="logbook-item" ng-repeat="item in logEntries track by item.lineId" id="{{item.lineId}}" ng-click="vm.logEntryOnClick(item)" level="{{item.level}}" ng-class="{'pinned': item.isPinned}">{{vm.covertLogEntryToString(item)}}</pre></pre> </div>
