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

View file

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

View file

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