You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ab...@apache.org on 2014/12/19 18:02:37 UTC

ambari git commit: AMBARI-8829 Admin Web > Version Management: UI tweaks. (ababiichuk)

Repository: ambari
Updated Branches:
  refs/heads/trunk 979f1949c -> 72552aa65


AMBARI-8829 Admin Web > Version Management: UI tweaks. (ababiichuk)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/72552aa6
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/72552aa6
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/72552aa6

Branch: refs/heads/trunk
Commit: 72552aa6543643d0c2b05a1d464388cceb3f38b5
Parents: 979f194
Author: aBabiichuk <ab...@cybervisiontech.com>
Authored: Fri Dec 19 18:45:00 2014 +0200
Committer: aBabiichuk <ab...@cybervisiontech.com>
Committed: Fri Dec 19 18:57:28 2014 +0200

----------------------------------------------------------------------
 .../data/stack_versions/stack_version_all.json  |  16 +-
 ambari-web/app/assets/test/tests.js             |   1 +
 ambari-web/app/controllers.js                   |   1 +
 .../repo_version_management_controller.js       | 179 +++++++++++++++++++
 .../stack_versions/repo_versions_controller.js  | 111 +-----------
 .../stack_version_details_controller.js         | 160 ++++++++++++++---
 .../stack_versions/stack_versions_controller.js | 134 +-------------
 .../app/mappers/repository_version_mapper.js    |   2 +-
 ambari-web/app/models/stack_version/version.js  |  10 +-
 ambari-web/app/routes/main.js                   |   2 +-
 ambari-web/app/styles/application.less          |  14 +-
 .../main/admin/stack_versions/repo_versions.hbs |  13 +-
 .../stack_versions/stack_version_details.hbs    |  87 +++++----
 .../admin/stack_versions/stack_versions.hbs     |  13 +-
 ambari-web/app/utils/ajax/ajax.js               |   4 +
 ambari-web/app/views/main/admin.js              |   2 +-
 .../app/views/main/admin/stack_versions/menu.js |  58 ++++--
 .../admin/stack_versions/operating_systems.js   |   8 +-
 .../admin/stack_versions/repo_version_view.js   |  45 +----
 .../stack_version_details_view.js               |  72 ++++----
 .../admin/stack_versions/stack_version_view.js  |  57 ++----
 ambari-web/app/views/main/menu.js               |   2 +-
 .../repo_version_management_controller_test.js  | 121 +++++++++++++
 .../repo_versions_controller_test.js            | 100 +----------
 .../stack_version_details_controller_test.js    |  95 +++++++---
 .../stack_versions_controller_test.js           |  69 -------
 .../stack_version/stack_version_details_test.js | 111 +++++++++---
 27 files changed, 795 insertions(+), 692 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/app/assets/data/stack_versions/stack_version_all.json
----------------------------------------------------------------------
diff --git a/ambari-web/app/assets/data/stack_versions/stack_version_all.json b/ambari-web/app/assets/data/stack_versions/stack_version_all.json
index b7ea2b0..17b7565 100644
--- a/ambari-web/app/assets/data/stack_versions/stack_version_all.json
+++ b/ambari-web/app/assets/data/stack_versions/stack_version_all.json
@@ -112,14 +112,12 @@
         "id": 3,
         "repository_version": 3,
         "stack": "HDP",
