From b069616da2d6c1a7c073b788d1e0babd967e71fa Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Tue, 18 Jun 2013 19:08:17 -0900 Subject: [PATCH 1/5] Add batch ops to images --- index.html | 1 + js/controllers.js | 21 +++++++++++++++++++-- js/services.js | 2 +- js/viewmodel.js | 8 ++++++++ partials/images.html | 14 ++++++++++++-- 5 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 js/viewmodel.js diff --git a/index.html b/index.html index 6945c1bf9..78ba4134d 100644 --- a/index.html +++ b/index.html @@ -59,6 +59,7 @@ + diff --git a/js/controllers.js b/js/controllers.js index 335597cf5..7943a97ea 100644 --- a/js/controllers.js +++ b/js/controllers.js @@ -165,14 +165,31 @@ function ImagesController($scope, Image, ViewSpinner) { $scope.predicate = '-Created'; $('#response').hide(); $scope.alertClass = 'block'; + $scope.toggle = false; $scope.showBuilder = function() { $('#build-modal').modal('show'); }; + $scope.removeAction = function() { + angular.forEach($scope.images, function(i) { + if (i.Checked) { + Image.remove({id: i.Id}, function(d) { + console.log(d); + }); + } + }); + }; + + $scope.toggleSelectAll = function() { + angular.forEach($scope.images, function(i) { + i.Checked = $scope.toggle; + }); + }; + ViewSpinner.spin(); Image.query({}, function(d) { - $scope.images = d; + $scope.images = d.map(function(item) { return new ImageViewModel(item); }); ViewSpinner.stop(); }, function (e) { console.log(e); @@ -188,7 +205,7 @@ function ImageController($scope, $routeParams, $location, Image) { $('#response').hide(); $scope.alertClass = 'block'; - + $scope.remove = function() { if (confirm("Are you sure you want to delete this image?")) { Image.remove({id: $routeParams.id}, function(d) { diff --git a/js/services.js b/js/services.js index cddac3f98..6aee21839 100644 --- a/js/services.js +++ b/js/services.js @@ -28,7 +28,7 @@ angular.module('dockerui.services', ['ngResource']) insert :{method: 'POST', params: {id: '@id', action:'insert'}}, push :{method: 'POST', params: {id: '@id', action:'push'}}, tag :{method: 'POST', params: {id: '@id', action:'tag', force: 0, repo: '@repo'}}, - delete :{id: '@id', method: 'DELETE'} + remove :{method: 'DELETE', params: {id: '@id'}, isArray: true} }); }) .factory('Docker', function($resource, Settings) { diff --git a/js/viewmodel.js b/js/viewmodel.js new file mode 100644 index 000000000..11560ab2d --- /dev/null +++ b/js/viewmodel.js @@ -0,0 +1,8 @@ + +function ImageViewModel(data) { + this.Id = data.Id; + this.Tag = data.Tag; + this.Repository = data.Repository; + this.Created = data.Created; + this.Checked = false; +} diff --git a/partials/images.html b/partials/images.html index 7dafb8a4a..6aea8a2bd 100644 --- a/partials/images.html +++ b/partials/images.html @@ -7,10 +7,19 @@ {{ response }} -Build Image + + @@ -19,7 +28,8 @@ - + + From 2d199eec5d01ba7d20f5eee7dcfe615be90c207f Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Wed, 19 Jun 2013 12:18:54 -0900 Subject: [PATCH 2/5] Add container size --- README.md | 2 ++ js/filters.js | 12 +++++++++++- partials/containers.html | 2 ++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4f69b1753..20f7b1ffb 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,8 @@ DockerUI currently supports the v1.1 Remote API ###Stack * Angular.js * Flatstrap ( Flat Twitter Bootstrap ) +* Spin.js +* Ace editor ###Todo: diff --git a/js/filters.js b/js/filters.js index bac632e30..35969e815 100644 --- a/js/filters.js +++ b/js/filters.js @@ -53,10 +53,20 @@ angular.module('dockerui.filters', []) return ''; }; }) + .filter('humansize', function() { + return function(bytes) { + var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; + if (bytes == 0) { + return 'n/a'; + } + var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024))); + return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[[i]]; + }; + }) .filter('getdate', function() { return function(data) { //Multiply by 1000 for the unix format var date = new Date(data * 1000); return date.toDateString(); - }; + }; }); diff --git a/partials/containers.html b/partials/containers.html index aaf8aaf4c..3af32b232 100644 --- a/partials/containers.html +++ b/partials/containers.html @@ -11,6 +11,7 @@ + @@ -20,6 +21,7 @@ + From dd8c4ce6726a068200ed95470a0f6400f5e39c7e Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Wed, 19 Jun 2013 12:39:33 -0900 Subject: [PATCH 3/5] Add size and actions to container view --- js/controllers.js | 38 +++++++++++++++++++++++++++++++++++--- js/viewmodel.js | 10 ++++++++++ partials/containers.html | 20 ++++++++++++++++++-- 3 files changed, 63 insertions(+), 5 deletions(-) diff --git a/js/controllers.js b/js/controllers.js index 7943a97ea..af8817d50 100644 --- a/js/controllers.js +++ b/js/controllers.js @@ -68,8 +68,7 @@ function ContainerController($scope, $routeParams, $location, Container) { $scope.start = function(){ Container.start({id: $routeParams.id}, function(d) { - console.log(d); - setSuccessfulResponse($scope, 'Container started.', '#response'); + console.log(d); setSuccessfulResponse($scope, 'Container started.', '#response'); }, function(e) { console.log(e); setFailedResponse($scope, e.data, '#response'); @@ -137,14 +136,31 @@ function ContainerController($scope, $routeParams, $location, Container) { function ContainersController($scope, Container, Settings, ViewSpinner) { $scope.displayAll = Settings.displayAll; $scope.predicate = '-Created'; + $scope.toggle = false; var update = function(data) { ViewSpinner.spin(); Container.query(data, function(d) { - $scope.containers = d; + $scope.containers = d.map(function(item) { return new ContainerViewModel(item); }); ViewSpinner.stop(); }); }; + + var batch = function(items, action) { + angular.forEach(items, function(c) { + if (c.Checked) { + action({id: c.Id}, function(d) { + console.log(d); + }); + } + }); + }; + + $scope.toggleSelectAll = function() { + angular.forEach($scope.containers, function(i) { + i.Checked = $scope.toggle; + }); + }; $scope.toggleGetAll = function() { Settings.displayAll = $scope.displayAll; @@ -157,6 +173,22 @@ function ContainersController($scope, Container, Settings, ViewSpinner) { u(data); }; + $scope.startAction = function() { + batch($scope.containers, Container.start); + }; + + $scope.stopAction = function() { + batch($scope.containers, Container.stop); + }; + + $scope.killAction = function() { + batch($scope.containers, Container.kill); + }; + + $scope.removeAction = function() { + batch($scope.containers, Container.remove); + }; + update({all: $scope.displayAll ? 1 : 0}); } diff --git a/js/viewmodel.js b/js/viewmodel.js index 11560ab2d..20763a255 100644 --- a/js/viewmodel.js +++ b/js/viewmodel.js @@ -6,3 +6,13 @@ function ImageViewModel(data) { this.Created = data.Created; this.Checked = false; } + +function ContainerViewModel(data) { + this.Id = data.Id; + this.Image = data.Image; + this.Command = data.Command; + this.Created = data.Created; + this.SizeRw = data.SizeRw; + this.Status = data.Status; + this.Checked = false; +} diff --git a/partials/containers.html b/partials/containers.html index 3af32b232..77f42be62 100644 --- a/partials/containers.html +++ b/partials/containers.html @@ -1,12 +1,27 @@

Containers:

-
- Display All +
+ + +
+ Display All +
Action Id Tag Repository
{{ image.Id|truncate:10}}{{ image.Id|truncate:20}} {{ image.Tag }} {{ image.Repository }} {{ image.Created|getdate }}Image Command CreatedSize Status
{{ container.Image }} {{ container.Command|truncate:40 }} {{ container.Created|getdate }}{{ container.SizeRw|humansize }} {{ container.Status }}
+ @@ -17,6 +32,7 @@ + From 37ea44a4dc4370a98b4fce0460ecaa87fe2e659c Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Wed, 19 Jun 2013 17:40:58 -0900 Subject: [PATCH 4/5] Add message view and controller --- css/app.css | 7 +++++- index.html | 1 + js/controllers.js | 49 ++++++++++++++++++++++++++++++++++++------ js/services.js | 8 +++++++ partials/images.html | 4 ---- partials/messages.html | 3 +++ 6 files changed, 61 insertions(+), 11 deletions(-) create mode 100644 partials/messages.html diff --git a/css/app.css b/css/app.css index 183e4b127..dc0d0731e 100644 --- a/css/app.css +++ b/css/app.css @@ -94,7 +94,7 @@ } .footer { - max-height:6px; + max-height:6px; } #response { @@ -108,3 +108,8 @@ border: 1px solid #DDD; margin-top: 5px; } + +.messages { + overflow: scroll; + max-height: 50px; +} diff --git a/index.html b/index.html index 78ba4134d..02b1f4ea0 100644 --- a/index.html +++ b/index.html @@ -29,6 +29,7 @@
+
diff --git a/js/controllers.js b/js/controllers.js index af8817d50..f942f12e4 100644 --- a/js/controllers.js +++ b/js/controllers.js @@ -6,6 +6,21 @@ function MastheadController($scope) { function DashboardController($scope, Container) { } +function MessageController($scope, Messages) { + $scope.template = 'partials/messages.html'; + $scope.messages = []; + $scope.$watch('messages.length', function(o, n) { + $('#message-display').show(); + }); + + $scope.$on(Messages.event, function(e, msg) { + $scope.messages.push(msg); + setTimeout(function() { + $('#message-display').hide('slow'); + }, 10000); + }); +} + function StatusBarController($scope, Settings) { $scope.template = 'partials/statusbar.html'; @@ -20,7 +35,7 @@ function SideBarController($scope, Container, Settings) { Container.query({all: 0}, function(d) { $scope.containers = d; - }); + }); } function SettingsController($scope, Auth, System, Docker, Settings) { @@ -193,21 +208,41 @@ function ContainersController($scope, Container, Settings, ViewSpinner) { } // Controller for the list of images -function ImagesController($scope, Image, ViewSpinner) { +function ImagesController($scope, Image, ViewSpinner, Messages) { $scope.predicate = '-Created'; $('#response').hide(); $scope.alertClass = 'block'; $scope.toggle = false; + $scope.respones = []; $scope.showBuilder = function() { $('#build-modal').modal('show'); }; $scope.removeAction = function() { + ViewSpinner.spin(); + var counter = 0; + var complete = function() { + counter = counter - 1; + if (counter === 0) { + ViewSpinner.stop(); + } + }; angular.forEach($scope.images, function(i) { if (i.Checked) { + counter = counter + 1; Image.remove({id: i.Id}, function(d) { console.log(d); + angular.forEach(d, function(resource) { + Messages.send({class: 'text-success', data: 'Deleted: ' + resource.Deleted}); + }); + var index = $scope.images.indexOf(i); + $scope.images.splice(index, 1); + complete(); + }, function(e) { + console.log(e); + Messages.send({class: 'text-error', data: e.data}); + complete(); }); } }); @@ -225,7 +260,7 @@ function ImagesController($scope, Image, ViewSpinner) { ViewSpinner.stop(); }, function (e) { console.log(e); - setFailedResponse($scope, e.data, '#response'); + setFailedResponses($scope, e.data, '#response'); ViewSpinner.stop(); }); } @@ -331,14 +366,16 @@ function StartContainerController($scope, $routeParams, $location, Container) { }; } -function BuilderController($scope, Dockerfile) { +function BuilderController($scope, Dockerfile, Messages) { $scope.template = '/partials/builder.html'; ace.config.set('basePath', '/lib/ace-builds/src-noconflict/'); $scope.build = function() { - Dockerfile.build(editor.getValue(), function(e) { - console.log(e); + Dockerfile.build(editor.getValue(), function(d) { + Messages.send({class:'text-info', data: d}); + }, function(e) { + Messages.send({class:'text-error', data: e}); }); }; } diff --git a/js/services.js b/js/services.js index 6aee21839..a59da988c 100644 --- a/js/services.js +++ b/js/services.js @@ -76,6 +76,14 @@ angular.module('dockerui.services', ['ngResource']) stop: function() { spinner.stop(); } }; }) + .factory('Messages', function($rootScope) { + return { + event: 'messageSend', + send: function(msg) { + $rootScope.$broadcast('messageSend', msg); + } + }; + }) .factory('Dockerfile', function(Settings) { var url = Settings.rawUrl + '/build'; return { diff --git a/partials/images.html b/partials/images.html index 6aea8a2bd..eb15b6504 100644 --- a/partials/images.html +++ b/partials/images.html @@ -3,10 +3,6 @@

Images:

-
- {{ response }} -
-
Action Id Image Command
{{ container.Id|truncate:10}} {{ container.Image }} {{ container.Command|truncate:40 }}
- + diff --git a/partials/image.html b/partials/image.html index 4ff58ac92..ef48d6bda 100644 --- a/partials/image.html +++ b/partials/image.html @@ -1,8 +1,3 @@ -
- {{ response }} -
- -
diff --git a/partials/images.html b/partials/images.html index eb15b6504..df661da55 100644 --- a/partials/images.html +++ b/partials/images.html @@ -15,7 +15,7 @@
Action Action Id Image Command
- + diff --git a/partials/settings.html b/partials/settings.html index 122ee5855..93430a08d 100644 --- a/partials/settings.html +++ b/partials/settings.html @@ -1,8 +1,4 @@
-
- {{ response }} -
-

Docker Information

diff --git a/partials/startcontainer.html b/partials/startcontainer.html index 41293a952..24081af8f 100644 --- a/partials/startcontainer.html +++ b/partials/startcontainer.html @@ -4,9 +4,6 @@

Create Container

Action Action Id Tag Repository