Change the repo view page to minimize the number of API calls necessary until such time as the information is needed (lazy load everything). Also increase the build timer to 30s.

This commit is contained in:
Joseph Schorr 2015-05-06 18:16:03 -04:00
parent 03481261e8
commit c04cb4e988
9 changed files with 91 additions and 23 deletions

View file

@ -5,7 +5,8 @@
<div class="co-panel"> <div class="co-panel">
<div class="co-panel-heading"><i class="fa fa-key"></i> User and Robot Permissions</div> <div class="co-panel-heading"><i class="fa fa-key"></i> User and Robot Permissions</div>
<div class="panel-body" style="padding-top: 5px;"> <div class="panel-body" style="padding-top: 5px;">
<div class="repository-permissions-table" repository="repository"></div> <div class="repository-permissions-table" repository="repository"
is-enabled="isEnabled"></div>
</div> </div>
</div> </div>
@ -13,12 +14,13 @@
<div class="co-panel" ng-show="hasTokens"> <div class="co-panel" ng-show="hasTokens">
<div class="co-panel-heading"><i class="fa fa-key"></i> Access Token Permissions</div> <div class="co-panel-heading"><i class="fa fa-key"></i> Access Token Permissions</div>
<div class="panel-body" style="padding-top: 5px;"> <div class="panel-body" style="padding-top: 5px;">
<div class="repository-tokens-table" repository="repository" has-tokens="hasTokens"></div> <div class="repository-tokens-table" repository="repository" has-tokens="hasTokens" is-enabled="isEnabled"></div>
</div> </div>
</div> </div>
<!-- Events and Notifications --> <!-- Events and Notifications -->
<div class="repository-events-table" repository="repository"></div> <div class="repository-events-table" repository="repository"
is-enabled="isEnabled"></div>
<!-- Other settings --> <!-- Other settings -->
<div class="co-panel"> <div class="co-panel">

View file

