Work in progress: add a loading bar and convert to using the new ApiService and resource-view

This commit is contained in:
Joseph Schorr 2013-12-17 13:19:59 -05:00
parent a53106be3b
commit 414bd34d52
15 changed files with 1116 additions and 642 deletions

View file

@ -15,7 +15,7 @@ $.fn.clipboardCopy = function() {
});
};
function SigninCtrl($scope, $location, $timeout, Restangular, KeyService, UserService) {
function SigninCtrl($scope) {
};
function PlansCtrl($scope, $location, UserService, PlanService) {
@ -24,17 +24,13 @@ function PlansCtrl($scope, $location, UserService, PlanService) {
$scope.plans = plans;
});
$scope.$watch( function () { return UserService.currentUser(); }, function (currentUser) {
$scope.user = currentUser;
}, true);
// Monitor any user changes and place the current user into the scope.
UserService.updateUserIn($scope);
$scope.signedIn = function() {
$('#signinModal').modal('hide');
PlanService.handleNotedPlan();
};
$scope.cancelNotedPlan = function() {
};
$scope.buyNow = function(plan) {
if ($scope.user && !$scope.user.anonymous) {
@ -61,61 +57,50 @@ function GuideCtrl($scope) {
function SecurityCtrl($scope) {
}
function RepoListCtrl($scope, Restangular, UserService) {
function RepoListCtrl($scope, Restangular, UserService, ApiService) {
$scope.namespace = null;
// Monitor changes in the user.
UserService.updateUserIn($scope, function() {
loadMyRepos($scope.namespace);
});
$scope.$watch( function () { return UserService.currentUser(); }, function (currentUser) {
$scope.user = currentUser;
}, true);
// Monitor changes in the namespace.
$scope.$watch('namespace', function(namespace) {
loadMyRepos(namespace);
});
$scope.loading = true;
$scope.public_repositories = null;
$scope.user_repositories = [];
var loadMyRepos = function(namespace) {
if (!$scope.user || $scope.user.anonymous || !namespace) {
return;
}
$scope.loadingmyrepos = true;
// Load the list of repositories.
var params = {
'public': false,
'sort': true,
'namespace': namespace
};
var repositoryFetch = Restangular.all('repository/');
repositoryFetch.getList(params).then(function(resp) {
$scope.user_repositories = resp.repositories;
$scope.loading = !($scope.public_repositories && $scope.user_repositories);
var options = {'public': false, 'sort': true, 'namespace': namespace};
$scope.user_repositories = ApiService.at('repository').withOptions(options).get(function(resp) {
return resp.repositories;
});
};
// Load the list of public repositories.
var options = {'public': true, 'private': false, 'sort': true, 'limit': 10};
var repositoryPublicFetch = Restangular.all('repository/');
repositoryPublicFetch.getList(options).then(function(resp) {
$scope.public_repositories = resp.repositories;
$scope.loading = !($scope.public_repositories && $scope.user_repositories);
});
var loadPublicRepos = function() {
var options = {'public': true, 'private': false, 'sort': true, 'limit': 10};
$scope.public_repositories = ApiService.at('repository').withOptions(options).get(function(resp) {
return resp.repositories;
});
};
loadPublicRepos();
}
function LandingCtrl($scope, $timeout, $location, Restangular, UserService, KeyService, PlanService) {
function LandingCtrl($scope, UserService, ApiService) {
$scope.namespace = null;
$scope.$watch('namespace', function(namespace) {
loadMyRepos(namespace);
});
$scope.$watch( function () { return UserService.currentUser(); }, function (currentUser) {
$scope.user = currentUser;
}, true);
UserService.updateUserIn($scope, function() {
loadMyRepos($scope.namespace);
});
$scope.canCreateRepo = function(namespace) {
if (!$scope.user) { return false; }
@ -141,40 +126,44 @@ function LandingCtrl($scope, $timeout, $location, Restangular, UserService, KeyS
return;
}
$scope.loadingmyrepos = true;
// Load the list of repositories.
var params = {
'limit': 4,
'public': false,
'sort': true,
'namespace': namespace
};
var repositoryFetch = Restangular.all('repository/');
repositoryFetch.getList(params).then(function(resp) {
$scope.myrepos = resp.repositories;
$scope.loadingmyrepos = false;
var options = {'limit': 4, 'public': false, 'sort': true, 'namespace': namespace };
$scope.my_repositories = ApiService.at('repository').withOptions(options).get(function(resp) {
return resp.repositories;
});
};
browserchrome.update();
}
function RepoCtrl($scope, Restangular, $routeParams, $rootScope, $location, $timeout) {
function RepoCtrl($scope, Restangular, ApiService, $routeParams, $rootScope, $location, $timeout) {
var namespace = $routeParams.namespace;
var name = $routeParams.name;
$rootScope.title = 'Loading...';
// Watch for the destruction of the scope.
$scope.$on('$destroy', function() {
if ($scope.tree) {
$scope.tree.dispose();
}
});
// Watch for changes to the repository.
$scope.$watch('repo', function() {
if ($scope.tree) {
$timeout(function() {
$scope.tree.notifyResized();
});
}
});
// Watch for changes to the tag parameter.
$scope.$on('$routeUpdate', function(){
$scope.setTag($location.search().tag, false);
});
// Start scope methods //////////////////////////////////////////
$scope.updateForDescription = function(content) {
$scope.repo.description = content;
$scope.repo.put();
@ -188,135 +177,9 @@ function RepoCtrl($scope, Restangular, $routeParams, $rootScope, $location, $tim
return moment($scope.parseDate(createdTime)).fromNow();
};
var getDefaultTag = function() {
if ($scope.repo === undefined) {
return undefined;
} else if ($scope.repo.tags.hasOwnProperty('latest')) {
return $scope.repo.tags['latest'];
} else {
for (key in $scope.repo.tags) {
return $scope.repo.tags[key];
}
}
};
$scope.$watch('repo', function() {
if ($scope.tree) {
$timeout(function() {
$scope.tree.notifyResized();
});
}
});
var fetchRepository = function() {
var repositoryFetch = Restangular.one('repository/' + namespace + '/' + name);
repositoryFetch.get().then(function(repo) {
$rootScope.title = namespace + '/' + name;
var kind = repo.is_public ? 'public' : 'private';
$rootScope.description = jQuery(getFirstTextLine(repo.description)).text() ||
'View of a ' + kind + ' docker repository on Quay';
$scope.repo = repo;
$scope.setTag($routeParams.tag);
$('#copyClipboard').clipboardCopy();
$scope.loading = false;
if (repo.is_building) {
startBuildInfoTimer(repo);
}
}, function() {
$scope.repo = null;
$scope.loading = false;
$rootScope.title = 'Unknown Repository';
});
};
var startBuildInfoTimer = function(repo) {
if ($scope.interval) { return; }
getBuildInfo(repo);
$scope.interval = setInterval(function() {
$scope.$apply(function() { getBuildInfo(repo); });
}, 5000);
$scope.$on("$destroy", function() {
cancelBuildInfoTimer();
});
};
var cancelBuildInfoTimer = function() {
if ($scope.interval) {
clearInterval($scope.interval);
}
};
var getBuildInfo = function(repo) {
var buildInfo = Restangular.one('repository/' + repo.namespace + '/' + repo.name + '/build/');
buildInfo.get().then(function(resp) {
var runningBuilds = [];
for (var i = 0; i < resp.builds.length; ++i) {
var build = resp.builds[i];
if (build.status != 'complete') {
runningBuilds.push(build);
}
}
$scope.buildsInfo = runningBuilds;
if (!runningBuilds.length) {
// Cancel the build timer.
cancelBuildInfoTimer();
// Mark the repo as no longer building.
$scope.repo.is_building = false;
// Reload the repo information.
fetchRepository();
listImages();
}
});
};
var listImages = function() {
var imageFetch = Restangular.one('repository/' + namespace + '/' + name + '/image/');
imageFetch.get().then(function(resp) {
$scope.imageHistory = resp.images;
// Dispose of any existing tree.
if ($scope.tree) {
$scope.tree.dispose();
}
// Create the new tree.
$scope.tree = new ImageHistoryTree(namespace, name, resp.images,
getFirstTextLine, $scope.getTimeSince);
$scope.tree.draw('image-history-container');
// If we already have a tag, use it
if ($scope.currentTag) {
$scope.tree.setTag($scope.currentTag.name);
}
$($scope.tree).bind('tagChanged', function(e) {
$scope.$apply(function() { $scope.setTag(e.tag, true); });
});
$($scope.tree).bind('imageChanged', function(e) {
$scope.$apply(function() { $scope.setImage(e.image); });
});
});
};
$scope.loadImageChanges = function(image) {
$scope.currentImageChanges = null;
var changesFetch = Restangular.one('repository/' + namespace + '/' + name + '/image/' + image.id + '/changes');
changesFetch.get().then(function(changeInfo) {
$scope.currentImageChanges = changeInfo;
}, function() {
$scope.currentImageChanges = {'added': [], 'removed': [], 'changed': []};
$scope.currentImageChangeResource = ApiService.at('repository', namespace, name, 'image', image.id, 'changes').get(function(ci) {
$scope.currentImageChanges = ci;
});
};
@ -373,22 +236,134 @@ function RepoCtrl($scope, Restangular, $routeParams, $rootScope, $location, $tim
return count;
};
var namespace = $routeParams.namespace;
var name = $routeParams.name;
var getDefaultTag = function() {
if ($scope.repo === undefined) {
return undefined;
} else if ($scope.repo.tags.hasOwnProperty('latest')) {
return $scope.repo.tags['latest'];
} else {
for (key in $scope.repo.tags) {
return $scope.repo.tags[key];
}
}
};
$scope.loading = true;
var fetchRepository = function() {
$rootScope.title = 'Loading Repository...';
$scope.repository = ApiService.at('repository', namespace, name).get(function(repo) {
// Set the repository object.
$scope.repo = repo;
// Fetch the repo.
fetchRepository();
// Set the default tag.
$scope.setTag($routeParams.tag);
// Fetch the image history.
listImages();
// Set the title of the page.
$rootScope.title = namespace + '/' + name;
var kind = repo.is_public ? 'public' : 'private';
$rootScope.description = jQuery(getFirstTextLine(repo.description)).text() ||
'View of a ' + kind + ' docker repository on Quay';
// If the repository is marked as building, start monitoring it for changes.
if (repo.is_building) {
startBuildInfoTimer(repo);
}
$('#copyClipboard').clipboardCopy();
});
};
var startBuildInfoTimer = function(repo) {
if ($scope.interval) { return; }
getBuildInfo(repo);
$scope.interval = setInterval(function() {
$scope.$apply(function() { getBuildInfo(repo); });
}, 5000);
$scope.$on("$destroy", function() {
cancelBuildInfoTimer();
});
};
var cancelBuildInfoTimer = function() {
if ($scope.interval) {
clearInterval($scope.interval);
}
};
var getBuildInfo = function(repo) {
var buildInfo = Restangular.one('repository/' + repo.namespace + '/' + repo.name + '/build/');
buildInfo.withHttpConfig({
'ignoreLoadingBar': true
});
buildInfo.get().then(function(resp) {
var runningBuilds = [];
for (var i = 0; i < resp.builds.length; ++i) {
var build = resp.builds[i];
if (build.status != 'complete') {
runningBuilds.push(build);
}
}
$scope.buildsInfo = runningBuilds;
if (!runningBuilds.length) {
// Cancel the build timer.
cancelBuildInfoTimer();
// Mark the repo as no longer building.
$scope.repo.is_building = false;
// Reload the repo information.
loadViewInfo();
}
});
};
var listImages = function() {
$scope.imageHistory = ApiService.at('repository', namespace, name, 'image').get(function(resp) {
// Dispose of any existing tree.
if ($scope.tree) {
$scope.tree.dispose();
}
// Create the new tree.
$scope.tree = new ImageHistoryTree(namespace, name, resp.images,
getFirstTextLine, $scope.getTimeSince);
$scope.tree.draw('image-history-container');
// If we already have a tag, use it
if ($scope.currentTag) {
$scope.tree.setTag($scope.currentTag.name);
}
// Listen for changes to the selected tag and image in the tree.
$($scope.tree).bind('tagChanged', function(e) {
$scope.$apply(function() { $scope.setTag(e.tag, true); });
});
$($scope.tree).bind('imageChanged', function(e) {
$scope.$apply(function() { $scope.setImage(e.image); });
});
return resp.images;
});
};
var loadViewInfo = function() {
fetchRepository();
listImages();
};
// Fetch the repository itself as well as the image history.
loadViewInfo();
}
function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) {
function RepoAdminCtrl($scope, Restangular, ApiService, $routeParams, $rootScope) {
$('.info-icon').popover({
'trigger': 'hover',
'html': true
'trigger': 'hover',
'html': true
});
var namespace = $routeParams.namespace;
@ -547,63 +522,19 @@ function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) {
});
};
$scope.loading = true;
var checkLoading = function() {
$scope.loading = !($scope.permissions['user'] && $scope.permissions['team'] && $scope.repo && $scope.tokens);
};
var fetchPermissions = function(kind) {
var permissionsFetch = Restangular.one('repository/' + namespace + '/' + name + '/permissions/' + kind + '/');
permissionsFetch.get().then(function(resp) {
$rootScope.title = 'Settings - ' + namespace + '/' + name;
$rootScope.description = 'Administrator settings for ' + namespace + '/' + name +
': Permissions, webhooks and other settings';
$scope.permissions[kind] = resp.permissions;
checkLoading();
}, function() {
$scope.permissions[kind] = null;
$rootScope.title = 'Unknown Repository';
$scope.loading = false;
});
};
// Fetch the repository information.
var repositoryFetch = Restangular.one('repository/' + namespace + '/' + name);
repositoryFetch.get().then(function(repo) {
$scope.repo = repo;
$scope.loading = !($scope.permissions && $scope.repo && $scope.tokens);
}, function() {
$scope.permissions = null;
$rootScope.title = 'Unknown Repository';
$scope.loading = false;
});
// Fetch the user and team permissions.
fetchPermissions('user');
fetchPermissions('team');
// Fetch the tokens.
var tokensFetch = Restangular.one('repository/' + namespace + '/' + name + '/tokens/');
tokensFetch.get().then(function(resp) {
$scope.tokens = resp.tokens;
checkLoading();
}, function() {
$scope.tokens = null;
$scope.loading = false;
});
$scope.webhooksLoading = true;
$scope.loadWebhooks = function() {
$scope.webhooksLoading = true;
var fetchWebhooks = Restangular.one('repository/' + namespace + '/' + name + '/webhook/');
fetchWebhooks.get().then(function(resp) {
$scope.newWebhook = {};
$scope.webhooksResource = ApiService.at('repository', namespace, name, 'webhook').get(function(resp) {
$scope.webhooks = resp.webhooks;
$scope.webhooksLoading = false;
return $scope.webhooks;
});
};
$scope.createWebhook = function() {
if (!$scope.newWebhook.url) {
return;
}
var newWebhook = Restangular.one('repository/' + namespace + '/' + name + '/webhook/');
newWebhook.customPOST($scope.newWebhook).then(function(resp) {
$scope.webhooks.push(resp);
@ -618,6 +549,44 @@ function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) {
$scope.webhooks.splice($scope.webhooks.indexOf(webhook), 1);
});
};
var fetchTokens = function() {
var tokensFetch = Restangular.one('repository/' + namespace + '/' + name + '/tokens/');
tokensFetch.get().then(function(resp) {
$scope.tokens = resp.tokens;
}, function() {
$scope.tokens = null;
});
};
var fetchPermissions = function(kind) {
var permissionsFetch = Restangular.one('repository/' + namespace + '/' + name + '/permissions/' + kind + '/');
permissionsFetch.get().then(function(resp) {
$scope.permissions[kind] = resp.permissions;
}, function() {
$scope.permissions[kind] = null;
});
};
var fetchRepository = function() {
$scope.repository = ApiService.at('repository', namespace, name).get(function(repo) {
$scope.repo = repo;
$rootScope.title = 'Settings - ' + namespace + '/' + name;
$rootScope.description = 'Administrator settings for ' + namespace + '/' + name +
': Permissions, webhooks and other settings';
// Fetch all the permissions and token info for the repository.
fetchPermissions('user');
fetchPermissions('team');
fetchTokens();
return $scope.repo;
});
};
// Fetch the repository.
fetchRepository();
}
function UserAdminCtrl($scope, $timeout, $location, Restangular, PlanService, UserService, KeyService, $routeParams) {
@ -774,6 +743,7 @@ function ImageViewCtrl($scope, $routeParams, $rootScope, Restangular) {
};
// Fetch the image.
$scope.loading = true;
var imageFetch = Restangular.one('repository/' + namespace + '/' + name + '/image/' + imageid);
imageFetch.get().then(function(image) {
$scope.loading = false;
@ -1259,7 +1229,7 @@ function TeamViewCtrl($rootScope, $scope, Restangular, $routeParams) {
function OrgsCtrl($scope, UserService) {
$scope.loading = true;
$scope.$watch( function () { return UserService.currentUser(); }, function (currentUser) {
$scope.$watch(function () { return UserService.currentUser(); }, function (currentUser) {
$scope.user = currentUser;
$scope.loading = false;
}, true);