Add spin.js-based throbber for all loading
This commit is contained in:
parent
ee41f79bcc
commit
76d9cbc14f
8 changed files with 90 additions and 23 deletions
|
@ -1,3 +1,7 @@
|
|||
.loading {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.landing {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
|
|
@ -1,3 +1,31 @@
|
|||
// Register any plugin code.
|
||||
$.fn.spin = function(opts) {
|
||||
this.each(function() {
|
||||
var $this = $(this),
|
||||
spinner = $this.data('spinner');
|
||||
|
||||
if (spinner) spinner.stop();
|
||||
if (opts !== false) {
|
||||
options = {
|
||||
color: $this.css('color') || '#000',
|
||||
lines: 12, // The number of lines to draw
|
||||
length: 7, // The length of each line
|
||||
width: 4, // The line thickness
|
||||
radius: 10, // The radius of the inner circle
|
||||
speed: 1, // Rounds per second
|
||||
trail: 100, // Afterglow percentage
|
||||
shadow: false // Whether to render a shadow
|
||||
};
|
||||
|
||||
opts = $.extend(options, opts);
|
||||
spinner = new Spinner(opts).spin(this);
|
||||
$this.data('spinner', spinner);
|
||||
}
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
// Start the application code itself.
|
||||
quayApp = angular.module('quay', ['restangular', 'angularMoment'], function($provide) {
|
||||
$provide.factory('UserService', ['Restangular', function(Restangular) {
|
||||
var userResponse = {
|
||||
|
|
|
@ -78,11 +78,6 @@ function HeaderCtrl($scope, UserService) {
|
|||
}
|
||||
|
||||
function RepoListCtrl($scope, Restangular) {
|
||||
var repositoryFetch = Restangular.all('repository/');
|
||||
repositoryFetch.getList().then(function(resp) {
|
||||
$scope.repositories = resp.repositories;
|
||||
});
|
||||
|
||||
$scope.getCommentFirstLine = function(commentString) {
|
||||
return getMarkedDown(getFirstTextLine(commentString));
|
||||
};
|
||||
|
@ -91,6 +86,16 @@ function RepoListCtrl($scope, Restangular) {
|
|||
if (!string) { return ''; }
|
||||
return getMarkedDown(string);
|
||||
};
|
||||
|
||||
$('.spin').spin();
|
||||
$scope.loading = true;
|
||||
|
||||
// Load the list of repositories.
|
||||
var repositoryFetch = Restangular.all('repository/');
|
||||
repositoryFetch.getList().then(function(resp) {
|
||||
$scope.repositories = resp.repositories;
|
||||
$scope.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
function LandingCtrl($scope) {
|
||||
|
@ -162,25 +167,31 @@ function RepoCtrl($scope, Restangular, $routeParams, $rootScope) {
|
|||
var name = $routeParams.name;
|
||||
var tag = $routeParams.tag || 'latest';
|
||||
|
||||
$('.spin').spin();
|
||||
$scope.loading = true;
|
||||
|
||||
var repositoryFetch = Restangular.one('repository/' + namespace + '/' + name);
|
||||
repositoryFetch.get().then(function(repo) {
|
||||
$rootScope.title = namespace + '/' + name;
|
||||
$scope.repo = repo;
|
||||
$scope.currentTag = repo.tags[tag] || repo.tags['latest'];
|
||||
|
||||
var clip = new ZeroClipboard($('#copyClipboard'), { 'moviePath': 'static/lib/ZeroClipboard.swf' });
|
||||
clip.on('complete', function() {
|
||||
// Resets the animation.
|
||||
var elem = $('#clipboardCopied')[0];
|
||||
elem.style.display = 'none';
|
||||
var clip = new ZeroClipboard($('#copyClipboard'), { 'moviePath': 'static/lib/ZeroClipboard.swf' });
|
||||
clip.on('complete', function() {
|
||||
// Resets the animation.
|
||||
var elem = $('#clipboardCopied')[0];
|
||||
elem.style.display = 'none';
|
||||
|
||||
// Show the notification.
|
||||
setTimeout(function() {
|
||||
elem.style.display = 'block';
|
||||
}, 1);
|
||||
});
|
||||
|
||||
// Show the notification.
|
||||
setTimeout(function() {
|
||||
elem.style.display = 'block';
|
||||
}, 1);
|
||||
});
|
||||
$scope.loading = false;
|
||||
}, function() {
|
||||
$scope.repo = null;
|
||||
$scope.loading = false;
|
||||
$rootScope.title = 'Unknown Repository';
|
||||
});
|
||||
}
|
||||
|
@ -189,7 +200,7 @@ function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) {
|
|||
var namespace = $routeParams.namespace;
|
||||
var name = $routeParams.name;
|
||||
|
||||
$('#userSearch').typeahead({
|
||||
$('#userSearch').typeahead({
|
||||
name: 'users',
|
||||
remote: {
|
||||
url: '/api/users/%QUERY',
|
||||
|
@ -311,11 +322,19 @@ function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) {
|
|||
$('#cannotchangeModal').modal({});
|
||||
});
|
||||
};
|
||||
|
||||
$('.spin').spin();
|
||||
$scope.loading = true;
|
||||
|
||||
// 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);
|
||||
}, function() {
|
||||
$scope.permissions = null;
|
||||
$rootScope.title = 'Unknown Repository';
|
||||
$scope.loading = false;
|
||||
});
|
||||
|
||||
// Fetch the permissions.
|
||||
|
@ -323,8 +342,10 @@ function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) {
|
|||
permissionsFetch.get().then(function(resp) {
|
||||
$rootScope.title = 'Settings - ' + namespace + '/' + name;
|
||||
$scope.permissions = resp.permissions;
|
||||
$scope.loading = !($scope.permissions && $scope.repo);
|
||||
}, function() {
|
||||
$scope.permissions = null;
|
||||
$rootScope.title = 'Unknown Repository';
|
||||
$scope.loading = false;
|
||||
});
|
||||
}
|
1
static/lib/spin.min.js
vendored
Normal file
1
static/lib/spin.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
(function(a,b,c){function O(a){H(arguments,function(b,d){a[b]===c&&(a[b]=d)});return a}function N(a){H(arguments,function(b,c){a[m][M(a,b)||b]=c});return a}function M(a,b){var d=a[m],f,g;if(d[b]!==c){return b}b=b.charAt(0).toUpperCase()+b.slice(1);for(g=0;g<E[e];g++){f=E[g]+b;if(d[f]!==c){return f}}}function L(a,b){var c=[j,b,~~(a*100)].join("-"),d="{"+j+":"+a+"}",f;if(!F[c]){for(f=0;f<E[e];f++){try{K.insertRule("@"+(E[f]&&"-"+E[f].toLowerCase()+"-"||"")+"keyframes "+c+"{0%{"+j+":1}"+b+"%"+d+"to"+d+"}",K.cssRules[e])}catch(g){}}F[c]=1}return c}function J(a,b,c){c&&!c[t]&&J(a,c),a.insertBefore(b,c||null);return a}function I(a){var c=b.createElement(a||"div");H(arguments,function(a,b){c[a]=b});return c}function H(a,b){var c=~~((a[e]-1)/2);for(var d=1;d<=c;d++){b(a[d*2-1],a[d*2])}}var d="width",e="length",f="radius",g="lines",h="trail",i="color",j="opacity",k="speed",l="shadow",m="style",n="height",o="left",p="top",q="px",r="childNodes",s="firstChild",t="parentNode",u="position",v="relative",w="absolute",x="animation",y="transform",z="Origin",A="Timeout",B="coord",C="#000",D=m+"Sheets",E="webkit0Moz0ms0O".split(0),F={},G;J(b.getElementsByTagName("head")[0],I(m));var K=b[D][b[D][e]-1],P=function(a){this.opts=O(a||{},g,12,h,100,e,7,d,5,f,10,i,C,j,0.25,k,1)},Q=P.prototype={spin:function(b){var c=this,d=c.el=c[g](c.opts);b&&J(b,N(d,o,~~(b.offsetWidth/2)+q,p,~~(b.offsetHeight/2)+q),b[s]);if(!G){var e=c.opts,f=0,i=20/e[k],l=(1-e[j])/(i*e[h]/100),m=i/e[g];(function n(){f++;for(var b=e[g];b;b--){var h=Math.max(1-(f+b*m)%i*l,e[j]);c[j](d,e[g]-b,h,e)}c[A]=c.el&&a["set"+A](n,50)})()}return c},stop:function(){var b=this,d=b.el;a["clear"+A](b[A]),d&&d[t]&&d[t].removeChild(d),b.el=c;return b}};Q[g]=function(a){function s(b,c){return N(I(),u,w,d,a[e]+a[d]+q,n,a[d]+q,"background",b,"boxShadow",c,y+z,o,y,"rotate("+~~(360/a[g]*m)+"deg) translate("+a[f]+q+",0)","borderRadius","100em")}var b=N(I(),u,v),c=L(a[j],a[h]),m=0,r;for(;m<a[g];m++){r=N(I(),u,w,p,1+~(a[d]/2)+q,y,"translate3d(0,0,0)",x,c+" "+1/a[k]+"s linear infinite "+(1/a[g]/a[k]*m-1/a[k])+"s"),a[l]&&J(r,N(s(C,"0 0 4px "+C),p,2+q)),J(b,J(r,s(a[i],"0 0 1px rgba(0,0,0,.1)")))}return b},Q[j]=function(a,b,c){a[r][b][m][j]=c};var R="behavior",S="url(#default#VML)",T="group0roundrect0fill0stroke".split(0);(function(){var a=N(I(T[0]),R,S),b;if(!M(a,y)&&a.adj){for(b=0;b<T[e];b++){K.addRule(T[b],R+":"+S)}Q[g]=function(){function s(c,e,l){J(k,J(N(h(),"rotation",360/a[g]*c+"deg",o,~~e),J(N(I(T[1],"arcsize",1),d,b,n,a[d],o,a[f],p,-a[d]/2,"filter",l),I(T[2],i,a[i],j,a[j]),I(T[3],j,0))))}function h(){return N(I(T[0],B+"size",c+" "+c,B+z,-b+" "+-b),d,c,n,c)}var a=this.opts,b=a[e]+a[d],c=2*b,k=h(),m=~(a[e]+a[f]+a[d])+q,r;if(a[l]){for(r=1;r<=a[g];r++){s(r,-2,"progid:DXImage"+y+".Microsoft.Blur(pixel"+f+"=2,make"+l+"=1,"+l+j+"=.3)")}}for(r=1;r<=a[g];r++){s(r)}return J(N(I(),"margin",m+" 0 0 "+m,u,v),k)},Q[j]=function(a,b,c,d){d=d[l]&&d[g]||0,a[s][r][b+d][s][s][j]=c}}else{G=M(a,x)}})(),a.Spinner=P})(window,document);
|
|
@ -1,8 +1,12 @@
|
|||
<div class="container" ng-show="!repo || !permissions">
|
||||
<div class="loading" ng-show="loading">
|
||||
<div class="spin"></div>
|
||||
</div>
|
||||
|
||||
<div class="container" ng-show="!loading && (!repo || !permissions)">
|
||||
No repository found
|
||||
</div>
|
||||
|
||||
<div class="container repo repo-admin" ng-show="repo && permissions">
|
||||
<div class="container repo repo-admin" ng-show="!loading && repo && permissions">
|
||||
<div class="header">
|
||||
<a href="{{ '#/repository/' + repo.namespace + '/' + repo.name }}" class="back"><i class="icon-chevron-left"></i></a>
|
||||
<h3>
|
||||
|
@ -14,7 +18,7 @@
|
|||
<div class="panel panel-default">
|
||||
<div class="panel-heading">User Access Permissions</div>
|
||||
<div class="panel-body">
|
||||
|
||||
|
||||
<table class="permissions">
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
<div class="container">
|
||||
<div class="loading" ng-show="loading">
|
||||
<div class="spin"></div>
|
||||
</div>
|
||||
|
||||
<div class="container" ng-show="!loading">
|
||||
<h3>Repositories</h3>
|
||||
<div class="repo-listing" ng-repeat="repository in repositories">
|
||||
<i class="icon-hdd icon-large"></i>
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
<div class="container" ng-hide="repo">
|
||||
<div class="container" ng-show="!loading && !repo">
|
||||
No repository found
|
||||
</div>
|
||||
|
||||
<div class="container repo" ng-show="repo">
|
||||
<div class="loading" ng-show="loading">
|
||||
<div class="spin"></div>
|
||||
</div>
|
||||
|
||||
<div class="container repo" ng-show="!loading && repo">
|
||||
<!-- Repo Header -->
|
||||
<div class="header">
|
||||
<h3>
|
||||
|
@ -81,7 +85,7 @@
|
|||
|
||||
<div id="image-history" style="display: none">
|
||||
<div ng-hide="imageHistory">
|
||||
Loading images...
|
||||
<div class="spin"></div>
|
||||
</div>
|
||||
|
||||
<div ng-show="imageHistory">
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
<script src="static/lib/ZeroClipboard.min.js"></script>
|
||||
<script src="static/lib/typeahead.min.js"></script>
|
||||
<script src="static/lib/spin.min.js"></script>
|
||||
|
||||
<script src="static/js/app.js"></script>
|
||||
<script src="static/js/controllers.js"></script>
|
||||
|
|
Reference in a new issue