-        "state": "INSTALLED",
+        "state": "INSTALLING",
         "version": "2.2",
         "host_states": {
           "CURRENT": [],
-          "INSTALLED": [
-            "ab3test-4.c.pramod-thangali.internal"
-          ],
-          "INSTALLING": [],
+          "INSTALLED": [],
+          "INSTALLING": ["ab3test-4.c.pramod-thangali.internal"],
           "INSTALL_FAILED": [],
           "UPGRADED": [],
           "UPGRADE_FAILED": [],
@@ -180,15 +178,13 @@
         "id": 4,
         "repository_version": 4,
         "stack": "HDP",
-        "state": "INSTALLED",
+        "state": "INSTALL_FAILED",
         "version": "2.2",
         "host_states": {
           "CURRENT": [],
-          "INSTALLED": [
-            "ab3test-4.c.pramod-thangali.internal"
-          ],
+          "INSTALLED": [],
           "INSTALLING": [],
-          "INSTALL_FAILED": [],
+          "INSTALL_FAILED": ["ab3test-4.c.pramod-thangali.internal"],
           "UPGRADED": [],
           "UPGRADE_FAILED": [],
           "UPGRADING": []

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/app/assets/test/tests.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/assets/test/tests.js b/ambari-web/app/assets/test/tests.js
index 6209538..384735f 100644
--- a/ambari-web/app/assets/test/tests.js
+++ b/ambari-web/app/assets/test/tests.js
@@ -54,6 +54,7 @@ var files = ['test/init_model_test',
   'test/controllers/main/admin/kerberos/step4_controller_test',
   'test/controllers/main/admin/stack_and_upgrade_controller_test',
   'test/controllers/main/admin/stack_version/stack_version_details_controller_test',
+  'test/controllers/main/admin/stack_version/repo_version_management_controller_test',
   'test/controllers/main/admin/stack_version/repo_versions_controller_test',
   'test/controllers/main/admin/serviceAccounts_controller_test',
   'test/controllers/main/admin/highAvailability_controller_test',

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/app/controllers.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers.js b/ambari-web/app/controllers.js
index 7e30431..9d0e74d 100644
--- a/ambari-web/app/controllers.js
+++ b/ambari-web/app/controllers.js
@@ -53,6 +53,7 @@ require('controllers/main/admin/highAvailability/resourceManager/step3_controlle
 require('controllers/main/admin/highAvailability/resourceManager/step4_controller');
 require('controllers/main/admin/stack_and_upgrade_controller');
 require('controllers/main/admin/stack_upgrade_controller');
+require('controllers/main/admin/stack_versions/repo_version_management_controller');
 require('controllers/main/admin/stack_versions/repo_versions_controller');
 require('controllers/main/admin/stack_versions/stack_versions_controller');
 require('controllers/main/admin/stack_versions/stack_version_details_controller');

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/app/controllers/main/admin/stack_versions/repo_version_management_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/stack_versions/repo_version_management_controller.js b/ambari-web/app/controllers/main/admin/stack_versions/repo_version_management_controller.js
new file mode 100644
index 0000000..1412300
--- /dev/null
+++ b/ambari-web/app/controllers/main/admin/stack_versions/repo_version_management_controller.js
@@ -0,0 +1,179 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.RepoVersionsManagementController = Em.ArrayController.extend({
+  name: 'repoVersionsManagementController',
+
+  dataIsLoaded: false,
+  timeoutRef: null,
+  isPolling: false,
+  /**
+   * path to the mock json
+   * @type {String}
+   */
+  mockRepoUrl: '/data/stack_versions/repo_versions_all.json',
+
+  /**
+   * api to get RepoVersions
+   * @type {String}
+   */
+  realRepoUrl: function () {
+    return App.get('apiPrefix') + App.get('stackVersionURL') + '/repository_versions?fields=*,operatingSystems/*,operatingSystems/repositories/*';
+  }.property('App.stackVersionURL'),
+
+  /**
+   * path to the mock json
+   * @type {String}
+   */
+  mockStackUrl: '/data/stack_versions/stack_version_all.json',
+
+  /**
+   * api to get ClusterStackVersions with repository_versions (use to init data load)
+   * @type {String}
+   */
+  realStackUrl: function () {
+    return App.apiPrefix + '/clusters/' + App.get('clusterName') + '/stack_versions?fields=*,repository_versions/*,repository_versions/operatingSystems/repositories/*';
+  }.property('App.clusterName'),
+
+  realUpdateUrl: function () {
+    return App.apiPrefix + '/clusters/' + App.get('clusterName') + '/stack_versions?fields=ClusterStackVersions/*';
+  }.property('App.clusterName'),
+
+  /**
+   * returns url to get data for repoVersion or clusterStackVersion
+   * @param {Boolean} stack true if load clusterStackVersion
+   * @param {Boolean} fullLoad true if load all data
+   * @returns {String}
+   * @method getUrl
+   */
+  getUrl: function(stack, fullLoad) {
+    if (App.get('testMode')) {
+      return stack ? this.get('mockStackUrl') : this.get('mockRepoUrl')
+    } else {
+      if (fullLoad) {
+        return stack ? this.get('realStackUrl') : this.get('realRepoUrl');
+      } else {
+        return this.get('realUpdateUrl');
+      }
+    }
+  },
+
+  /**
+   * get stack versions from server and push it to model
+   * @return {*}
+   * @method loadStackVersionsToModel
+   */
+  loadStackVersionsToModel: function (fullLoad) {
+    var dfd = $.Deferred();
+    App.HttpClient.get(this.getUrl(true, fullLoad), App.stackVersionMapper, {
+      complete: function () {
+        dfd.resolve();
+      }
+    });
+    return dfd.promise();
+  },
+
+  /**
+   * get repo versions from server and push it to model
+   * @return {*}
+   * @params {Boolean} isUpdate - if true loads part of data that need to be updated
+   * @method loadRepoVersionsToModel()
+   */
+  loadRepoVersionsToModel: function () {
+    var dfd = $.Deferred();
+    App.HttpClient.get(this.getUrl(false, true), App.repoVersionMapper, {
+      complete: function () {
+        dfd.resolve();
+      }
+    });
+    return dfd.promise();
+  },
+
+  load: function() {
+    var dfd = $.Deferred();
+    var self = this;
+    self.set('dataIsLoaded', false);
+    self.loadStackVersionsToModel(true).done(function () {
+      self.loadRepoVersionsToModel().done(function() {
+        self.set('dataIsLoaded', true);
+        dfd.resolve();
+      });
+    });
+    return dfd.promise();
+  },
+
+  /**
+   * request latest data from server and update content
+   * @method doPolling
+   */
+  doPolling: function () {
+    var self = this;
+
+    this.set('timeoutRef', setTimeout(function () {
+      if (self.get('isPolling')) {
+        self.loadStackVersionsToModel(false).done(function () {
+          self.doPolling();
+        })
+      }
+    }, App.componentsUpdateInterval));
+  },
+
+  /**
+   * goes to the hosts page with content filtered by repo_version_name and repo_version_state
+   * @param version
+   * @param state
+   * @method filterHostsByStack
+   */
+  filterHostsByStack: function (version, state) {
+    if (!version || !state)
+      return;
+    App.router.get('mainHostController').filterByStack(version, state);
+    App.router.get('mainHostController').set('showFilterConditionsFirstLoad', true);
+    App.router.transitionTo('hosts.index');
+  },
+
+  /**
+   * shows popup with listed hosts wich has current state of hostStackVersion
+   * @param event
+   * @returns {*|void}
+   * @method showHosts
+   */
+  showHosts: function(event) {
+    var self = this;
+    var status = event.currentTarget.title.toCapital();
+    var version = event.contexts[0];
+    var hosts = event.contexts[1];
+    if (hosts.length) {
+      return App.ModalPopup.show({
+        bodyClass: Ember.View.extend({
+          title: Em.I18n.t('admin.stackVersions.hosts.popup.title').format(version, status, hosts.length),
+          template: Em.Handlebars.compile('<h4>{{view.title}}</h4><span class="limited-height-2">'+ hosts.join('<br/>') + '</span>')
+        }),
+        header: Em.I18n.t('admin.stackVersions.hosts.popup.header').format(status),
+        primary: Em.I18n.t('admin.stackVersions.hosts.popup.primary'),
+        secondary: Em.I18n.t('common.close'),
+        onPrimary: function() {
+          this.hide();
+          self.filterHostsByStack(version, status);
+        }
+      });
+    }
+  }
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/app/controllers/main/admin/stack_versions/repo_versions_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/stack_versions/repo_versions_controller.js b/ambari-web/app/controllers/main/admin/stack_versions/repo_versions_controller.js
index 2e4a3c8..38365a7 100644
--- a/ambari-web/app/controllers/main/admin/stack_versions/repo_versions_controller.js
+++ b/ambari-web/app/controllers/main/admin/stack_versions/repo_versions_controller.js
@@ -18,119 +18,14 @@
 
 var App = require('app');
 
-App.RepoVersionsController = Em.ArrayController.extend({
+App.RepoVersionsController = App.RepoVersionsManagementController.extend({
   name: 'repoVersionsController',
 
   content: function () {
     return App.RepositoryVersion.find().filterProperty('stackVersion', null);
   }.property('dataIsLoaded'),
 
-  /**
-   * true if content is loaded to model
-   * @type {Boolean}
-   */
-  dataIsLoaded: false,
-
-  /**
-   * path to the mock json
-   * @type {String}
-   */
-  mockUrl: '/data/stack_versions/repo_versions_all.json',
-
-  /**
-   * api to get RepoVersions
-   * @type {String}
-   */
-  realUrl: function () {
-    return App.get('apiPrefix') + App.get('stackVersionURL') + '/repository_versions?fields=*,operatingSystems/*,operatingSystems/repositories/*';
-  }.property('App.stackVersionURL'),
-
-  /**
-   * load all data components required by repo version table
-   * @return {*}
-   * @method load()
-   */
-  load: function () {
-    this.set('dataIsLoaded', false);
-    var dfd = $.Deferred();
-    var self = this;
-
-    App.get('router.mainStackVersionsController').loadStackVersionsToModel().done(function () {
-      self.loadRepoVersionsToModel().done(function () {
-        self.set('dataIsLoaded', true);
-        dfd.resolve();
-      });
-    });
-    return dfd.promise();
-  },
-
-  /**
-   * get repo versions from server and push it to model
-   * @return {*}
-   * @params {Boolean} isUpdate - if true loads part of data that need to be updated
-   * @method loadRepoVersionsToModel()
-   */
-  loadRepoVersionsToModel: function () {
-    var dfd = $.Deferred();
-    App.HttpClient.get(this.getUrl(), App.repoVersionMapper, {
-      complete: function () {
-        dfd.resolve();
-      }
-    });
-    return dfd.promise();
-  },
-
-  /**
-   * returns api url to get repositoryVersion
-   * or mock json if testmode is on
-   * @returns {String}
-   * @method getUrl
-   */
-  getUrl: function () {
-    return App.get('testMode') ? this.get('mockUrl') : this.get('realUrl');
-  },
-
-  /**
-   * sends request to install repoVersion to the cluster
-   * and create clusterStackVersion resourse
-   * @param event
-   * @return {$.ajax}
-   * @method installRepoVersion
-   */
-  installRepoVersion: function (event) {
-    var repo = event.context;
-    var data = {
-      ClusterStackVersions: {
-        stack: repo.get('stackVersionType'),
-        version: repo.get('stackVersionNumber'),
-        repository_version: repo.get('repositoryVersion')
-      },
-      id: repo.get('id')
-    };
-    return App.ajax.send({
-      name: 'admin.stack_version.install.repo_version',
-      sender: this,
-      data: data,
-      success: 'installStackVersionSuccess'
-    });
-  },
-
-  /**
-   * success callback for <code>installRepoVersion()<code>
-   * saves request id to the db, and redirect user to the just
-   * created clusterStackVersion.
-   * @param data
-   * @param opt
-   * @param params
-   * @method installStackVersionSuccess
-   */
-  installStackVersionSuccess: function (data, opt, params) {
-    App.db.set('repoVersion', 'id', [data.Requests.id]);
-    if(!App.StackVersion.find().findProperty('repositoryVersion.id', params.id)) {
-      App.get('router.mainStackVersionsController').loadStackVersionsToModel().done(function() {
-        var stackVersion = App.StackVersion.find().findProperty('repositoryVersion.id', params.id);
-        App.router.transitionTo('main.admin.adminStackVersions.version', stackVersion);
-      });
-    }
+  installRepoVersion: function(event) {
+   App.get('router.mainStackVersionsDetailsController').installRepoVersion(event);
   }
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/app/controllers/main/admin/stack_versions/stack_version_details_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/stack_versions/stack_version_details_controller.js b/ambari-web/app/controllers/main/admin/stack_versions/stack_version_details_controller.js
index 7678c5a..08116f6 100644
--- a/ambari-web/app/controllers/main/admin/stack_versions/stack_version_details_controller.js
+++ b/ambari-web/app/controllers/main/admin/stack_versions/stack_version_details_controller.js
@@ -24,6 +24,12 @@ App.MainStackVersionsDetailsController = Em.Controller.extend({
   content: null,
 
   /**
+   * timeOut function to load updated progress
+   * when install repo wersion is running
+   */
+  timeoutRef: null,
+
+  /**
    * amount of all hosts installed on cluster
    * @type {Number}
    */
@@ -36,57 +42,159 @@ App.MainStackVersionsDetailsController = Em.Controller.extend({
    * @type {Boolean}
    */
   installFailed: function() {
-    return this.get('content.state') == "INSTALL_FAILED";
-  }.property('content.state'),
+    return this.get('content.stackVersion.state') == "INSTALL_FAILED";
+  }.property('content.stackVersion.state'),
   /**
    * true if stack version install is in progress
    * @type {Boolean}
    */
   installInProgress: function() {
-    return this.get('content.state') == "INSTALLING";
-  }.property('content.state'),
+    return this.get('content.stackVersion.state') == "INSTALLING";
+  }.property('content.stackVersion.state'),
 
   /**
    * true if repo version is installed on all hosts but not upgraded
    * @type {Boolean}
    */
-  installedNotUpgraded: function() {
-    return this.get('content.state') == "INSTALLED";
-  }.property('content.state'),
+  installComplete: function() {
+    return this.get('content.stackVersion.state')
+      && this.get('content.stackVersion.state') != "INSTALLING"
+      && this.get('content.stackVersion.state') != "INSTALL_FAILED";
+  }.property('content.stackVersion.state'),
 
+  /**
+   * true if repo version is not installed
+   * this flag is used for install/reinstall button
+   * we should show this button when there is no stackVersion (instead init state)
+   * or when <code>INSTALL_FAILED<code> state
+   * @type {Boolean}
+   */
+  notInstalled: function() {
+    return !this.get('content.stackVersion.state') || this.get('content.stackVersion.state') == "INSTALL_FAILED";
+  }.property('content.stackVersion.state'),
 
   /**
-   * depending on state run or install repo request
-   * or show the installation process popup
-   * @param event
-   * @method installStackVersion
+   * true if repo version is current
+   * @type {Boolean}
    */
-  installStackVersion: function(event) {
-    if (this.get('installInProgress')) {
-      this.showProgressPopup();
-    } else if (this.get('installFailed')) {
-      this.installRepoVersion(event);
-    }
-  },
+  current: function() {
+    return this.get('content.stackVersion.state') == "CURRENT";
+  }.property('content.stackVersion.state'),
 
   /**
-   * install repoVersion using <code>installRepoVersion()<code> method
-   * of <code>repoVersionsController<code> controller
-   * @param event
-   * @method installRepoVersion
+   * counter that is shown on install button
+   * @type {Number}
    */
-  installRepoVersion: function(event) {
-    App.get('router.repoVersionsController').installRepoVersion(event);
-  },
+  hostsToInstall: function() {
+    return this.get('content.stackVersion') ? this.get('content.stackVersion.initHosts.length') : this.get('totalHostCount');
+  }.property('content.stackVersion.initHosts.length'),
+
+  /**
+   * persentage of install progress
+   * @type {Number}
+   */
+  progress: 0,
 
   /**
    * opens a popup with installations state per host
    * @method showProgressPopup
    */
   showProgressPopup: function() {
-    var popupTitle = Em.I18n.t('admin.stackVersions.datails.install.hosts.popup.title').format(this.get('content.repositoryVersion.displayName'));
+    var popupTitle = Em.I18n.t('admin.stackVersions.datails.install.hosts.popup.title').format(this.get('content.displayName'));
     var requestIds = App.get('testMode') ? [1] : App.db.get('repoVersion', 'id');
     var hostProgressPopupController = App.router.get('highAvailabilityProgressPopupController');
     hostProgressPopupController.initPopup(popupTitle, requestIds, this);
+  },
+
+  /**
+   * runs <code>updateProgress<code> method
+   * to keep information up-to-date
+   * @method doPolling
+   */
+  doPolling: function () {
+    var self = this;
+    self.updateProgress();
+    this.set('timeoutRef', setTimeout(function () {
+      if (self.get('installInProgress')) {
+        self.doPolling();
+      } else {
+        clearTimeout(self.get('timeoutRef'));
+      }
+    }, App.componentsUpdateInterval));
+  },
+
+  /**
+   * runs ajax request to get current progress of
+   * installing repo version to cluster
+   * @returns {$.ajax}
+   * @method updateProgress
+   */
+  updateProgress: function() {
+    return App.ajax.send({
+      'name': 'admin.stack_versions.progress.request',
+      'sender': this,
+      'data': {
+        requestId: App.db.get('repoVersion', 'id')
+      },
+      'success': 'updateProgressSuccess'
+    });
+  },
+
+  /**
+   * success calback for updateProgress
+   * @param data
+   * @method updateProgressSuccess
+   */
+  updateProgressSuccess: function(data) {
+    if (Em.get(data, 'Requests.progress_percent')) {
+      this.set('progress', parseInt(Em.get(data, 'Requests.progress_percent')));
+    }
+  },
+
+  /**
+   * sends request to install repoVersion to the cluster
+   * and create clusterStackVersion resourse
+   * @param event
+   * @return {$.ajax}
+   * @method installRepoVersion
+   */
+  installRepoVersion: function (event) {
+    var repo = event.context;
+    var data = {
+      ClusterStackVersions: {
+        stack: repo.get('stackVersionType'),
+        version: repo.get('stackVersionNumber'),
+        repository_version: repo.get('repositoryVersion')
+      },
+      id: repo.get('id')
+    };
+    return App.ajax.send({
+      name: 'admin.stack_version.install.repo_version',
+      sender: this,
+      data: data,
+      success: 'installStackVersionSuccess'
+    });
+  },
+
+  /**
+   * success callback for <code>installRepoVersion()<code>
+   * saves request id to the db, and redirect user to the just
+   * created clusterStackVersion.
+   * @param data
+   * @param opt
+   * @param params
+   * @method installStackVersionSuccess
+   */
+  installStackVersionSuccess: function (data, opt, params) {
+    var self = this;
+    App.db.set('repoVersion', 'id', [data.Requests.id]);
+    App.get('router.repoVersionsManagementController').loadStackVersionsToModel(true).done(function() {
+      var repoVersion = App.RepositoryVersion.find(params.id);
+      if (App.get('router.currentState.name') == "update") {
+        App.router.transitionTo('main.admin.adminStackVersions.version', repoVersion);
+      } else {
+        self.set('content', repoVersion);
+      }
+    });
   }
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/app/controllers/main/admin/stack_versions/stack_versions_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/stack_versions/stack_versions_controller.js b/ambari-web/app/controllers/main/admin/stack_versions/stack_versions_controller.js
index 1cc8bdc..c61ac03 100644
--- a/ambari-web/app/controllers/main/admin/stack_versions/stack_versions_controller.js
+++ b/ambari-web/app/controllers/main/admin/stack_versions/stack_versions_controller.js
@@ -18,138 +18,8 @@
 
 var App = require('app');
 
-App.MainStackVersionsController = Em.ArrayController.extend({
+App.MainStackVersionsController = App.RepoVersionsManagementController.extend({
   name: 'mainStackVersionsController',
 
-  content: App.StackVersion.find(),
-  timeoutRef: null,
-  isPolling: false,
-  dataIsLoaded: false,
-
-  /**
-   *  path to the mock json
-   * @type {String}
-   */
-  mockUrl: '/data/stack_versions/stack_version_all.json',
-
-  /**
-   * api to get ClusterStackVersions with repository_versions (use to init data load)
-   * @type {String}
-   */
-  realUrl: function () {
-    return App.apiPrefix + '/clusters/' + App.get('clusterName') + '/stack_versions?fields=*,repository_versions/*,repository_versions/operatingSystems/repositories/*';
-  }.property('App.clusterName'),
-
-  /**
-   * api to get ClusterStackVersions without repository_versions (use to update data)
-   * @type {String}
-   */
-  realUpdateUrl: function () {
-    return App.apiPrefix + '/clusters/' + App.get('clusterName') + '/stack_versions?fields=ClusterStackVersions/*';
-  }.property('App.clusterName'),
-
-  /**
-   * request latest data from server and update content
-   * @method doPolling
-   */
-  doPolling: function () {
-    var self = this;
-
-    this.set('timeoutRef', setTimeout(function () {
-      if (self.get('isPolling')) {
-        self.loadStackVersionsToModel(self.get('dataIsLoaded')).done(function () {
-          self.doPolling();
-        })
-      }
-    }, App.componentsUpdateInterval));
-  },
-  /**
-   * load all data components required by stack version table
-   * @return {*}
-   * @method load
-   */
-  load: function () {
-    var dfd = $.Deferred();
-    var self = this;
-    this.loadStackVersionsToModel().done(function () {
-      App.get('router.repoVersionsController').loadRepoVersionsToModel().done(function() {
-        self.set('dataIsLoaded', true);
-        dfd.resolve();
-      });
-
-    });
-    return dfd.promise();
-  },
-
-  /**
-   * get stack versions from server and push it to model
-   * @return {*}
-   * @method loadStackVersionsToModel
-   */
-  loadStackVersionsToModel: function (isUpdate) {
-    var dfd = $.Deferred();
-
-    App.HttpClient.get(this.getUrl(isUpdate), App.stackVersionMapper, {
-      complete: function () {
-        dfd.resolve();
-      }
-    });
-    return dfd.promise();
-  },
-
-  /**
-   * returns api url to get clusteStackVersion wirh repositoryVersion
-   * or just clustrerStackVersion if only updates are requested
-   * or mock json if testmode is on
-   * @param isUpdate true if data needs to be updated
-   * @returns {String}
-   * @method getUrl
-   */
-  getUrl: function (isUpdate) {
-    return App.get('testMode') ? this.get('mockUrl') :
-      isUpdate ? this.get('realUpdateUrl') : this.get('realUrl');
-  },
-
-  /**
-   * goes to the hosts page with content filtered by repo_version_name and repo_version_state
-   * @param version
-   * @param state
-   * @method filterHostsByStack
-   */
-  filterHostsByStack: function (version, state) {
-    if (!version || !state)
-      return;
-    App.router.get('mainHostController').filterByStack(version, state);
-    App.router.get('mainHostController').set('showFilterConditionsFirstLoad', true);
-    App.router.transitionTo('hosts.index');
-  },
-
-  /**
-   * shows popup with listed hosts wich has current state of hostStackVersion
-   * @param event
-   * @returns {*|void}
-   * @method showHosts
-   */
-  showHosts: function(event) {
-    var self = this;
-    var status = event.currentTarget.title.toCapital();
-    var version = event.contexts[0];
-    var hosts = event.contexts[1];
-    if (hosts.length) {
-      return App.ModalPopup.show({
-        bodyClass: Ember.View.extend({
-          title: Em.I18n.t('admin.stackVersions.hosts.popup.title').format(version, status, hosts.length),
-          template: Em.Handlebars.compile('<h4>{{view.title}}</h4><span class="limited-height-2">'+ hosts.join('<br/>') + '</span>')
-        }),
-        header: Em.I18n.t('admin.stackVersions.hosts.popup.header').format(status),
-        primary: Em.I18n.t('admin.stackVersions.hosts.popup.primary'),
-        secondary: Em.I18n.t('common.close'),
-        onPrimary: function() {
-          this.hide();
-          self.filterHostsByStack(version, status);
-        }
-      });
-    }
-  }
-
+  content: App.StackVersion.find()
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/app/mappers/repository_version_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/repository_version_mapper.js b/ambari-web/app/mappers/repository_version_mapper.js
index 5d42fd8..13b2869 100644
--- a/ambari-web/app/mappers/repository_version_mapper.js
+++ b/ambari-web/app/mappers/repository_version_mapper.js
@@ -75,7 +75,7 @@ App.repoVersionMapper = App.QuickDataMapper.create({
 
     if (json && json.items) {
       json.items.forEach(function (item) {
-        if (loadAll || !App.StackVersion.find().someProperty('repositoryVersion.id', item.RepositoryVersions.id.toString())) {
+        if (loadAll || (item.RepositoryVersions && !App.StackVersion.find().someProperty('repositoryVersion.id', item.RepositoryVersions.id.toString()))) {
           var repo = item;
           var osArray = [];
           //TODO leave onr property name after api will be fixed

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/app/models/stack_version/version.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/stack_version/version.js b/ambari-web/app/models/stack_version/version.js
index 6f718ea..ec5920b 100644
--- a/ambari-web/app/models/stack_version/version.js
+++ b/ambari-web/app/models/stack_version/version.js
@@ -36,6 +36,10 @@ App.StackVersion = DS.Model.extend({
   upgradeFailedHosts: DS.attr('array'),
   currentHosts: DS.attr('array'),
 
+  initHosts:  function() {
+    return this.get('installingHosts') && this.get('installingHosts').concat(this.get('installFailedHosts'));
+  }.property('installFailedHosts', 'installingHosts'),
+
   noInstalledHosts:  function() {
     return this.get('installedHosts.length') == 0;
   }.property('installedHosts.length'),
@@ -44,9 +48,9 @@ App.StackVersion = DS.Model.extend({
     return this.get('currentHosts.length') == 0;
   }.property('currentHosts.length'),
 
-  noInstallFailedHosts: function() {
-    return this.get('installFailedHosts.length') == 0;
-  }.property('currentHosts.length')
+  noInitHosts: function() {
+    return this.get('initHosts.length') == 0;
+  }.property('initHosts.length')
 });
 
 App.StackVersion.FIXTURES = [];

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/app/routes/main.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/main.js b/ambari-web/app/routes/main.js
index 6f9613d..87fcf53 100644
--- a/ambari-web/app/routes/main.js
+++ b/ambari-web/app/routes/main.js
@@ -531,7 +531,7 @@ module.exports = Em.Route.extend({
         }
       }),
       version: Em.Route.extend({
-        route: '/:stack_version_id',
+        route: '/:repository_version_id',
         connectOutlets: function (router, stackVersion) {
           router.get('mainAdminController').connectOutlet('mainStackVersionsDetails', stackVersion);
         }

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/app/styles/application.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/application.less b/ambari-web/app/styles/application.less
index d8a68ee..af74a8b 100644
--- a/ambari-web/app/styles/application.less
+++ b/ambari-web/app/styles/application.less
@@ -5099,10 +5099,20 @@ ul.inline li {
     }
   }
   .stack-status-button {
-    padding-top: 20px;
-    padding-bottom: 20px;
+    padding: 10px;
     width: 250px;
   }
+  .repo-installing-info {
+    float: left;
+    width: 140px;
+    text-align: right;
+  }
+  #repo-installing-link {}
+  .repo-installing-progress {
+    width: 230px;
+    float: right;
+    display: inline;
+  }
 }
 .one-story-bar {
   margin-bottom: 60px;

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/app/templates/main/admin/stack_versions/repo_versions.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/stack_versions/repo_versions.hbs b/ambari-web/app/templates/main/admin/stack_versions/repo_versions.hbs
index 4b1d6cf..985fd88 100644
--- a/ambari-web/app/templates/main/admin/stack_versions/repo_versions.hbs
+++ b/ambari-web/app/templates/main/admin/stack_versions/repo_versions.hbs
@@ -20,15 +20,13 @@
   <table class="table advanced-header-table table-bordered table-striped">
     <thead>
     {{#view view.sortView classNames="label-row" contentBinding="view.filteredContent"}}
-      {{view view.parentView.repoNameSort}}
       {{view view.parentView.repoVersionSort}}
       {{view view.parentView.osSort}}
       <th class="action-col">Actions</th>
     {{/view}}
 
     <tr class="filter-row">
-      <th class="first repo-name-filter">{{view view.repoNameFilterView}}</th>
-      <th class="repo-version-filter">{{view view.repoVersionFilterView}}</th>
+      <th class="first repo-version-filter">{{view view.repoVersionFilterView}}</th>
       <th class="os-type-filter">{{view view.osFilterView}}</th>
       <th></th>
     </tr>
@@ -37,11 +35,8 @@
       {{#if view.pageContent}}
         {{#each item in view.pageContent}}
           {{#view view.RepositoryVersionView contentBinding="item"}}
-            <td class="first repo-name">
-               <span>{{view.content.repositoryVersion}}</span>
-            </td>
-            <td class="repo-display-name">
-              <span>{{view.content.displayName}}</span>
+            <td class="first repo-display-name">
+              <a href="#/main/admin/versions/{{unbound view.content.id}}">{{view.content.displayName}}</a>
             </td>
             <td class="os-types">
               {{view App.OperatingSystemsView contentBinding="view.content"}}
@@ -53,7 +48,7 @@
         {{/each}}
       {{else}}
         <tr>
-          <td class="first empty-table" colspan="4">
+          <td class="first empty-table" colspan="3">
             {{t admin.repoVersions.table.empty}}
           </td>
         </tr>

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/app/templates/main/admin/stack_versions/stack_version_details.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/stack_versions/stack_version_details.hbs b/ambari-web/app/templates/main/admin/stack_versions/stack_version_details.hbs
index c984bdf..ab47e28 100644
--- a/ambari-web/app/templates/main/admin/stack_versions/stack_version_details.hbs
+++ b/ambari-web/app/templates/main/admin/stack_versions/stack_version_details.hbs
@@ -17,23 +17,7 @@
 }}
 
 <div id="stack-version-details">
-  <a class="breadcrumbs" href="#/main/admin/versions">{{t common.versions}}</a><span>&nbsp; > &nbsp;{{content.repositoryVersion.displayName}}</span>
-
-  <div class="box">
-    <div class="box-header">
-      <h4>{{t common.details}}</h4>
-    </div>
-    <div class="version-content">
-      <div class="row-fluid">
-        <div class="span3">{{t common.stack}}</div>
-        <div class="span6">{{content.name}}</div>
-      </div>
-      <div class="row-fluid">
-        <div class="span3">{{t admin.stackVersions.datails.versionName}}</div>
-        <div class="span6">{{content.repositoryVersion.displayName}}</div>
-      </div>
-    </div>
-  </div>
+  <a class="breadcrumbs" href="#/main/admin/versions">{{t common.versions}}</a><span>&nbsp; > &nbsp;{{content.displayName}}</span>
 
   <div class="box">
     <div class="box-header">
@@ -41,40 +25,67 @@
     </div>
     <div class="version-content">
       <div class="row-fluid">
-        <div class="span8">
-          <div class="row-fluid">
-            <div class="span3">{{t admin.stackVersions.datails.not.installed.on}}</div>
-            <div {{bindAttr class="noInitHosts:not-active-link :span6"}}>
-              <a href="#" title='current' class="not-installed-hosts-count"
-                {{action showHosts content.repositoryVersion.displayName content.noInstallFailedHosts target="App.router.mainStackVersionsController"}}>
-                {{content.installFailedHosts.length}}/{{totalHostCount}}
-              </a>
+        <div class="span7">
+          <div {{bindAttr class="view.showCounters::hide"}}>
+          {{#unless installComplete}}
+            <div class="row-fluid">
+              <div class="span3">{{t admin.stackVersions.datails.not.installed.on}}</div>
+              <div {{bindAttr class="content.stackVersion.noInitHosts:not-active-link :span6"}}>
+                <a href="#" title='current' class="not-installed-hosts-count"
+                  {{action showHosts content.displayName content.stackVersion.initHosts target="App.router.mainStackVersionsController"}}>
+                  {{content.stackVersion.initHosts.length}}&nbsp;{{pluralize content.stackVersion.initHosts.length singular="t:common.host" plural="t:common.hosts"}}
+                </a>
+              </div>
             </div>
-          </div>
+          {{/unless}}
           <div class="row-fluid">
             <div class="span3">{{t admin.stackVersions.datails.installed.on}}</div>
-            <div {{bindAttr class="content.noInstalledHosts:not-active-link :span6"}}>
+            <div {{bindAttr class="content.stackVersion.noInstalledHosts:not-active-link :span6"}}>
               <a href="#" title='installed' class="installed-hosts-count"
-                {{action showHosts content.repositoryVersion.displayName content.installedHosts target="App.router.mainStackVersionsController"}}>
-                {{content.installedHosts.length}}/{{totalHostCount}}
+                {{action showHosts content.displayName content.stackVersion.installedHosts target="App.router.mainStackVersionsController"}}>
+                {{content.stackVersion.installedHosts.length}}&nbsp;{{pluralize content.stackVersion.installedHosts.length singular="t:common.host" plural="t:common.hosts"}}
               </a>
             </div>
           </div>
           <div class="row-fluid">
             <div class="span3">{{t admin.stackVersions.datails.current.on}}</div>
-            <div {{bindAttr class="content.noCurrentHosts:not-active-link :span6"}}>
+            <div {{bindAttr class="content.stackVersion.noCurrentHosts:not-active-link :span6"}}>
               <a href="#" title='current' class="current-hosts-count"
-                {{action showHosts content.repositoryVersion.displayName content.currentHosts target="App.router.mainStackVersionsController"}}>
-                {{content.currentHosts.length}}/{{totalHostCount}}
+                {{action showHosts content.displayName content.stackVersion.currentHosts target="App.router.mainStackVersionsController"}}>
+                {{content.stackVersion.currentHosts.length}}&nbsp;{{pluralize content.stackVersion.currentHosts.length singular="t:common.host" plural="t:common.hosts"}}
               </a>
             </div>
           </div>
+          </div>
         </div>
-        <div class="span4 align-center">
-          <a id="repo-version-action-button" {{bindAttr class="view.statusClass :btn :stack-status-button"}} {{action installStackVersion content.repositoryVersion target="controller"}}>
-            <i {{bindAttr class="installInProgress:icon-cog"}}>&nbsp;</i>{{view.stackTextStatus}}
-          </a>
-          <a href="#/main/admin/stack" {{bindAttr class="installedNotUpgraded::hidden"}} >{{t admin.stackVersions.datails.hosts.btn.goto.upgrade}}</a>
+        <div class="span5 align-center">
+          {{!show progress when install repo is in progress}}
+          {{#if installInProgress}}
+            <div class="repo-installing-info">
+            <i class="icon-cog">&nbsp;</i>
+            <a href="javascript:void(null);" id="repo-installing-link" {{action showProgressPopup target="controller"}}>
+              {{t admin.stackVersions.datails.hosts.btn.installing}}
+            </a>
+            </div>
+            <div class="progress-striped active progress-info progress repo-installing-progress"><div class="bar" {{bindAttr style="view.progress"}}></div></div>
+          {{/if}}
+          {{!show install/reinstall button}}
+          {{#if notInstalled}}
+            <a {{bindAttr class="view.installButtonClass :btn :stack-status-button"}}
+              {{action installRepoVersion content target="controller"}}>
+              {{view.installButtonMsg}}
+            </a>
+          {{/if}}
+          {{!show success mesasge when install complete}}
+          {{#if installComplete}}
+            <i class="icon-ok">&nbsp;</i>
+            <span>{{t admin.stackVersions.datails.hosts.btn.nothing}}</span>&nbsp;
+            {{#if controller.current}}
+              <span class="label label-success">{{t common.current}}</span>
+            {{else}}
+              <a href="#/main/admin/stack">{{t admin.stackVersions.datails.hosts.btn.goto.upgrade}}</a>
+            {{/if}}
+          {{/if}}
         </div>
       </div>
     </div>
@@ -100,7 +111,7 @@
         </tr>
         </thead>
         <tbody>
-        {{#each os in content.repositoryVersion.operatingSystems}}
+        {{#each os in content.operatingSystems}}
           {{#each repo in os.repositories}}
             <tr>
               <td>

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/app/templates/main/admin/stack_versions/stack_versions.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/stack_versions/stack_versions.hbs b/ambari-web/app/templates/main/admin/stack_versions/stack_versions.hbs
index ac6822d..5a8400f 100644
--- a/ambari-web/app/templates/main/admin/stack_versions/stack_versions.hbs
+++ b/ambari-web/app/templates/main/admin/stack_versions/stack_versions.hbs
@@ -20,7 +20,6 @@
   <table class="table advanced-header-table table-bordered table-striped">
     <thead>
     {{#view view.sortView classNames="label-row" contentBinding="view.filteredContent"}}
-      {{view view.parentView.stackNameSort}}
       {{view view.parentView.stackVersionSort}}
       {{view view.parentView.osSort}}
       {{view view.parentView.installedSort}}
@@ -28,8 +27,7 @@
     {{/view}}
 
     <tr class="filter-row">
-      <th class="first stack-name-filter">{{view view.stackNameFilterView}}</th>
-      <th class="repo-version-filter">{{view view.stackVersionFilterView}}</th>
+      <th class="first repo-version-filter">{{view view.stackVersionFilterView}}</th>
       <th class="os-type-filter">{{view view.osFilterView}}</th>
       <th class="installed-hosts-filter">{{view view.installedFilterView}}</th>
       <th class="current-hosts-filter">{{view view.currentFilterView}}</th>
@@ -39,11 +37,8 @@
       {{#if view.pageContent}}
         {{#each item in view.pageContent}}
           {{#view view.StackVersionView contentBinding="item"}}
-            <td class="first stack-name">
-               <span class="stack-name">{{view.content.name}}</span>
-            </td>
-            <td class="repo-version">
-              <a href="#/main/admin/versions/{{unbound view.content.id}}">{{view.content.repositoryVersion.displayName}}</a>
+            <td class="first repo-version">
+              <a href="#/main/admin/versions/{{unbound view.content.repositoryVersion.id}}">{{view.content.repositoryVersion.displayName}}</a>
             </td>
             <td class="os-types">
               {{view App.OperatingSystemsView contentBinding="view.content.repositoryVersion"}}
@@ -68,7 +63,7 @@
         {{/each}}
       {{else}}
         <tr>
-          <td class="first empty-table" colspan="5">
+          <td class="first empty-table" colspan="4">
             {{t admin.stackVersions.table.empty}}
           </td>
         </tr>

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/app/utils/ajax/ajax.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js
index c955217..75f4e2e 100644
--- a/ambari-web/app/utils/ajax/ajax.js
+++ b/ambari-web/app/utils/ajax/ajax.js
@@ -1407,6 +1407,10 @@ var urls = {
     },
     'mock': ''
   },
+  'admin.stack_versions.progress.request': {
+    'real': '/clusters/{clusterName}/requests/{requestId}?fields=Requests/progress_percent',
+    'mock': '/data/background_operations/host_upgrade_tasks.json'
+  },
   'admin.rolling_upgrade.pre_upgrade_check': {
     'real': '/clusters/{clusterName}/rolling_upgrades_check?fields=*',
     'mock': '/data/stack_versions/pre_upgrade_check.json'

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/app/views/main/admin.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin.js b/ambari-web/app/views/main/admin.js
index 949d74c..2507f98 100644
--- a/ambari-web/app/views/main/admin.js
+++ b/ambari-web/app/views/main/admin.js
@@ -32,7 +32,7 @@ App.MainAdminView = Em.View.extend({
       items.push({
         name: 'stackVersions',
         url: 'adminStackVersions.index',
-        label: Em.I18n.t('common.stack.versions')
+        label: Em.I18n.t('common.versions')
       });
     }
     items.push({

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/app/views/main/admin/stack_versions/menu.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/stack_versions/menu.js b/ambari-web/app/views/main/admin/stack_versions/menu.js
index e4567cf..1f65b3c 100644
--- a/ambari-web/app/views/main/admin/stack_versions/menu.js
+++ b/ambari-web/app/views/main/admin/stack_versions/menu.js
@@ -32,10 +32,13 @@ App.StackVersionMenuView = Em.CollectionView.extend({
   init: function(){ this._super(); this.activateView(); },
 
   activateView:function () {
+    var self = this;
+    self.changeNewRepoCount();
     $.each(this._childViews, function () {
-      this.set('active', (document.URL.endsWith(this.get('content.routing')) ? "active" : ""));
+      this.set('active', self.getActive(this.get('content.routing')));
+      this.set('label', self.updateLabel(this.get('content.routing'), this.get('content.label')));
     });
-  }.observes('App.router.location.lastSetURL'),
+  }.observes('App.router.location.lastSetURL', 'controller.dataIsLoaded'),
 
   deactivateChildViews: function() {
     $.each(this._childViews, function(){
@@ -43,24 +46,45 @@ App.StackVersionMenuView = Em.CollectionView.extend({
     });
   },
 
+  /**
+   * disable update available tab if there is no any updates
+   * otherwise set active selected tab
+   * @param routing
+   * @returns {string}
+   * @method getActive
+   */
+  getActive: function(routing) {
+    if (routing == 'updates' && this.get('newRepoCount') == 0) {
+      return 'not-active-link';
+    }
+    return document.URL.endsWith(routing) ? "active" : "";
+  },
+
+  /**
+   * update label on updates tab if there is any new repo vreison
+   * otherwise returns same label as is
+   * @param {String} routing
+   * @param {String} defauldLabel
+   * @returns {string}
+   * @method getActive
+   */
+  updateLabel: function(routing, defauldLabel) {
+    if (routing == 'updates' && this.get('newRepoCount') > 0) {
+      return Em.I18n.t('admin.stackVersions.updateTab.title.available').format(this.get('newRepoCount'));
+    }
+    return defauldLabel;
+  },
+
+  changeNewRepoCount: function() {
+    this.set('newRepoCount', App.RepositoryVersion.find().filterProperty('stackVersion', null).get('length'));
+  },
+
+  newRepoCount: 0,
+
   itemViewClass: Em.View.extend({
     classNameBindings: ["active"],
     active: "",
-    newRepoCount: function() {
-      return App.RepositoryVersion.find().filterProperty('stackVersion', null).get('length');
-    }.property('controller.dataIsLoaded'),
-    label: function() {
-      if (this.get('content.routing') == 'updates') {
-        if (this.get('newRepoCount') > 0) {
-          this.set("active", "");
-          return  Em.I18n.t('admin.stackVersions.updateTab.title.available').format(this.get('newRepoCount'))
-        } else {
-          this.set("active", 'not-active-link');
-        }
-      }
-      return this.get('content.label')
-    }.property('view.content.label', 'newRepoCount'),
-
+    label: "",
     template: Ember.Handlebars.compile('<a href="#/main/admin/{{unbound view.content.url}}"> {{view.label}}</a>')
   })
 });
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/app/views/main/admin/stack_versions/operating_systems.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/stack_versions/operating_systems.js b/ambari-web/app/views/main/admin/stack_versions/operating_systems.js
index 03cef25..41f73fa 100644
--- a/ambari-web/app/views/main/admin/stack_versions/operating_systems.js
+++ b/ambari-web/app/views/main/admin/stack_versions/operating_systems.js
@@ -25,7 +25,7 @@ App.OperatingSystemsView = Em.View.extend({
     this.set('isOsCollapsed', true);
   },
 
-  toggleOs: function(event) {
+  toggleOs: function() {
     if (this.get('hasMoreOs')) {
       this.set('isOsCollapsed', !this.get('isOsCollapsed'));
       this.$('.operating-systems').toggle();
@@ -36,10 +36,14 @@ App.OperatingSystemsView = Em.View.extend({
     return this.get('content.operatingSystems.length') > 1;
   }.property('content.operatingSystems.length'),
 
+  /**
+   * shows OS in different way depending on amount
+   * @type {String}
+   */
   osText: function() {
     switch (this.get('content.operatingSystems.length')) {
       case 0:
-        return Em.I18n.t("none");
+        return Em.I18n.t("none").toCapital();
         break;
       case 1:
         return this.get('content.operatingSystems').getEach('osType');

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/app/views/main/admin/stack_versions/repo_version_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/stack_versions/repo_version_view.js b/ambari-web/app/views/main/admin/stack_versions/repo_version_view.js
index 9d874ec..ef873cc 100644
--- a/ambari-web/app/views/main/admin/stack_versions/repo_version_view.js
+++ b/ambari-web/app/views/main/admin/stack_versions/repo_version_view.js
@@ -40,57 +40,28 @@ App.RepoVersionsView = App.TableView.extend({
    */
   colPropAssoc: function () {
     var associations = [];
-    associations[1] = 'repositoryVersion';
-    associations[2] = 'displayName';
-    associations[3] = 'operatingSystems';
+    associations[1] = 'displayName';
+    associations[2] = 'operatingSystems';
     return associations;
   }.property(),
 
   sortView: sort.wrapperView,
-  repoNameSort: sort.fieldView.extend({
-    column: 1,
-    name: 'repositoryVersion',
-    displayName: Em.I18n.t('admin.stackVersions.table.header.stack'),
-    type: 'version',
-    classNames: ['first']
-  }),
   repoVersionSort: sort.fieldView.extend({
-    column: 2,
+    column: 1,
     name: 'displayName',
     displayName: Em.I18n.t('admin.stackVersions.table.header.version'),
-    type: 'version'
+    type: 'version',
+    classNames: ['first']
   }),
   osSort: sort.fieldView.extend({
-    column: 3,
+    column: 2,
     name: 'operatingSystems.length',
     displayName: Em.I18n.t('admin.stackVersions.table.header.os'),
     type: 'number'
   }),
 
-  repoNameFilterView: filters.createSelectView({
-    column: 1,
-    fieldType: 'filter-input-width',
-    content: function () {
-      var names = this.get('parentView.content').mapProperty('repositoryVersion').uniq();
-      return [
-        {
-          value: '',
-          label: Em.I18n.t('common.all')
-        }
-      ].concat(names.map(function (name) {
-        return {
-          value: name,
-          label: name
-        }
-      }));
-    }.property('App.router.repoVersionsController.dataIsLoaded'),
-    onChangeValue: function () {
-      this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'select');
-    }
-  }),
-
   repoVersionFilterView: filters.createTextView({
-    column: 2,
+    column: 1,
     fieldType: 'filter-input-width',
     onChangeValue: function () {
       this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'string');
@@ -98,7 +69,7 @@ App.RepoVersionsView = App.TableView.extend({
   }),
 
   osFilterView: filters.createSelectView({
-    column: 3,
+    column: 2,
     fieldType: 'filter-input-width',
     content: function () {
       var names = App.OS.find().mapProperty('osType').uniq();

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/app/views/main/admin/stack_versions/stack_version_details_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/stack_versions/stack_version_details_view.js b/ambari-web/app/views/main/admin/stack_versions/stack_version_details_view.js
index f4d213b..61e732f 100644
--- a/ambari-web/app/views/main/admin/stack_versions/stack_version_details_view.js
+++ b/ambari-web/app/views/main/admin/stack_versions/stack_version_details_view.js
@@ -25,61 +25,53 @@ App.MainStackVersionsDetailsView = Em.View.extend({
   content: function() {
     return this.get('controller.content')
   }.property('controller.content'),
+
+  /**
+   * message on install button depending on status
+   * <code>INSTALL_FAILED<code>/INIT
+   * @type {String}
+   */
+  installButtonMsg: function() {
+    return this.get('content.stackVersion.state') == 'INSTALL_FAILED'
+      ? Em.I18n.t('admin.stackVersions.datails.hosts.btn.reinstall')
+      : Em.I18n.t('admin.stackVersions.datails.hosts.btn.install').format(this.get('controller.hostsToInstall'))
+  }.property('content.stackVersion.state', 'parentView.content.stackVersion.initHosts.length'),
+
   /**
-   * text on install buttons
+   * class on install button depending on status
+   * <code>INSTALL_FAILED<code>/INIT
    * @type {String}
    */
-  stackTextStatus: function() {
-    var self = this;
-    switch(this.get('content.state')) {
-      case 'UPGRADING':
-      case 'INSTALLING':
-        return self.get('content.state').toCapital().concat("...");
-        break;
-      case 'INSTALLED':
-        return Em.I18n.t('admin.stackVersions.datails.hosts.btn.nothing');
-        break;
-      //TODO remove INIT case if it would not be user
-      case 'INIT':
-        return Em.I18n.t('admin.stackVersions.datails.hosts.btn.install').format(self.get('totalHostCount') - self.get('content.installedHosts.length'));
-        break;
-      case 'INSTALL_FAILED':
-        return Em.I18n.t('admin.stackVersions.datails.hosts.btn.reinstall');
-        break;
-      default:
-        return self.get('content.state') && self.get('content.state').toCapital();
-    }
-  }.property('content.state'),
+  installButtonClass: function() {
+    return this.get('content.stackVersion.state') == 'INSTALL_FAILED' ? 'btn-danger' : 'btn-success';
+  }.property('content.stackVersion.state'),
 
   /**
-   * class on install buttons
+   * property is used as width for progres bar
    * @type {String}
    */
-  statusClass: function() {
-    switch (this.get('content.state')) {
-      //TODO remove INSTALL case if it would not be user
-      case 'INSTALL':
-        return 'btn-success';
-        break;
-      case 'INSTALLING':
-        return 'btn-primary';
-        break;
-      case 'INSTALL_FAILED':
-        return 'btn-danger';
-        break;
-      default:
-        return 'disabled';
-    }
-  }.property('content.state'),
+  progress: function() {
+    return "width:" + this.get('controller.progress') + "%";
+  }.property('controller.progress'),
+
+  /**
+   * true if repoVersion has ClusterStackVersion
+   * defines show host counters on repoversionDetails page
+   * @type {Boolean}
+   */
+  showCounters: function() {
+    return this.get('content.stackVersion') != null;
+  }.property('content.stackVersion'),
 
   didInsertElement: function() {
     App.get('router.mainStackVersionsController').set('isPolling', true);
-    App.get('router.mainStackVersionsController').load();
     App.get('router.mainStackVersionsController').doPolling();
+    this.get('controller').doPolling();
   },
 
   willDestroyElement: function () {
     App.get('router.mainStackVersionsController').set('isPolling', false);
     clearTimeout(App.get('router.mainStackVersionsController.timeoutRef'));
+    clearTimeout(this.get('controller.timeoutRef'));
   }
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/app/views/main/admin/stack_versions/stack_version_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/stack_versions/stack_version_view.js b/ambari-web/app/views/main/admin/stack_versions/stack_version_view.js
index 41897fa..6a0f2d4 100644
--- a/ambari-web/app/views/main/admin/stack_versions/stack_version_view.js
+++ b/ambari-web/app/views/main/admin/stack_versions/stack_version_view.js
@@ -41,71 +41,42 @@ App.MainStackVersionsView = App.TableView.extend({
    */
   colPropAssoc: function () {
     var associations = [];
-    associations[1] = 'name';
-    associations[2] = 'repositoryVersion.displayName';
-    associations[3] = 'repositoryVersion.operatingSystems';
-    associations[4] = 'installedHosts.length';
-    associations[5] = 'currentHosts.length';
+    associations[1] = 'repositoryVersion.displayName';
+    associations[2] = 'repositoryVersion.operatingSystems';
+    associations[3] = 'installedHosts.length';
+    associations[4] = 'currentHosts.length';
     return associations;
   }.property(),
 
   sortView: sort.wrapperView,
-  stackNameSort: sort.fieldView.extend({
-    column: 1,
-    name: 'name',
-    displayName: Em.I18n.t('admin.stackVersions.table.header.stack'),
-    type: 'version',
-    classNames: ['first']
-  }),
   stackVersionSort: sort.fieldView.extend({
-    column: 2,
+    column: 1,
     name: 'repositoryVersion.displayName',
     displayName: Em.I18n.t('admin.stackVersions.table.header.version'),
-    type: 'version'
+    type: 'version',
+    classNames: ['first']
   }),
   osSort: sort.fieldView.extend({
-    column: 3,
+    column: 2,
     name: 'repositoryVersion.operatingSystems.length',
     displayName: Em.I18n.t('admin.stackVersions.table.header.os'),
     type: 'number'
   }),
   installedSort: sort.fieldView.extend({
-    column: 4,
+    column: 3,
     name: 'installedHosts.length',
     displayName: Em.I18n.t('admin.stackVersions.table.header.installed'),
     type: "number"
   }),
   currentSort: sort.fieldView.extend({
-    column: 5,
+    column: 4,
     name: 'currentHosts.length',
     displayName: Em.I18n.t('admin.stackVersions.table.header.current'),
     type: "number"
   }),
 
-  stackNameFilterView: filters.createSelectView({
-    column: 1,
-    fieldType: 'filter-input-width',
-    content: function () {
-      var names = this.get('parentView.content').mapProperty('name').uniq();
-      return [
-        {
-          value: '',
-          label: Em.I18n.t('common.all')
-        }
-      ].concat(names.map(function (name) {
-        return {
-          value: name,
-          label: name
-        }
-      }));
-    }.property('App.router.mainStackVersionsController.dataIsLoaded'),
-    onChangeValue: function () {
-      this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'select');
-    }
-  }),
-
   stackVersionFilterView: filters.createTextView({
-    column: 2,
+    column: 1,
     fieldType: 'filter-input-width',
     onChangeValue: function () {
       this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'string');
@@ -113,7 +84,7 @@ App.MainStackVersionsView = App.TableView.extend({
   }),
 
   osFilterView: filters.createSelectView({
-    column: 3,
+    column: 2,
     fieldType: 'filter-input-width',
     content: function () {
       var names = App.OS.find().mapProperty('osType').uniq();
@@ -135,7 +106,7 @@ App.MainStackVersionsView = App.TableView.extend({
   }),
 
   installedFilterView: filters.createTextView({
-    column: 4,
+    column: 3,
     fieldType: 'filter-input-width',
     onChangeValue: function () {
       this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'string');
@@ -143,7 +114,7 @@ App.MainStackVersionsView = App.TableView.extend({
   }),
 
   currentFilterView: filters.createTextView({
-    column: 5,
+    column: 4,
     fieldType: 'filter-input-width',
     onChangeValue: function () {
       this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'string');

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/app/views/main/menu.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/menu.js b/ambari-web/app/views/main/menu.js
index 8f6d2ad..13a068d 100644
--- a/ambari-web/app/views/main/menu.js
+++ b/ambari-web/app/views/main/menu.js
@@ -130,7 +130,7 @@ App.MainMenuView = Em.CollectionView.extend({
           categories.push({
             name: 'adminStackVersions.index',
             url: 'versions',
-            label: Em.I18n.t('common.stack.versions')
+            label: Em.I18n.t('common.versions')
           });
         }
         categories.push({

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/test/controllers/main/admin/stack_version/repo_version_management_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/admin/stack_version/repo_version_management_controller_test.js b/ambari-web/test/controllers/main/admin/stack_version/repo_version_management_controller_test.js
new file mode 100644
index 0000000..2e71236
--- /dev/null
+++ b/ambari-web/test/controllers/main/admin/stack_version/repo_version_management_controller_test.js
@@ -0,0 +1,121 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+var App = require('app');
+require('controllers/main/admin/stack_versions/stack_versions_controller');
+var controller;
+
+describe('App.RepoVersionsManagementController', function () {
+
+  beforeEach(function () {
+    controller = App.RepoVersionsManagementController.create({});
+  });
+
+  describe('#load()', function () {
+    it('loads data to model by running loadStackVersionsToModel', function () {
+      sinon.stub(controller, 'loadStackVersionsToModel').returns($.Deferred().resolve());
+      sinon.stub(controller, 'loadRepoVersionsToModel').returns($.Deferred().resolve());
+
+      controller.load();
+      expect(controller.loadStackVersionsToModel.calledWith(true)).to.be.true;
+      expect(controller.loadRepoVersionsToModel.calledOnce).to.be.true;
+
+      controller.loadStackVersionsToModel.restore();
+      controller.loadRepoVersionsToModel.restore();
+    });
+  });
+
+  describe('#loadRepoVersionsToModel()', function () {
+    it('loads data to model', function () {
+      sinon.stub(App.HttpClient, 'get', Em.K);
+      sinon.stub(controller, 'getUrl', Em.K);
+
+      controller.loadRepoVersionsToModel();
+      expect(App.HttpClient.get.calledOnce).to.be.true;
+      expect(controller.getUrl.calledWith(false, true)).to.be.true;
+
+      controller.getUrl.restore();
+      App.HttpClient.get.restore();
+    });
+  });
+
+  describe('#loadStackVersionsToModel()', function () {
+    beforeEach(function() {
+      sinon.stub(App.HttpClient, 'get', Em.K);
+      sinon.stub(controller, 'getUrl', Em.K);
+    });
+
+    afterEach(function() {
+      controller.getUrl.restore();
+      App.HttpClient.get.restore();
+    });
+    it('loads all data to model', function () {
+      controller.loadStackVersionsToModel(true);
+      expect(App.HttpClient.get.calledOnce).to.be.true;
+      expect(controller.getUrl.calledWith(true, true)).to.be.true;
+    });
+
+    it('loads update data to model', function () {
+      controller.loadStackVersionsToModel(false);
+      expect(App.HttpClient.get.calledOnce).to.be.true;
+      expect(controller.getUrl.calledWith(true, false)).to.be.true;
+    });
+  });
+
+  describe('#filterHostsByStack()', function () {
+    beforeEach(function() {
+      sinon.stub(App.router.get('mainHostController'), 'filterByStack', Em.K);
+      sinon.stub(App.router, 'transitionTo', Em.K);
+    });
+    afterEach(function() {
+      App.router.get('mainHostController').filterByStack.restore();
+      App.router.transitionTo.restore();
+    });
+    var tests = [
+      {
+        version: "version1",
+        state: "state1",
+        m: 'go to hosts filtered by host stack version and host stack state',
+        runAll: true
+      },
+      {
+        version: null,
+        state: "state1",
+        m: 'doesn\'t do anything because version is missing'
+      },
+      {
+        version: "version1",
+        state: null,
+        m: 'doesn\'t do anything because state is missing'
+      }
+    ].forEach(function(t) {
+        it(t.m, function () {
+          controller.filterHostsByStack(t.version, t.state);
+          if (t.runAll) {
+            expect(App.router.get('mainHostController').filterByStack.calledWith(t.version, t.state)).to.be.true;
+            expect(App.router.transitionTo.calledWith('hosts.index')).to.be.true;
+          } else {
+            expect(App.router.get('mainHostController').filterByStack.calledOnce).to.be.false;
+            expect(App.router.transitionTo.calledOnce).to.be.false;
+          }
+
+        });
+      });
+  });
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/test/controllers/main/admin/stack_version/repo_versions_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/admin/stack_version/repo_versions_controller_test.js b/ambari-web/test/controllers/main/admin/stack_version/repo_versions_controller_test.js
index 19678bc..993fa37 100644
--- a/ambari-web/test/controllers/main/admin/stack_version/repo_versions_controller_test.js
+++ b/ambari-web/test/controllers/main/admin/stack_version/repo_versions_controller_test.js
@@ -19,110 +19,26 @@
 
 var App = require('app');
 require('controllers/main/admin/stack_versions/repo_versions_controller');
-var repoVersionsController;
+var controller;
 
 describe('App.RepoVersionsController', function () {
 
   beforeEach(function () {
-    repoVersionsController = App.RepoVersionsController.create();
+    controller = App.RepoVersionsController.create();
   });
 
-  describe('#installRepoVersion', function () {
-    beforeEach(function () {
-      sinon.stub(App.ajax, 'send', Em.K);
-    });
-    afterEach(function () {
-      App.ajax.send.restore();
-    });
-    it("runs post request to create stack version", function () {
-      var repoVersion = Em.Object.create({
-        stackVersionType: "HDP",
-        stackVersionNumber: "2.2",
-        repositoryVersion: "2.2.0.1"
-      });
-      repoVersionsController.installRepoVersion({context: repoVersion});
-      expect(App.ajax.send.getCall(0).args[0].data.ClusterStackVersions).to.deep.eql({
-        "stack": "HDP",
-        "version": "2.2",
-        "repository_version": "2.2.0.1"
-      });
-    });
-  });
-
-  describe('#load', function () {
-    it('loads data by running loadRepoVersionsToModel', function () {
-      sinon.stub(repoVersionsController, 'loadRepoVersionsToModel').returns({done: Em.K});
-      sinon.stub(App.get('router.mainStackVersionsController'), 'loadStackVersionsToModel', function() { return $.Deferred().resolve()});
-      repoVersionsController.load();
-      expect(repoVersionsController.loadRepoVersionsToModel.calledOnce).to.be.true;
-      expect(App.get('router.mainStackVersionsController').loadStackVersionsToModel.calledOnce).to.be.true;
-      repoVersionsController.loadRepoVersionsToModel.restore();
-      App.get('router.mainStackVersionsController').loadStackVersionsToModel.restore();
-    });
-  });
-  describe('#loadRepoVersionsToModel()', function () {
-    it('loads data to model', function () {
-      sinon.stub(App.HttpClient, 'get', Em.K);
-      sinon.stub(repoVersionsController, 'getUrl', Em.K);
-
-      repoVersionsController.loadRepoVersionsToModel();
-      expect(App.HttpClient.get.calledOnce).to.be.true;
-      expect(repoVersionsController.getUrl.calledOnce).to.be.true;
-
-      repoVersionsController.getUrl.restore();
-      App.HttpClient.get.restore();
-    });
-  });
 
-  describe('#installStackVersionSuccess()', function () {
-    var repoId = "1";
-    var requestId = "2";
-    var stackVersionObject = {repositoryVersion: {id: repoId}};
-    var stackVersion;
+  describe('#installRepoVersion', function () {
     beforeEach(function() {
-      sinon.stub(App.db, 'set', Em.K);
-      sinon.stub(App.router, 'transitionTo', Em.K);
-      sinon.stub(App.StackVersion, 'find', function() {
-        return [stackVersion];
-      });
+      sinon.stub(App.get('router.mainStackVersionsDetailsController'), 'installRepoVersion', Em.K);
     });
-
     afterEach(function() {
-      App.db.set.restore();
-      App.router.transitionTo.restore();
-      App.StackVersion.find.restore();
+      App.get('router.mainStackVersionsDetailsController').installRepoVersion.restore();
     });
-    it('success callback for install stack version', function () {
-      stackVersion = null;
-      sinon.stub(App.get('router.mainStackVersionsController'), 'loadStackVersionsToModel', function() {
-        stackVersion = stackVersionObject;
-        return $.Deferred().resolve()});
-
-      repoVersionsController.installStackVersionSuccess({Requests: {id: requestId}}, null, {id: repoId});
-      expect(App.db.set.calledWith('repoVersion', 'id', [requestId])).to.be.true;
-      expect(App.get('router.mainStackVersionsController').loadStackVersionsToModel.calledOnce).to.be.true;
-      expect(App.StackVersion.find.called).to.be.true;
-      expect(App.router.transitionTo.calledWith('main.admin.adminStackVersions.version', stackVersion)).to.be.true;
-
-      App.get('router.mainStackVersionsController').loadStackVersionsToModel.restore();
-    });
-
-    it('success callback for install stack version without redirect', function () {
-      stackVersion = stackVersionObject;
-      sinon.stub(App.get('router.mainStackVersionsController'), 'loadStackVersionsToModel', function() {
-        return $.Deferred().resolve()
-      });
-
-      repoVersionsController.installStackVersionSuccess({Requests: {id: requestId}}, null, {id: repoId});
-      expect(App.db.set.calledWith('repoVersion', 'id', [requestId])).to.be.true;
-      expect(App.get('router.mainStackVersionsController').loadStackVersionsToModel.calledOnce).to.be.false;
-      expect(App.StackVersion.find.calledOnce).to.be.true;
-      expect(App.router.transitionTo.calledWith('main.admin.adminStackVersions.version', stackVersion)).to.be.false;
-
-      App.get('router.mainStackVersionsController').loadStackVersionsToModel.restore();
-
+    it("runs installRepoVersion of mainStackVersionsDetailsController", function() {
+      controller.installRepoVersion();
+      expect(App.get('router.mainStackVersionsDetailsController').installRepoVersion.calledOnce).to.be.true;
     });
   });
 
-
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/test/controllers/main/admin/stack_version/stack_version_details_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/admin/stack_version/stack_version_details_controller_test.js b/ambari-web/test/controllers/main/admin/stack_version/stack_version_details_controller_test.js
index 95fa393..6161ede 100644
--- a/ambari-web/test/controllers/main/admin/stack_version/stack_version_details_controller_test.js
+++ b/ambari-web/test/controllers/main/admin/stack_version/stack_version_details_controller_test.js
@@ -19,33 +19,12 @@
 
 var App = require('app');
 require('controllers/main/admin/stack_versions/stack_version_details_controller');
-var mainStackVersionsDetailsController;
+var controller;
 
 describe('App.MainStackVersionsDetailsController', function () {
 
   beforeEach(function () {
-    mainStackVersionsDetailsController = App.MainStackVersionsDetailsController.create();
-  });
-
-  describe('#installStackVersion', function () {
-    beforeEach(function() {
-      sinon.stub(mainStackVersionsDetailsController, 'showProgressPopup', Em.K);
-      sinon.stub(mainStackVersionsDetailsController, 'installRepoVersion', Em.K);
-    });
-    afterEach(function() {
-      mainStackVersionsDetailsController.showProgressPopup.restore();
-      mainStackVersionsDetailsController.installRepoVersion.restore();
-    });
-    it("shows installing proggress", function() {
-      mainStackVersionsDetailsController.reopen({'installInProgress': true});
-      mainStackVersionsDetailsController.installStackVersion({});
-      expect(mainStackVersionsDetailsController.showProgressPopup.calledOnce).to.be.true;
-    });
-    it("shows senq request to install/reinstall repoVersion", function() {
-      mainStackVersionsDetailsController.reopen({'installFailed': true});
-      mainStackVersionsDetailsController.installStackVersion({context: "1"});
-      expect(mainStackVersionsDetailsController.installRepoVersion.calledWith({context: "1"})).to.be.true;
-    });
+    controller = App.MainStackVersionsDetailsController.create({});
   });
 
   describe('#showProgressPopup', function () {
@@ -58,11 +37,75 @@ describe('App.MainStackVersionsDetailsController', function () {
       App.set('testMode', false);
     });
     it("runs initPopup", function() {
-      mainStackVersionsDetailsController.reopen({'content': { 'repositoryVersion': {'displayName': "v1"}}});
+      controller.reopen({'content': { 'displayName': "v1"}});
       var popupTitle = Em.I18n.t('admin.stackVersions.datails.install.hosts.popup.title').format("v1");
       var requestIds =[1];
-      mainStackVersionsDetailsController.showProgressPopup();
-      expect(App.router.get('highAvailabilityProgressPopupController').initPopup.calledWith(popupTitle, requestIds, mainStackVersionsDetailsController)).to.be.true;
+      controller.showProgressPopup();
+      expect(App.router.get('highAvailabilityProgressPopupController').initPopup.calledWith(popupTitle, requestIds, controller)).to.be.true;
+    });
+  });
+
+  describe('#installRepoVersion', function () {
+    beforeEach(function () {
+      sinon.stub(App.ajax, 'send', Em.K);
+    });
+    afterEach(function () {
+      App.ajax.send.restore();
+    });
+    it("runs post request to create stack version", function () {
+      var repoVersion = Em.Object.create({
+        stackVersionType: "HDP",
+        stackVersionNumber: "2.2",
+        repositoryVersion: "2.2.0.1"
+      });
+      controller.installRepoVersion({context: repoVersion});
+      expect(App.ajax.send.getCall(0).args[0].data.ClusterStackVersions).to.deep.eql({
+        "stack": "HDP",
+        "version": "2.2",
+        "repository_version": "2.2.0.1"
+      });
+    });
+  });
+
+  describe('#installStackVersionSuccess()', function () {
+    var repoId = "1";
+    var requestId = "2";
+    var repoVersion = {id: repoId};
+    var route;
+    beforeEach(function() {
+      sinon.stub(App.db, 'set', Em.K);
+      sinon.stub(App.router, 'transitionTo', Em.K);
+      sinon.stub(App.RepositoryVersion, 'find', function() {
+        return repoVersion;
+      });
+      sinon.stub(App.get('router.repoVersionsManagementController'), 'loadStackVersionsToModel', function() {
+        return $.Deferred().resolve()});
+      route = App.get('router.currentState.name');
+    });
+
+    afterEach(function() {
+      App.db.set.restore();
+      App.router.transitionTo.restore();
+      App.RepositoryVersion.find.restore();
+      App.get('router.repoVersionsManagementController').loadStackVersionsToModel.restore();
+      App.set('router.currentState.name', route);
+    });
+    it('success callback for install stack version without redirect', function () {
+      controller.installStackVersionSuccess({Requests: {id: requestId}}, null, {id: repoId});
+      expect(App.db.set.calledWith('repoVersion', 'id', [requestId])).to.be.true;
+      expect(App.get('router.repoVersionsManagementController').loadStackVersionsToModel.calledWith(true)).to.be.true;
+      expect(App.RepositoryVersion.find.calledOnce).to.be.true;
+      expect(controller.get('content')).to.be.eql(repoVersion);
+    });
+
+    it('success callback for install stack version', function () {
+      App.set('router.currentState.name', "update");
+      controller.installStackVersionSuccess({Requests: {id: requestId}}, null, {id: repoId});
+      expect(App.db.set.calledWith('repoVersion', 'id', [requestId])).to.be.true;
+      expect(App.get('router.repoVersionsManagementController').loadStackVersionsToModel.calledOnce).to.be.true;
+      expect(App.RepositoryVersion.find.called).to.be.true;
+      expect(App.router.transitionTo.calledWith('main.admin.adminStackVersions.version', repoVersion)).to.be.true;
     });
   });
+
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/test/controllers/main/admin/stack_version/stack_versions_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/admin/stack_version/stack_versions_controller_test.js b/ambari-web/test/controllers/main/admin/stack_version/stack_versions_controller_test.js
index 9eb4f92..4b38e58 100644
--- a/ambari-web/test/controllers/main/admin/stack_version/stack_versions_controller_test.js
+++ b/ambari-web/test/controllers/main/admin/stack_version/stack_versions_controller_test.js
@@ -27,73 +27,4 @@ describe('App.MainStackVersionsController', function () {
     controller = App.MainStackVersionsController.create();
   });
 
-  describe('#load()', function () {
-    it('loads data to model by running loadStackVersionsToModel', function () {
-      sinon.stub(controller, 'loadStackVersionsToModel').returns({done: Em.K});
-      sinon.stub(App.get('router.repoVersionsController'), 'loadRepoVersionsToModel').returns({done: Em.K});
-
-      controller.load();
-      expect(controller.loadStackVersionsToModel.calledOnce).to.be.true;
-      expect(App.get('router.repoVersionsController').loadRepoVersionsToModel.calledOnce).to.be.true;
-
-      controller.loadConfigVersionsToModel.restore();
-      App.get('router.repoVersionsController').loadRepoVersionsToModel.restore();
-    });
-  });
-
-  describe('#loadStackVersionsToModel()', function () {
-    it('loads data to model', function () {
-      sinon.stub(App.HttpClient, 'get', Em.K);
-      sinon.stub(controller, 'getUrl', Em.K);
-
-      controller.loadConfigVersionsToModel();
-      expect(App.HttpClient.get.calledOnce).to.be.true;
-      expect(controller.getUrl.calledWith([1])).to.be.true;
-
-
-      controller.getUrl.restore();
-      App.HttpClient.get.restore();
-    });
-  });
-
-  describe('#filterHostsByStack()', function () {
-    beforeEach(function() {
-      sinon.stub(App.router.get('mainHostController'), 'filterByStack').returns({done: Em.K});
-      sinon.stub(App.router, 'transitionTo').returns({done: Em.K});
-    });
-    afterEach(function() {
-      App.router.get('mainHostController').filterByStack.restore();
-      App.router.transitionTo.restore();
-    });
-    var tests = [
-      {
-        version: "version1",
-        state: "state1",
-        m: 'go to hosts filtered by host stack version and host stack state',
-        runAll: true
-      },
-      {
-        version: null,
-        state: "state1",
-        m: 'doesn\'t do anything because version is missing'
-      },
-      {
-        version: "version1",
-        state: null,
-        m: 'doesn\'t do anything because state is missing'
-      }
-    ].forEach(function(t) {
-        it(t.m, function () {
-          controller.load(t.version, t.stack);
-          if (t.runAll) {
-            expect(App.router.get('mainHostController').filterByStack.calledWith('hosts.index')).to.be.true;
-            expect(App.router.transitionTo.calledWith('hosts.index')).to.be.true;
-          } else {
-            expect(App.router.get('mainHostController').filterByStack.calledOnce).to.be.false;
-            expect(App.router.transitionTo.calledOnce).to.be.false;
-          }
-
-        });
-      });
-  });
 });
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/72552aa6/ambari-web/test/views/main/admin/stack_version/stack_version_details_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/admin/stack_version/stack_version_details_test.js b/ambari-web/test/views/main/admin/stack_version/stack_version_details_test.js
index 61c0cb4..f577a67 100644
--- a/ambari-web/test/views/main/admin/stack_version/stack_version_details_test.js
+++ b/ambari-web/test/views/main/admin/stack_version/stack_version_details_test.js
@@ -19,37 +19,98 @@
 
 var App = require('app');
 require('views/main/admin/stack_versions/stack_version_view');
-var mainStackVersionsDetailsView;
+var view;
 
 describe('App.MainStackVersionsDetailsView', function () {
 
   beforeEach(function () {
-    mainStackVersionsDetailsView = App.MainStackVersionsDetailsView.create();
-  });
-
-  describe('#statusClass', function () {
-    var tests = [
-      {
-        state: "ANY",
-        buttonClass: 'disabled'
-      },
-      {
-        state: "INSTALL",
-        buttonClass: 'btn-success'
-      },
-      {
-        state: "INSTALLING",
-        buttonClass: 'btn-primary'
+    view = App.MainStackVersionsDetailsView.create({
+      "controller": {
+        "hostsToInstall" : 0,
+        "progress": 0,
+        "doPolling": Em.K
       },
-      {
-        state: "INSTALL_FAILED",
-        buttonClass: "btn-danger"
+      "content": {
+        "stackVersion":
+          {
+            "state" : "ANY"
+          }
       }
-    ].forEach(function(t) {
-      it("status is " + t.status + " class is " + t.buttonClass, function() {
-        mainStackVersionsDetailsView.reopen({ content: {'state': t.state}});
-        expect(mainStackVersionsDetailsView.get('statusClass')).to.equal(t.buttonClass);
-      });
+    });
+  });
+
+  describe('#installButtonMsg', function () {
+    it("install button msg for init state" , function() {
+      view.set("controller.hostsToInstall", 2);
+      view.set("content.stackVersion.state", "ANY");
+      expect(view.get('installButtonMsg')).to.equal(Em.I18n.t('admin.stackVersions.datails.hosts.btn.install').format(2))
+    });
+
+    it("install button msg for install failed state" , function() {
+      view.set("content.stackVersion.state", "INSTALL_FAILED");
+      expect(view.get('installButtonMsg')).to.equal(Em.I18n.t('admin.stackVersions.datails.hosts.btn.reinstall'))
+    });
+  });
+
+  describe('#installButtonClass', function () {
+    it("install button class for init state" , function() {
+      view.set("content.stackVersion.state", "ANY");
+      expect(view.get('installButtonClass')).to.equal('btn-success')
+    });
+
+    it("install button class install failed state" , function() {
+      view.set("content.stackVersion.state", "INSTALL_FAILED");
+      expect(view.get('installButtonClass')).to.equal('btn-danger')
+    });
+  });
+
+  describe('#progress', function () {
+    it("this that is used as width of progress bar" , function() {
+      view.set("controller.progress", 20);
+      expect(view.get('progress')).to.equal('width:20%');
+    });
+  });
+
+  describe('#showCounters', function () {
+    it("true when repo version has cluster stack version" , function() {
+      view.set("content.stackVersion", Em.Object.create({}));
+      expect(view.get('showCounters')).to.be.true;
+    });
+    it("false when repo version has no cluster stack version" , function() {
+      view.set("content.stackVersion", null);
+      expect(view.get('showCounters')).to.be.false;
+    });
+  });
+
+  describe('#didInsertElement', function () {
+    beforeEach(function() {
+      sinon.stub(App.get('router.mainStackVersionsController'), 'set', Em.K);
+      sinon.stub(App.get('router.mainStackVersionsController'), 'doPolling', Em.K);
+      sinon.stub(view.get('controller'), 'doPolling', Em.K);
+    });
+    afterEach(function() {
+      App.get('router.mainStackVersionsController').set.restore();
+      App.get('router.mainStackVersionsController').doPolling.restore();
+      view.get('controller').doPolling.restore();
+    });
+    it("runs polling when view is in dom" , function() {
+      view.didInsertElement();
+      expect(App.get('router.mainStackVersionsController').set.calledWith('isPolling', true)).to.be.true;
+      expect(App.get('router.mainStackVersionsController').doPolling.calledOnce).to.be.true;
+      expect(view.get('controller').doPolling.calledOnce).to.be.true;
+    });
+  });
+
+  describe('#willDestroyElement', function () {
+    beforeEach(function() {
+      sinon.stub(App.get('router.mainStackVersionsController'), 'set', Em.K);
+    });
+    afterEach(function() {
+      App.get('router.mainStackVersionsController').set.restore();
+    });
+    it("runs polling when view is in dom" , function() {
+      view.willDestroyElement();
+      expect(App.get('router.mainStackVersionsController').set.calledWith('isPolling', false)).to.be.true;
     });
   });
 });