From 35e2cecee15ca58f8babba7f9bfead62cb7556ef Mon Sep 17 00:00:00 2001 From: Richard Goater Date: Sun, 12 Mar 2017 13:24:41 -0400 Subject: [PATCH] feat(services): display clearer information about services --- app/components/containers/containers.html | 2 +- app/components/services/services.html | 6 ++-- app/components/services/servicesController.js | 35 ++++++++++++------- app/filters/filters.js | 9 +++++ app/models/service.js | 8 ++++- 5 files changed, 44 insertions(+), 16 deletions(-) diff --git a/app/components/containers/containers.html b/app/components/containers/containers.html index 5849e8ac2..39a754168 100644 --- a/app/components/containers/containers.html +++ b/app/components/containers/containers.html @@ -105,7 +105,7 @@ {{ container.Status }} {{ container|swarmcontainername}} {{ container|containername}} - {{ container.Image }} + {{ container.Image | hideshasum }} {{ container.IP ? container.IP : '-' }} {{ container.hostIP }} diff --git a/app/components/services/services.html b/app/components/services/services.html index df4b69047..6eb427ac6 100644 --- a/app/components/services/services.html +++ b/app/components/services/services.html @@ -70,11 +70,13 @@ {{ service.Name }} - {{ service.Image }} + {{ service.Image | hideshasum }} {{ service.Mode }} + {{ service.Running }} + / + {{ service.Replicas }} - {{ service.Replicas }} Scale diff --git a/app/components/services/servicesController.js b/app/components/services/servicesController.js index 850d5009f..13f63fff6 100644 --- a/app/components/services/servicesController.js +++ b/app/components/services/servicesController.js @@ -1,6 +1,6 @@ angular.module('services', []) -.controller('ServicesController', ['$q', '$scope', '$stateParams', '$state', 'Service', 'ServiceHelper', 'Messages', 'Pagination', 'Authentication', 'UserService', 'ModalService', 'ResourceControlService', -function ($q, $scope, $stateParams, $state, Service, ServiceHelper, Messages, Pagination, Authentication, UserService, ModalService, ResourceControlService) { +.controller('ServicesController', ['$q', '$scope', '$stateParams', '$state', 'Service', 'ServiceHelper', 'Messages', 'Pagination', 'Task', 'Node', 'Authentication', 'UserService', 'ModalService', 'ResourceControlService', +function ($q, $scope, $stateParams, $state, Service, ServiceHelper, Messages, Pagination, Task, Node, Authentication, UserService, ModalService, ResourceControlService) { $scope.state = {}; $scope.state.selectedItemCount = 0; $scope.state.pagination_count = Pagination.getPaginationCount('services'); @@ -127,30 +127,41 @@ function ($q, $scope, $stateParams, $state, Service, ServiceHelper, Messages, Pa function fetchServices() { $('#loadServicesSpinner').show(); + var userDetails = Authentication.getUserDetails(); $scope.user = userDetails; - Service.query({}, function (d) { - $scope.services = d.map(function (service) { - return new ServiceViewModel(service); + $q.all({ + services: Service.query({}).$promise, + tasks: Task.query({filters: {'desired-state': ['running']}}).$promise, + nodes: Node.query({}).$promise, + }) + .then(function success(data) { + $scope.services = data.services.map(function (service) { + var serviceTasks = data.tasks.filter(function (task) { + return task.ServiceID === service.ID; + }); + var taskNodes = data.nodes.filter(function (node) { + return node.Spec.Availability === 'active' && node.Status.State === 'ready'; + }); + return new ServiceViewModel(service, serviceTasks, taskNodes); }); if (userDetails.role === 1) { UserService.users() .then(function success(data) { mapUsersToServices(data); }) - .catch(function error(err) { - Messages.error("Failure", err, "Unable to retrieve users"); - }) .finally(function final() { $('#loadServicesSpinner').hide(); }); } - $('#loadServicesSpinner').hide(); - }, function(e) { - $('#loadServicesSpinner').hide(); - Messages.error("Failure", e, "Unable to retrieve services"); + }) + .catch(function error(err) { $scope.services = []; + Messages.error("Failure", err, "Unable to retrieve services"); + }) + .finally(function final() { + $('#loadServicesSpinner').hide(); }); } diff --git a/app/filters/filters.js b/app/filters/filters.js index ddfda05f1..075fa5902 100644 --- a/app/filters/filters.js +++ b/app/filters/filters.js @@ -228,4 +228,13 @@ angular.module('portainer.filters', []) } return ''; }; +}) +.filter('hideshasum', function () { + 'use strict'; + return function (imageName) { + if (imageName) { + return imageName.split('@sha')[0]; + } + return ''; + }; }); diff --git a/app/models/service.js b/app/models/service.js index b312e2d2c..156faefef 100644 --- a/app/models/service.js +++ b/app/models/service.js @@ -1,4 +1,4 @@ -function ServiceViewModel(data) { +function ServiceViewModel(data, runningTasks, nodes) { this.Model = data; this.Id = data.ID; this.Name = data.Spec.Name; @@ -9,6 +9,12 @@ function ServiceViewModel(data) { this.Replicas = data.Spec.Mode.Replicated.Replicas; } else { this.Mode = 'global'; + if (nodes) { + this.Replicas = nodes.length; + } + } + if (runningTasks) { + this.Running = runningTasks.length; } this.Labels = data.Spec.Labels; if (data.Spec.TaskTemplate.ContainerSpec) {