diff --git a/index.html b/index.html
index 6f8537ccb..6945c1bf9 100644
--- a/index.html
+++ b/index.html
@@ -51,6 +51,7 @@
+
diff --git a/js/controllers.js b/js/controllers.js
index 63fc8d319..335597cf5 100644
--- a/js/controllers.js
+++ b/js/controllers.js
@@ -4,7 +4,6 @@ function MastheadController($scope) {
}
function DashboardController($scope, Container) {
-
}
function StatusBarController($scope, Settings) {
@@ -20,7 +19,7 @@ function SideBarController($scope, Container, Settings) {
$scope.endpoint = Settings.endpoint;
Container.query({all: 0}, function(d) {
- $scope.containers = d;
+ $scope.containers = d;
});
}
@@ -46,11 +45,11 @@ function SettingsController($scope, Auth, System, Docker, Settings) {
}, function(e) {
console.log(e);
setFailedResponse($scope, e.data, '#response');
- });
- };
+ });
+ };
Auth.get({}, function(d) {
- $scope.auth = d;
+ $scope.auth = d;
});
Docker.get({}, function(d) {
@@ -117,34 +116,36 @@ function ContainerController($scope, $routeParams, $location, Container) {
$scope.getChanges = function() {
Container.changes({id: $routeParams.id}, function(d) {
- $scope.changes = d;
+ $scope.changes = d;
});
};
Container.get({id: $routeParams.id}, function(d) {
- $scope.container = d;
+ $scope.container = d;
}, function(e) {
console.log(e);
setFailedResponse($scope, e.data, '#response');
if (e.status === 404) {
$('.detail').hide();
}
- });
+ });
$scope.getChanges();
}
// Controller for the list of containers
-function ContainersController($scope, Container, Settings) {
+function ContainersController($scope, Container, Settings, ViewSpinner) {
$scope.displayAll = Settings.displayAll;
$scope.predicate = '-Created';
var update = function(data) {
+ ViewSpinner.spin();
Container.query(data, function(d) {
- $scope.containers = d;
- });
+ $scope.containers = d;
+ ViewSpinner.stop();
+ });
};
-
+
$scope.toggleGetAll = function() {
Settings.displayAll = $scope.displayAll;
var u = update;
@@ -156,11 +157,11 @@ function ContainersController($scope, Container, Settings) {
u(data);
};
- update({all: $scope.displayAll ? 1 : 0});
+ update({all: $scope.displayAll ? 1 : 0});
}
// Controller for the list of images
-function ImagesController($scope, Image) {
+function ImagesController($scope, Image, ViewSpinner) {
$scope.predicate = '-Created';
$('#response').hide();
$scope.alertClass = 'block';
@@ -169,11 +170,14 @@ function ImagesController($scope, Image) {
$('#build-modal').modal('show');
};
+ ViewSpinner.spin();
Image.query({}, function(d) {
$scope.images = d;
+ ViewSpinner.stop();
}, function (e) {
console.log(e);
setFailedResponse($scope, e.data, '#response');
+ ViewSpinner.stop();
});
}
@@ -285,7 +289,7 @@ function BuilderController($scope, Dockerfile) {
$scope.build = function() {
Dockerfile.build(editor.getValue(), function(e) {
- console.log(e);
+ console.log(e);
});
};
}
diff --git a/js/services.js b/js/services.js
index d14af9e78..cddac3f98 100644
--- a/js/services.js
+++ b/js/services.js
@@ -62,14 +62,23 @@ angular.module('dockerui.services', ['ngResource'])
displayAll: false,
endpoint: DOCKER_ENDPOINT,
version: DOCKER_API_VERSION,
- rawUrl: DOCKER_ENDPOINT + '/' + DOCKER_API_VERSION,
+ rawUrl: DOCKER_ENDPOINT + DOCKER_PORT + '/' + DOCKER_API_VERSION,
uiVersion: UI_VERSION,
url: url
};
})
+ .factory('ViewSpinner', function() {
+ var spinner = new Spinner();
+ var target = document.getElementById('view');
+
+ return {
+ spin: function() { spinner.spin(target); },
+ stop: function() { spinner.stop(); }
+ };
+ })
.factory('Dockerfile', function(Settings) {
+ var url = Settings.rawUrl + '/build';
return {
- settings: Settings,
build: function(file, callback) {
var data = new FormData();
var dockerfile = new Blob([file], { type: 'text/text' });
@@ -77,7 +86,7 @@ angular.module('dockerui.services', ['ngResource'])
var request = new XMLHttpRequest();
request.onload = callback;
- request.open('POST', 'http://192.168.1.9:4243/v1.1/build');
+ request.open('POST', url);
request.send(data);
}
};
diff --git a/lib/spin.js b/lib/spin.js
new file mode 100644
index 000000000..c66c607a7
--- /dev/null
+++ b/lib/spin.js
@@ -0,0 +1,349 @@
+//fgnass.github.com/spin.js#v1.3
+
+/**
+ * Copyright (c) 2011-2013 Felix Gnass
+ * Licensed under the MIT license
+ */
+(function(root, factory) {
+
+ /* CommonJS */
+ if (typeof exports == 'object') module.exports = factory()
+
+ /* AMD module */
+ else if (typeof define == 'function' && define.amd) define(factory)
+
+ /* Browser global */
+ else root.Spinner = factory()
+}
+(this, function() {
+ "use strict";
+
+ var prefixes = ['webkit', 'Moz', 'ms', 'O'] /* Vendor prefixes */
+ , animations = {} /* Animation rules keyed by their name */
+ , useCssAnimations /* Whether to use CSS animations or setTimeout */
+
+ /**
+ * Utility function to create elements. If no tag name is given,
+ * a DIV is created. Optionally properties can be passed.
+ */
+ function createEl(tag, prop) {
+ var el = document.createElement(tag || 'div')
+ , n
+
+ for(n in prop) el[n] = prop[n]
+ return el
+ }
+
+ /**
+ * Appends children and returns the parent.
+ */
+ function ins(parent /* child1, child2, ...*/) {
+ for (var i=1, n=arguments.length; i> 1) : parseInt(o.left, 10) + mid) + 'px',
+ top: (o.top == 'auto' ? tp.y-ep.y + (target.offsetHeight >> 1) : parseInt(o.top, 10) + mid) + 'px'
+ })
+ }
+
+ el.setAttribute('role', 'progressbar')
+ self.lines(el, self.opts)
+
+ if (!useCssAnimations) {
+ // No CSS animation support, use setTimeout() instead
+ var i = 0
+ , start = (o.lines - 1) * (1 - o.direction) / 2
+ , alpha
+ , fps = o.fps
+ , f = fps/o.speed
+ , ostep = (1-o.opacity) / (f*o.trail / 100)
+ , astep = f/o.lines
+
+ ;(function anim() {
+ i++;
+ for (var j = 0; j < o.lines; j++) {
+ alpha = Math.max(1 - (i + (o.lines - j) * astep) % f * ostep, o.opacity)
+
+ self.opacity(el, j * o.direction + start, alpha, o)
+ }
+ self.timeout = self.el && setTimeout(anim, ~~(1000/fps))
+ })()
+ }
+ return self
+ },
+
+ /**
+ * Stops and removes the Spinner.
+ */
+ stop: function() {
+ var el = this.el
+ if (el) {
+ clearTimeout(this.timeout)
+ if (el.parentNode) el.parentNode.removeChild(el)
+ this.el = undefined
+ }
+ return this
+ },
+
+ /**
+ * Internal method that draws the individual lines. Will be overwritten
+ * in VML fallback mode below.
+ */
+ lines: function(el, o) {
+ var i = 0
+ , start = (o.lines - 1) * (1 - o.direction) / 2
+ , seg
+
+ function fill(color, shadow) {
+ return css(createEl(), {
+ position: 'absolute',
+ width: (o.length+o.width) + 'px',
+ height: o.width + 'px',
+ background: color,
+ boxShadow: shadow,
+ transformOrigin: 'left',
+ transform: 'rotate(' + ~~(360/o.lines*i+o.rotate) + 'deg) translate(' + o.radius+'px' +',0)',
+ borderRadius: (o.corners * o.width>>1) + 'px'
+ })
+ }
+
+ for (; i < o.lines; i++) {
+ seg = css(createEl(), {
+ position: 'absolute',
+ top: 1+~(o.width/2) + 'px',
+ transform: o.hwaccel ? 'translate3d(0,0,0)' : '',
+ opacity: o.opacity,
+ animation: useCssAnimations && addAnimation(o.opacity, o.trail, start + i * o.direction, o.lines) + ' ' + 1/o.speed + 's linear infinite'
+ })
+
+ if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'}))
+
+ ins(el, ins(seg, fill(o.color, '0 0 1px rgba(0,0,0,.1)')))
+ }
+ return el
+ },
+
+ /**
+ * Internal method that adjusts the opacity of a single line.
+ * Will be overwritten in VML fallback mode below.
+ */
+ opacity: function(el, i, val) {
+ if (i < el.childNodes.length) el.childNodes[i].style.opacity = val
+ }
+
+ })
+
+
+ function initVML() {
+
+ /* Utility function to create a VML tag */
+ function vml(tag, attr) {
+ return createEl('<' + tag + ' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">', attr)
+ }
+
+ // No CSS transforms but VML support, add a CSS rule for VML elements:
+ sheet.addRule('.spin-vml', 'behavior:url(#default#VML)')
+
+ Spinner.prototype.lines = function(el, o) {
+ var r = o.length+o.width
+ , s = 2*r
+
+ function grp() {
+ return css(
+ vml('group', {
+ coordsize: s + ' ' + s,
+ coordorigin: -r + ' ' + -r
+ }),
+ { width: s, height: s }
+ )
+ }
+
+ var margin = -(o.width+o.length)*2 + 'px'
+ , g = css(grp(), {position: 'absolute', top: margin, left: margin})
+ , i
+
+ function seg(i, dx, filter) {
+ ins(g,
+ ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),
+ ins(css(vml('roundrect', {arcsize: o.corners}), {
+ width: r,
+ height: o.width,
+ left: o.radius,
+ top: -o.width>>1,
+ filter: filter
+ }),
+ vml('fill', {color: o.color, opacity: o.opacity}),
+ vml('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change
+ )
+ )
+ )
+ }
+
+ if (o.shadow)
+ for (i = 1; i <= o.lines; i++)
+ seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)')
+
+ for (i = 1; i <= o.lines; i++) seg(i)
+ return ins(el, g)
+ }
+
+ Spinner.prototype.opacity = function(el, i, val, o) {
+ var c = el.firstChild
+ o = o.shadow && o.lines || 0
+ if (c && i+o < c.childNodes.length) {
+ c = c.childNodes[i+o]; c = c && c.firstChild; c = c && c.firstChild
+ if (c) c.opacity = val
+ }
+ }
+ }
+
+ var probe = css(createEl('group'), {behavior: 'url(#default#VML)'})
+
+ if (!vendor(probe, 'transform') && probe.adj) initVML()
+ else useCssAnimations = vendor(probe, 'animation')
+
+ return Spinner
+
+}));