{"action":"created","comment":{"url":"https://api.github.com/repos/zendesk/samson/pulls/comments/48729985","id":48729985,"diff_hunk":"@@ -1,15 +1,184 @@\n-samson.controller('KubernetesDashboardCtrl', function($scope, $stateParams, SseFactory) {\n-  $scope.project_id = $stateParams.project_id;\n-  $scope.messages = [];\n-\n-  function init() {\n-    // Subscribe to the SSE channel for K8s\n-    SseFactory.on('k8s', function(msg) {\n-      console.log(\"Got SSE msg: \", msg);\n-      $scope.messages.push(JSON.stringify(msg));\n-      _.defer(function() { $scope.$apply(); });\n-    });\n-  }\n-\n-  init();\n-});\n+samson.controller('KubernetesDashboardCtrl',\n+  function($rootScope, $scope, $stateParams, $q, environmentsService, kubernetesService, SseFactory, notificationService) {\n+    $scope.project_id = $stateParams.project_id;\n+    $scope.environments = [];\n+    $scope.messages = [];\n+    $scope.dashboard_data = [];\n+    $scope.environment = undefined;\n+    $scope.loadingEnvironments = false;\n+    $scope.loadingClusterState = false;\n+\n+    $scope.reloadDashboardData = function() {\n+      loadClusterState();\n+    };\n+\n+    $scope.environmentChanged = function(env) {\n+      $scope.environment = env;\n+      loadClusterState();\n+    };\n+\n+    $scope.dashboardReady = function() {\n+      return !$scope.loadingEnvironments && !$scope.loadingClusterState;\n+    };\n+\n+    $scope.empty = function(collection) {\n+      return _.isUndefinedOrEmpty(collection);\n+    };\n+\n+    $scope.notEmpty = function(collection) {\n+      return _.isNotUndefinedOrEmpty(collection);\n+    };\n+\n+    function init() {\n+      // Chaining the several promises (they should be resolved sequentially)\n+      loadEnvironments()\n+        .then(function() {\n+            return loadClusterState();\n+          }\n+        )\n+        .then(function() {\n+            startListeningForUpdates()\n+          }\n+        );\n+    }\n+\n+    init();\n+\n+    /*\n+     Controller private functions.\n+     */\n+\n+    function loadEnvironments() {\n+      $scope.loadingEnvironments = true;\n+\n+      var deferred = $q.defer();\n+      environmentsService.loadEnvironments($scope.project_id).then(\n+        function(environments) {\n+          $scope.loadingEnvironments = false;\n+          $scope.environments = environments;\n+\n+          // Selects the production environment by default\n+          var default_environment = _.findWhere(environments, {'is_production': true});\n+          $scope.environment = _.isDefined(default_environment) ? default_environment : environments[0];\n+\n+          deferred.resolve();\n+        },\n+        function(result) {\n+          $scope.loadingEnvironments = false;\n+          result.messages.map(function(message) {\n+            notificationService.error(message);\n+          });\n+          deferred.reject();\n+        }\n+      );\n+\n+      return deferred.promise;\n+    }\n+\n+    function loadClusterState() {\n+      $scope.loadingClusterState = true;\n+      $scope.dashboard_data = [];\n+\n+      var deferred = $q.defer();\n+      kubernetesService.loadDashboardData($scope.project_id, $scope.environment).then(\n+        function(data) {\n+          $scope.loadingClusterState = false;\n+          if (_.isNotUndefinedOrEmpty(data)) {\n+            $scope.dashboard_data = data;\n+            deferred.resolve();\n+          }\n+          else {\n+            deferred.reject();\n+          }\n+        },\n+        function(result) {\n+          $scope.loadingClusterState = false;\n+          result.messages.map(function(message) {\n+            notificationService.error(message);\n+          });\n+          deferred.reject();\n+        }\n+      );\n+\n+      return deferred.promise;\n+    }\n+\n+    function startListeningForUpdates() {\n+      SseFactory.on('k8s', function(msg) {\n+        var role = findOrCreateRole(msg);\n+        var deploy_group = findOrCreateDeployGroup(role, msg);\n+        var release = findOrCreateRelease(deploy_group, msg);\n+        updateReleaseState(release, msg);\n+      });\n+    }\n+\n+    function findOrCreateRole(msg) {\n+      var role = findRole(msg.role);\n+\n+      if (_.isUndefined(role)) {\n+        role = {\n+          name: msg.role,\n+          deploy_groups: []\n+        };\n+        $scope.dashboard_data.push(role);\n+      }\n+\n+      return role;\n+    }\n+\n+    function findOrCreateDeployGroup(role, msg) {\n+      if (_.isDefined(role)) {\n+        var deploy_group = findDeployGroup(role, msg.deploy_group);\n+\n+        if (_.isUndefined(deploy_group)) {\n+          deploy_group = {\n+            name: msg.deploy_group,\n+            releases: []\n+          };\n+          role.deploy_groups.push(deploy_group);\n+        }\n+\n+        return deploy_group;\n+      }\n+    }\n+\n+    function findOrCreateRelease(deploy_group, msg) {\n+      if (_.isDefined(deploy_group)) {","path":"plugins/kubernetes/app/assets/javascripts/kubernetes/controllers/kubernetes_dashboard_ctrl.js","position":161,"original_position":161,"commit_id":"d9e90879960dd5561104939e598f142d1c296efb","original_commit_id":"d9e90879960dd5561104939e598f142d1c296efb","user":{"login":"sbrnunes","id":2833020,"avatar_url":"https://avatars.githubusercontent.com/u/2833020?v=3","gravatar_id":"","url":"https://api.github.com/users/sbrnunes","html_url":"https://github.com/sbrnunes","followers_url":"https://api.github.com/users/sbrnunes/followers","following_url":"https://api.github.com/users/sbrnunes/following{/other_user}","gists_url":"https://api.github.com/users/sbrnunes/gists{/gist_id}","starred_url":"https://api.github.com/users/sbrnunes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sbrnunes/subscriptions","organizations_url":"https://api.github.com/users/sbrnunes/orgs","repos_url":"https://api.github.com/users/sbrnunes/repos","events_url":"https://api.github.com/users/sbrnunes/events{/privacy}","received_events_url":"https://api.github.com/users/sbrnunes/received_events","type":"User","site_admin":false},"body":"Good catch.\r\n\r\nThis is old code, added before I started creating the data myself when it didn't exist.","created_at":"2016-01-04T13:28:00Z","updated_at":"2016-01-04T13:28:00Z","html_url":"https://github.com/zendesk/samson/pull/685#discussion_r48729985","pull_request_url":"https://api.github.com/repos/zendesk/samson/pulls/685","_links":{"self":{"href":"https://api.github.com/repos/zendesk/samson/pulls/comments/48729985"},"html":{"href":"https://github.com/zendesk/samson/pull/685#discussion_r48729985"},"pull_request":{"href":"https://api.github.com/repos/zendesk/samson/pulls/685"}}},"pull_request":{"url":"https://api.github.com/repos/zendesk/samson/pulls/685","id":53150753,"html_url":"https://github.com/zendesk/samson/pull/685","diff_url":"https://github.com/zendesk/samson/pull/685.diff","patch_url":"https://github.com/zendesk/samson/pull/685.patch","issue_url":"https://api.github.com/repos/zendesk/samson/issues/685","number":685,"state":"open","locked":false,"title":"Kubernetes Dashboard Page","user":{"login":"sbrnunes","id":2833020,"avatar_url":"https://avatars.githubusercontent.com/u/2833020?v=3","gravatar_id":"","url":"https://api.github.com/users/sbrnunes","html_url":"https://github.com/sbrnunes","followers_url":"https://api.github.com/users/sbrnunes/followers","following_url":"https://api.github.com/users/sbrnunes/following{/other_user}","gists_url":"https://api.github.com/users/sbrnunes/gists{/gist_id}","starred_url":"https://api.github.com/users/sbrnunes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sbrnunes/subscriptions","organizations_url":"https://api.github.com/users/sbrnunes/orgs","repos_url":"https://api.github.com/users/sbrnunes/repos","events_url":"https://api.github.com/users/sbrnunes/events{/privacy}","received_events_url":"https://api.github.com/users/sbrnunes/received_events","type":"User","site_admin":false},"body":"PR containing the Kubernetes dashboard page. \r\n\r\nWhenever a deploying is in progress, if a User is in the dashboard page he will see the updates from the cluster coming through.\r\n\r\n/cc @msufa, @henders, @jonmoter \r\n\r\n![screenshot 2015-12-14 19 07 00](https://cloud.githubusercontent.com/assets/2833020/11790780/673c3c38-a295-11e5-93df-2761a60ac10b.png)\r\n\r\n\r\n\r\n\r\n\r\n\r\n","created_at":"2015-12-09T17:26:36Z","updated_at":"2016-01-04T13:28:00Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c607d17aed8f2a660d6f27ce58d0f615e4d3bb42","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/zendesk/samson/pulls/685/commits","review_comments_url":"https://api.github.com/repos/zendesk/samson/pulls/685/comments","review_comment_url":"https://api.github.com/repos/zendesk/samson/pulls/comments{/number}","comments_url":"https://api.github.com/repos/zendesk/samson/issues/685/comments","statuses_url":"https://api.github.com/repos/zendesk/samson/statuses/d9e90879960dd5561104939e598f142d1c296efb","head":{"label":"zendesk:sbrnunes/kubernetes-dashboard-page","ref":"sbrnunes/kubernetes-dashboard-page","sha":"d9e90879960dd5561104939e598f142d1c296efb","user":{"login":"zendesk","id":11525,"avatar_url":"https://avatars.githubusercontent.com/u/11525?v=3","gravatar_id":"","url":"https://api.github.com/users/zendesk","html_url":"https://github.com/zendesk","followers_url":"https://api.github.com/users/zendesk/followers","following_url":"https://api.github.com/users/zendesk/following{/other_user}","gists_url":"https://api.github.com/users/zendesk/gists{/gist_id}","starred_url":"https://api.github.com/users/zendesk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zendesk/subscriptions","organizations_url":"https://api.github.com/users/zendesk/orgs","repos_url":"https://api.github.com/users/zendesk/repos","events_url":"https://api.github.com/users/zendesk/events{/privacy}","received_events_url":"https://api.github.com/users/zendesk/received_events","type":"Organization","site_admin":false},"repo":{"id":20208662,"name":"samson","full_name":"zendesk/samson","owner":{"login":"zendesk","id":11525,"avatar_url":"https://avatars.githubusercontent.com/u/11525?v=3","gravatar_id":"","url":"https://api.github.com/users/zendesk","html_url":"https://github.com/zendesk","followers_url":"https://api.github.com/users/zendesk/followers","following_url":"https://api.github.com/users/zendesk/following{/other_user}","gists_url":"https://api.github.com/users/zendesk/gists{/gist_id}","starred_url":"https://api.github.com/users/zendesk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zendesk/subscriptions","organizations_url":"https://api.github.com/users/zendesk/orgs","repos_url":"https://api.github.com/users/zendesk/repos","events_url":"https://api.github.com/users/zendesk/events{/privacy}","received_events_url":"https://api.github.com/users/zendesk/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/zendesk/samson","description":"Web interface for deployments","fork":false,"url":"https://api.github.com/repos/zendesk/samson","forks_url":"https://api.github.com/repos/zendesk/samson/forks","keys_url":"https://api.github.com/repos/zendesk/samson/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zendesk/samson/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zendesk/samson/teams","hooks_url":"https://api.github.com/repos/zendesk/samson/hooks","issue_events_url":"https://api.github.com/repos/zendesk/samson/issues/events{/number}","events_url":"https://api.github.com/repos/zendesk/samson/events","assignees_url":"https://api.github.com/repos/zendesk/samson/assignees{/user}","branches_url":"https://api.github.com/repos/zendesk/samson/branches{/branch}","tags_url":"https://api.github.com/repos/zendesk/samson/tags","blobs_url":"https://api.github.com/repos/zendesk/samson/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zendesk/samson/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zendesk/samson/git/refs{/sha}","trees_url":"https://api.github.com/repos/zendesk/samson/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zendesk/samson/statuses/{sha}","languages_url":"https://api.github.com/repos/zendesk/samson/languages","stargazers_url":"https://api.github.com/repos/zendesk/samson/stargazers","contributors_url":"https://api.github.com/repos/zendesk/samson/contributors","subscribers_url":"https://api.github.com/repos/zendesk/samson/subscribers","subscription_url":"https://api.github.com/repos/zendesk/samson/subscription","commits_url":"https://api.github.com/repos/zendesk/samson/commits{/sha}","git_commits_url":"https://api.github.com/repos/zendesk/samson/git/commits{/sha}","comments_url":"https://api.github.com/repos/zendesk/samson/comments{/number}","issue_comment_url":"https://api.github.com/repos/zendesk/samson/issues/comments{/number}","contents_url":"https://api.github.com/repos/zendesk/samson/contents/{+path}","compare_url":"https://api.github.com/repos/zendesk/samson/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zendesk/samson/merges","archive_url":"https://api.github.com/repos/zendesk/samson/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zendesk/samson/downloads","issues_url":"https://api.github.com/repos/zendesk/samson/issues{/number}","pulls_url":"https://api.github.com/repos/zendesk/samson/pulls{/number}","milestones_url":"https://api.github.com/repos/zendesk/samson/milestones{/number}","notifications_url":"https://api.github.com/repos/zendesk/samson/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zendesk/samson/labels{/name}","releases_url":"https://api.github.com/repos/zendesk/samson/releases{/id}","created_at":"2014-05-27T05:55:57Z","updated_at":"2016-01-02T15:24:19Z","pushed_at":"2016-01-04T11:26:49Z","git_url":"git://github.com/zendesk/samson.git","ssh_url":"git@github.com:zendesk/samson.git","clone_url":"https://github.com/zendesk/samson.git","svn_url":"https://github.com/zendesk/samson","homepage":null,"size":137059,"stargazers_count":568,"watchers_count":568,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":87,"mirror_url":null,"open_issues_count":54,"forks":87,"open_issues":54,"watchers":568,"default_branch":"master"}},"base":{"label":"zendesk:master","ref":"master","sha":"10e591288bf34701ab055f20d3788c398aa08df5","user":{"login":"zendesk","id":11525,"avatar_url":"https://avatars.githubusercontent.com/u/11525?v=3","gravatar_id":"","url":"https://api.github.com/users/zendesk","html_url":"https://github.com/zendesk","followers_url":"https://api.github.com/users/zendesk/followers","following_url":"https://api.github.com/users/zendesk/following{/other_user}","gists_url":"https://api.github.com/users/zendesk/gists{/gist_id}","starred_url":"https://api.github.com/users/zendesk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zendesk/subscriptions","organizations_url":"https://api.github.com/users/zendesk/orgs","repos_url":"https://api.github.com/users/zendesk/repos","events_url":"https://api.github.com/users/zendesk/events{/privacy}","received_events_url":"https://api.github.com/users/zendesk/received_events","type":"Organization","site_admin":false},"repo":{"id":20208662,"name":"samson","full_name":"zendesk/samson","owner":{"login":"zendesk","id":11525,"avatar_url":"https://avatars.githubusercontent.com/u/11525?v=3","gravatar_id":"","url":"https://api.github.com/users/zendesk","html_url":"https://github.com/zendesk","followers_url":"https://api.github.com/users/zendesk/followers","following_url":"https://api.github.com/users/zendesk/following{/other_user}","gists_url":"https://api.github.com/users/zendesk/gists{/gist_id}","starred_url":"https://api.github.com/users/zendesk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zendesk/subscriptions","organizations_url":"https://api.github.com/users/zendesk/orgs","repos_url":"https://api.github.com/users/zendesk/repos","events_url":"https://api.github.com/users/zendesk/events{/privacy}","received_events_url":"https://api.github.com/users/zendesk/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/zendesk/samson","description":"Web interface for deployments","fork":false,"url":"https://api.github.com/repos/zendesk/samson","forks_url":"https://api.github.com/repos/zendesk/samson/forks","keys_url":"https://api.github.com/repos/zendesk/samson/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zendesk/samson/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zendesk/samson/teams","hooks_url":"https://api.github.com/repos/zendesk/samson/hooks","issue_events_url":"https://api.github.com/repos/zendesk/samson/issues/events{/number}","events_url":"https://api.github.com/repos/zendesk/samson/events","assignees_url":"https://api.github.com/repos/zendesk/samson/assignees{/user}","branches_url":"https://api.github.com/repos/zendesk/samson/branches{/branch}","tags_url":"https://api.github.com/repos/zendesk/samson/tags","blobs_url":"https://api.github.com/repos/zendesk/samson/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zendesk/samson/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zendesk/samson/git/refs{/sha}","trees_url":"https://api.github.com/repos/zendesk/samson/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zendesk/samson/statuses/{sha}","languages_url":"https://api.github.com/repos/zendesk/samson/languages","stargazers_url":"https://api.github.com/repos/zendesk/samson/stargazers","contributors_url":"https://api.github.com/repos/zendesk/samson/contributors","subscribers_url":"https://api.github.com/repos/zendesk/samson/subscribers","subscription_url":"https://api.github.com/repos/zendesk/samson/subscription","commits_url":"https://api.github.com/repos/zendesk/samson/commits{/sha}","git_commits_url":"https://api.github.com/repos/zendesk/samson/git/commits{/sha}","comments_url":"https://api.github.com/repos/zendesk/samson/comments{/number}","issue_comment_url":"https://api.github.com/repos/zendesk/samson/issues/comments{/number}","contents_url":"https://api.github.com/repos/zendesk/samson/contents/{+path}","compare_url":"https://api.github.com/repos/zendesk/samson/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zendesk/samson/merges","archive_url":"https://api.github.com/repos/zendesk/samson/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zendesk/samson/downloads","issues_url":"https://api.github.com/repos/zendesk/samson/issues{/number}","pulls_url":"https://api.github.com/repos/zendesk/samson/pulls{/number}","milestones_url":"https://api.github.com/repos/zendesk/samson/milestones{/number}","notifications_url":"https://api.github.com/repos/zendesk/samson/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zendesk/samson/labels{/name}","releases_url":"https://api.github.com/repos/zendesk/samson/releases{/id}","created_at":"2014-05-27T05:55:57Z","updated_at":"2016-01-02T15:24:19Z","pushed_at":"2016-01-04T11:26:49Z","git_url":"git://github.com/zendesk/samson.git","ssh_url":"git@github.com:zendesk/samson.git","clone_url":"https://github.com/zendesk/samson.git","svn_url":"https://github.com/zendesk/samson","homepage":null,"size":137059,"stargazers_count":568,"watchers_count":568,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":87,"mirror_url":null,"open_issues_count":54,"forks":87,"open_issues":54,"watchers":568,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/zendesk/samson/pulls/685"},"html":{"href":"https://github.com/zendesk/samson/pull/685"},"issue":{"href":"https://api.github.com/repos/zendesk/samson/issues/685"},"comments":{"href":"https://api.github.com/repos/zendesk/samson/issues/685/comments"},"review_comments":{"href":"https://api.github.com/repos/zendesk/samson/pulls/685/comments"},"review_comment":{"href":"https://api.github.com/repos/zendesk/samson/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/zendesk/samson/pulls/685/commits"},"statuses":{"href":"https://api.github.com/repos/zendesk/samson/statuses/d9e90879960dd5561104939e598f142d1c296efb"}}}}