Merge pull request #507 from coreos-inc/buildmsg

Better UX for build logs when switching focus back to tab
This commit is contained in:
josephschorr 2015-09-21 13:42:19 -04:00
commit d606a42e39
3 changed files with 56 additions and 35 deletions

View file

@ -24,34 +24,41 @@
please check for JavaScript or networking issues and contact support.
</div>
<span class="no-logs" ng-if="!logEntries.length && currentBuild.phase == 'waiting'">
(Waiting for build to start)
</span>
<div ng-show="!loadError && pollChannel.skipping">
Refreshing Build Status...
<span class="cor-loader"></span>
</div>
<div class="log-container" ng-class="container.type" ng-repeat="container in logEntries">
<div class="container-header" ng-class="container.type == 'phase' ? container.message : ''"
ng-switch on="container.type" ng-click="container.logs.toggle()">
<i class="fa chevron"
ng-class="container.logs.isVisible ? 'fa-chevron-down' : 'fa-chevron-right'"
ng-show="hasLogs(container)"></i>
<div ng-switch-when="phase">
<span class="container-content build-log-phase" phase="container"></span>
</div>
<div ng-switch-when="error">
<span class="container-content build-log-error" error="container" entries="logEntries"></span>
</div>
<div ng-switch-when="command">
<span class="container-content build-log-command" command="container"></span>
</div>
</div>
<div ng-show="!pollChannel.skipping">
<span class="no-logs" ng-if="!logEntries.length && currentBuild.phase == 'waiting'">
(Waiting for build to start)
</span>
<!-- Display the entries for the container -->
<div class="container-logs" ng-show="container.logs.isVisible">
<div class="log-entry" bindonce ng-repeat="entry in container.logs.visibleEntries">
<span class="id" bo-text="$index + container.index + 1" ng-if="!useTimestamps"></span>
<span class="id" bo-text="formatDatetime(entry.data.datetime)" ng-if="useTimestamps"></span>
<span class="message" bo-html="processANSI(entry.message, container)"></span>
<span class="timestamp" bo-text="formatDatetime(entry.data.datetime)" ng-if="!useTimestamps"></span>
<div class="log-container" ng-class="container.type" ng-repeat="container in logEntries">
<div class="container-header" ng-class="container.type == 'phase' ? container.message : ''"
ng-switch on="container.type" ng-click="container.logs.toggle()">
<i class="fa chevron"
ng-class="container.logs.isVisible ? 'fa-chevron-down' : 'fa-chevron-right'"
ng-show="hasLogs(container)"></i>
<div ng-switch-when="phase">
<span class="container-content build-log-phase" phase="container"></span>
</div>
<div ng-switch-when="error">
<span class="container-content build-log-error" error="container" entries="logEntries"></span>
</div>
<div ng-switch-when="command">
<span class="container-content build-log-command" command="container"></span>
</div>
</div>
<!-- Display the entries for the container -->
<div class="container-logs" ng-show="container.logs.isVisible">
<div class="log-entry" bindonce ng-repeat="entry in container.logs.visibleEntries">
<span class="id" bo-text="$index + container.index + 1" ng-if="!useTimestamps"></span>
<span class="id" bo-text="formatDatetime(entry.data.datetime)" ng-if="useTimestamps"></span>
<span class="message" bo-html="processANSI(entry.message, container)"></span>
<span class="timestamp" bo-text="formatDatetime(entry.data.datetime)" ng-if="!useTimestamps"></span>
</div>
</div>
</div>
</div>

View file

@ -28,7 +28,7 @@ angular.module('quay').directive('buildLogsView', function () {
$scope.currentBuild = null;
$scope.loadError = null;
var pollChannel = null;
$scope.pollChannel = null;
var appendToTextLog = function(type, message) {
if (type == 'phase') {
@ -146,14 +146,14 @@ angular.module('quay').directive('buildLogsView', function () {
getBuildStatusAndLogs(build, callback);
};
pollChannel = AngularPollChannel.create($scope, conductStatusAndLogRequest, 5 * 1000 /* 5s */);
pollChannel.start();
$scope.pollChannel = AngularPollChannel.create($scope, conductStatusAndLogRequest, 5 * 1000 /* 5s */);
$scope.pollChannel.start();
};
var stopWatching = function() {
if (pollChannel) {
pollChannel.stop();
pollChannel = null;
if ($scope.pollChannel) {
$scope.pollChannel.stop();
$scope.pollChannel = null;
}
};

View file

@ -1,8 +1,9 @@
/**
* Specialized class for conducting an HTTP poll, while properly preventing multiple calls.
*/
angular.module('quay').factory('AngularPollChannel', ['ApiService', '$timeout', 'DocumentVisibilityService',
function(ApiService, $timeout, DocumentVisibilityService) {
angular.module('quay').factory('AngularPollChannel',
['ApiService', '$timeout', 'DocumentVisibilityService', 'CORE_EVENT', '$rootScope',
function(ApiService, $timeout, DocumentVisibilityService, CORE_EVENT, $rootScope) {
var _PollChannel = function(scope, requester, opt_sleeptime) {
this.scope_ = scope;
this.requester_ = requester;
@ -11,10 +12,20 @@ angular.module('quay').factory('AngularPollChannel', ['ApiService', '$timeout',
this.working = false;
this.polling = false;
this.skipping = false;
var that = this;
var visibilityHandler = $rootScope.$on(CORE_EVENT.DOC_VISIBILITY_CHANGE, function() {
// If the poll channel was skipping because the visibility was hidden, call it immediately.
if (that.skipping && !DocumentVisibilityService.isHidden()) {
that.call_();
}
});
scope.$on('$destroy', function() {
that.stop();
visibilityHandler();
});
};
@ -28,9 +39,10 @@ angular.module('quay').factory('AngularPollChannel', ['ApiService', '$timeout',
if (this.timer_) {
$timeout.cancel(this.timer_);
this.timer_ = null;
this.polling_ = false;
this.polling = false;
}
this.skipping = false;
this.working = false;
};
@ -53,6 +65,7 @@ angular.module('quay').factory('AngularPollChannel', ['ApiService', '$timeout',
// If the document is currently hidden, skip the call.
if (DocumentVisibilityService.isHidden()) {
this.skipping = true;
this.setupTimer_();
return;
}
@ -63,6 +76,7 @@ angular.module('quay').factory('AngularPollChannel', ['ApiService', '$timeout',
that.requester_(function(status) {
if (status) {
that.working = false;
that.skipping = false;
that.setupTimer_();
} else {
that.stop();