@ -10,7 +10,8 @@ angular.module('quay').directive('repoPanelBuilds', function () {
restrict: 'C', restrict: 'C',
scope: { scope: {
'repository': '=repository', 'repository': '=repository',
'builds': '=builds' 'builds': '=builds',
'isEnabled': '=isEnabled'
}, },
controller: function($scope, $element, $filter, $routeParams, ApiService, TriggerService, UserService) { controller: function($scope, $element, $filter, $routeParams, ApiService, TriggerService, UserService) {
var orderBy = $filter('orderBy'); var orderBy = $filter('orderBy');
@ -58,7 +59,7 @@ angular.module('quay').directive('repoPanelBuilds', function () {
}; };
var loadBuilds = function(opt_forcerefresh) { var loadBuilds = function(opt_forcerefresh) {
if (!$scope.builds || !$scope.repository || !$scope.options.filter) { if (!$scope.builds || !$scope.repository || !$scope.options.filter || !$scope.isEnabled) {
return; return;
} }
@ -101,7 +102,7 @@ angular.module('quay').directive('repoPanelBuilds', function () {
return; return;
} }
if (!$scope.builds || !$scope.repository) { if (!$scope.builds || !$scope.repository || !$scope.isEnabled) {
return; return;
} }
@ -133,7 +134,7 @@ angular.module('quay').directive('repoPanelBuilds', function () {
}; };
var loadBuildTriggers = function() { var loadBuildTriggers = function() {
if (!$scope.repository || !$scope.repository.can_admin) { return; } if (!$scope.repository || !$scope.repository.can_admin || !$scope.isEnabled) { return; }
var params = { var params = {
'repository': $scope.repository.namespace + '/' + $scope.repository.name 'repository': $scope.repository.namespace + '/' + $scope.repository.name
@ -157,6 +158,9 @@ angular.module('quay').directive('repoPanelBuilds', function () {
$scope.$watch('repository', loadBuildTriggers); $scope.$watch('repository', loadBuildTriggers);
$scope.$watch('repository', loadBuilds); $scope.$watch('repository', loadBuilds);
$scope.$watch('isEnabled', loadBuildTriggers);
$scope.$watch('isEnabled', loadBuilds);
$scope.$watch('builds', buildsChanged); $scope.$watch('builds', buildsChanged);
$scope.$watch('options.filter', loadBuilds); $scope.$watch('options.filter', loadBuilds);

View file

@ -9,7 +9,8 @@ angular.module('quay').directive('repoPanelSettings', function () {
transclude: false, transclude: false,
restrict: 'C', restrict: 'C',
scope: { scope: {
'repository': '=repository' 'repository': '=repository',
'isEnabled': '=isEnabled'
}, },
controller: function($scope, $element, ApiService, Config) { controller: function($scope, $element, ApiService, Config) {
$scope.getBadgeFormat = function(format, repository) { $scope.getBadgeFormat = function(format, repository) {

View file

@ -10,13 +10,15 @@ angular.module('quay').directive('repositoryEventsTable', function () {
transclude: true, transclude: true,
restrict: 'C', restrict: 'C',
scope: { scope: {
'repository': '=repository' 'repository': '=repository',
'isEnabled': '=isEnabled'
}, },
controller: function($scope, $element, ApiService, Restangular, UtilService, ExternalNotificationData) { controller: function($scope, $element, ApiService, Restangular, UtilService, ExternalNotificationData) {
$scope.showNewNotificationCounter = 0; $scope.showNewNotificationCounter = 0;
var loadNotifications = function() { var loadNotifications = function() {
if (!$scope.repository || $scope.notificationsResource) { return; } if (!$scope.repository || $scope.notificationsResource || !$scope.isEnabled) { return; }
var params = { var params = {
'repository': $scope.repository.namespace + '/' + $scope.repository.name 'repository': $scope.repository.namespace + '/' + $scope.repository.name
}; };
@ -29,6 +31,8 @@ angular.module('quay').directive('repositoryEventsTable', function () {
}; };
$scope.$watch('repository', loadNotifications); $scope.$watch('repository', loadNotifications);
$scope.$watch('isEnabled', loadNotifications);
loadNotifications(); loadNotifications();
$scope.handleNotificationCreated = function(notification) { $scope.handleNotificationCreated = function(notification) {

View file

@ -25,7 +25,8 @@ angular.module('quay').directive('repositoryPermissionsTable', function () {
transclude: true, transclude: true,
restrict: 'C', restrict: 'C',
scope: { scope: {
'repository': '=repository' 'repository': '=repository',
'isEnabled': '=isEnabled'
}, },
controller: function($scope, $element, ApiService, Restangular, UtilService) { controller: function($scope, $element, ApiService, Restangular, UtilService) {
$scope.permissionResources = {'team': {}, 'user': {}}; $scope.permissionResources = {'team': {}, 'user': {}};
@ -34,7 +35,8 @@ angular.module('quay').directive('repositoryPermissionsTable', function () {
$scope.addPermissionInfo = {}; $scope.addPermissionInfo = {};
var loadAllPermissions = function() { var loadAllPermissions = function() {
if (!$scope.repository) { return; } if (!$scope.repository || !$scope.isEnabled) { return; }
fetchPermissions('user'); fetchPermissions('user');
fetchPermissions('team'); fetchPermissions('team');
}; };
@ -58,6 +60,8 @@ angular.module('quay').directive('repositoryPermissionsTable', function () {
}; };
$scope.$watch('repository', loadAllPermissions); $scope.$watch('repository', loadAllPermissions);
$scope.$watch('isEnabled', loadAllPermissions);
loadAllPermissions(); loadAllPermissions();
var getPermissionEndpoint = function(entityName, kind) { var getPermissionEndpoint = function(entityName, kind) {

View file

@ -11,13 +11,14 @@ angular.module('quay').directive('repositoryTokensTable', function () {
restrict: 'C', restrict: 'C',
scope: { scope: {
'repository': '=repository', 'repository': '=repository',
'hasTokens': '=hasTokens' 'hasTokens': '=hasTokens',
'isEnabled': '=isEnabled'
}, },
controller: function($scope, $element, ApiService, Restangular, UtilService) { controller: function($scope, $element, ApiService, Restangular, UtilService) {
$scope.hasTokens = false; $scope.hasTokens = false;
var loadTokens = function() { var loadTokens = function() {
if (!$scope.repository || $scope.tokensResource) { return; } if (!$scope.repository || $scope.tokensResource || !$scope.isEnabled) { return; }
var params = { var params = {
'repository': $scope.repository.namespace + '/' + $scope.repository.name 'repository': $scope.repository.namespace + '/' + $scope.repository.name
}; };
@ -28,7 +29,9 @@ angular.module('quay').directive('repositoryTokensTable', function () {
}, ApiService.errorDisplay('Could not load access tokens')); }, ApiService.errorDisplay('Could not load access tokens'));
}; };
$scope.$watch('isEnabled', loadTokens);
$scope.$watch('repository', loadTokens); $scope.$watch('repository', loadTokens);
loadTokens(); loadTokens();
$scope.deleteToken = function(tokenCode) { $scope.deleteToken = function(tokenCode) {

View file

@ -17,7 +17,13 @@
$scope.namespace = $routeParams.namespace; $scope.namespace = $routeParams.namespace;
$scope.name = $routeParams.name; $scope.name = $routeParams.name;
$scope.imagesRequired = false;
// Tab-enabled counters.
$scope.logsShown = 0; $scope.logsShown = 0;
$scope.buildsShown = 0;
$scope.settingsShown = 0;
$scope.viewScope = { $scope.viewScope = {
'selectedTags': [], 'selectedTags': [],
'repository': null, 'repository': null,
@ -72,11 +78,17 @@
$scope.setTags($routeParams.tag); $scope.setTags($routeParams.tag);
// Load the images. // Load the images.
loadImages(); if ($scope.imagesRequired) {
loadImages();
}
// Track builds. // Track builds.
buildPollChannel = AngularPollChannel.create($scope, loadRepositoryBuilds, 15000 /* 15s */); if (!$scope.repository.is_building) {
buildPollChannel.start(); $scope.viewScope.builds = [];
}
buildPollChannel = AngularPollChannel.create($scope, loadRepositoryBuilds, 30000 /* 30s */);
buildPollChannel.start(!$scope.repository.is_building);
}, 10); }, 10);
}); });
}; };
@ -139,10 +151,28 @@
$scope.viewScope.selectedTags = $.unique(tagNames.split(',')); $scope.viewScope.selectedTags = $.unique(tagNames.split(','));
}; };
$scope.showBuilds = function() {
$scope.buildsShown++;
};
$scope.showSettings = function() {
$scope.settingsShown++;
};
$scope.showLogs = function() { $scope.showLogs = function() {
$scope.logsShown++; $scope.logsShown++;
}; };
$scope.requireImages = function() {
// Lazily load the repo's images if this is the first call to a tab
// that needs the images.
if (!$scope.imagesRequired) {
loadImages();
}
$scope.imagesRequired = true;
};
$scope.handleChangesState = function(value) { $scope.handleChangesState = function(value) {
$scope.viewScope.changesVisible = value; $scope.viewScope.changesVisible = value;
}; };

View file

@ -17,6 +17,12 @@ angular.module('quay').factory('AngularPollChannel', ['ApiService', '$timeout',
}); });
}; };
_PollChannel.prototype.setSleepTime = function(sleepTime) {
this.sleeptime_ = sleepTime;
this.stop();
this.start(true);
};
_PollChannel.prototype.stop = function() { _PollChannel.prototype.stop = function() {
if (this.timer_) { if (this.timer_) {
$timeout.cancel(this.timer_); $timeout.cancel(this.timer_);
@ -27,11 +33,18 @@ angular.module('quay').factory('AngularPollChannel', ['ApiService', '$timeout',
this.working = false; this.working = false;
}; };
_PollChannel.prototype.start = function() { _PollChannel.prototype.start = function(opt_skipFirstCall) {
// Make sure we invoke call outside the normal digest cycle, since // Make sure we invoke call outside the normal digest cycle, since
// we'll call $scope.$apply ourselves. // we'll call $scope.$apply ourselves.
var that = this; var that = this;
setTimeout(function() { that.call_(); }, 0); setTimeout(function() {
if (opt_skipFirstCall) {
that.setupTimer_();
return;
}
that.call_();
}, 0);
}; };
_PollChannel.prototype.call_ = function() { _PollChannel.prototype.call_ = function() {

View file

@ -21,17 +21,21 @@
<i class="fa fa-info-circle"></i> <i class="fa fa-info-circle"></i>
</span> </span>
<span class="cor-tab" tab-title="Tags" tab-target="#tags"> <span class="cor-tab" tab-title="Tags" tab-target="#tags"
tab-init="requireImages()">
<i class="fa fa-tags"></i> <i class="fa fa-tags"></i>
</span> </span>
<span class="cor-tab" tab-title="Builds" tab-target="#builds" <span class="cor-tab" tab-title="Builds" tab-target="#builds"
tab-init="showBuilds()"
quay-show="viewScope.repository.can_write && Features.BUILD_SUPPORT"> quay-show="viewScope.repository.can_write && Features.BUILD_SUPPORT">
<i class="fa fa-tasks"></i> <i class="fa fa-tasks"></i>
</span> </span>
<span class="cor-tab" tab-title="Visualize" tab-target="#changes" <span class="cor-tab" tab-title="Visualize" tab-target="#changes"
tab-shown="handleChangesState(true)" tab-hidden="handleChangesState(false)"> tab-shown="handleChangesState(true)"
tab-hidden="handleChangesState(false)"
tab-init="requireImages()">
<i class="fa fa-code-fork"></i> <i class="fa fa-code-fork"></i>
</span> </span>
@ -42,6 +46,7 @@
</span> </span>
<span class="cor-tab" tab-title="Settings" tab-target="#settings" <span class="cor-tab" tab-title="Settings" tab-target="#settings"
tab-init="showSettings()"
ng-show="viewScope.repository.can_admin"> ng-show="viewScope.repository.can_admin">
<i class="fa fa-gear"></i> <i class="fa fa-gear"></i>
</span> </span>
@ -68,7 +73,8 @@
<div id="builds" class="tab-pane"> <div id="builds" class="tab-pane">
<div class="repo-panel-builds" <div class="repo-panel-builds"
repository="viewScope.repository" repository="viewScope.repository"
builds="viewScope.builds"></div> builds="viewScope.builds"
is-enabled="buildsShown"></div>
</div> </div>
<!-- Changes --> <!-- Changes -->
@ -88,7 +94,8 @@
<!-- Settings --> <!-- Settings -->
<div id="settings" class="tab-pane" ng-if="viewScope.repository.can_admin"> <div id="settings" class="tab-pane" ng-if="viewScope.repository.can_admin">
<div class="repo-panel-settings" repository="viewScope.repository"></div> <div class="repo-panel-settings" repository="viewScope.repository"
is-enabled="settingsShown"></div>
</div> </div>
</div> <!-- /cor-tab-content --> </div> <!-- /cor-tab-content -->
</div> </div>