You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by at...@apache.org on 2015/01/14 13:15:19 UTC

[2/2] ambari git commit: AMBARI-9118 Merge "Admin > Stack and Upgrade" and "Admin > Versions" pages. (atkach)

AMBARI-9118 Merge "Admin > Stack and Upgrade" and "Admin > Versions" pages. (atkach)


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

Branch: refs/heads/trunk
Commit: c59df55e536f60c32c955292eefbdfe5e9123c5b
Parents: b0a3456
Author: Andrii Tkach <at...@hortonworks.com>
Authored: Wed Jan 14 13:50:49 2015 +0200
Committer: Andrii Tkach <at...@hortonworks.com>
Committed: Wed Jan 14 13:50:49 2015 +0200

----------------------------------------------------------------------
 .../admin-web/app/views/stackVersions/list.html |   2 +-
 ambari-web/app/assets/test/tests.js             |   4 -
 ambari-web/app/controllers.js                   |   4 -
 .../main/admin/stack_and_upgrade_controller.js  | 243 +++++++++++++------
 .../repo_version_management_controller.js       | 205 ----------------
 .../stack_versions/repo_versions_controller.js  |  37 ---
 .../stack_version_details_controller.js         | 193 ---------------
 .../stack_versions/stack_versions_controller.js |  25 --
 .../controllers/main/service/add_controller.js  |   9 +-
 ambari-web/app/messages.js                      |  35 +--
 ambari-web/app/routes/main.js                   |  48 ++--
 ambari-web/app/routes/stack_upgrade_routes.js   |   2 +-
 ambari-web/app/styles/application.less          |  42 ++--
 .../templates/main/admin/stack_and_upgrade.hbs  |  67 +----
 .../admin/stack_upgrade/edit_repositories.hbs   |  46 ++++
 .../main/admin/stack_upgrade/services.hbs       |  46 ++++
 .../admin/stack_upgrade/upgrade_version_box.hbs |  58 +++++
 .../main/admin/stack_upgrade/versions.hbs       |  34 +++
 ambari-web/app/views.js                         |   8 +-
 ambari-web/app/views/main/admin.js              |   9 +-
 .../views/main/admin/stack_and_upgrade_view.js  | 176 +-------------
 .../views/main/admin/stack_upgrade/menu_view.js |  61 +++++
 .../main/admin/stack_upgrade/services_view.js   |  43 ++++
 .../stack_upgrade/upgrade_version_box_view.js   | 150 ++++++++++--
 .../main/admin/stack_upgrade/versions_view.js   | 168 +++++++++++++
 .../app/views/main/admin/stack_versions/menu.js |  90 -------
 .../admin/stack_versions/operating_systems.js   |  60 -----
 .../admin/stack_versions/repo_version_view.js   | 101 --------
 .../stack_version_details_view.js               | 169 -------------
 .../admin/stack_versions/stack_version_view.js  | 154 ------------
 ambari-web/app/views/main/menu.js               |   7 -
 .../admin/stack_and_upgrade_controller_test.js  | 159 +-----------
 .../repo_version_management_controller_test.js  | 180 --------------
 .../repo_versions_controller_test.js            |  44 ----
 .../stack_version_details_controller_test.js    | 162 -------------
 .../stack_versions_controller_test.js           |  30 ---
 .../upgrade_version_box_view_test.js            |  34 ---
 .../stack_version/stack_version_details_test.js | 192 ---------------
 38 files changed, 828 insertions(+), 2269 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
index c661861..caefa6f 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
@@ -53,7 +53,7 @@
         <a href="#/stackVersions/{{repo.stack_name}}/{{repo.repository_version}}/edit">{{repo.display_name}}</a>
       </td>
       <td class="col-small">
-        <a href="/#/main/admin/versions/{{repo.stackVersionId}}" ng-show="repo.cluster">
+        <a href="/#/main/admin/stack/versions" ng-show="repo.cluster">
           {{repo.cluster}}
         </a>
         <select ng-show="!repo.cluster"

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/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 203b9c9..aa66fd9 100644
--- a/ambari-web/app/assets/test/tests.js
+++ b/ambari-web/app/assets/test/tests.js
@@ -52,9 +52,6 @@ var files = ['test/init_model_test',
   'test/controllers/main/admin/kerberos_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',
   'test/controllers/main/admin/highAvailability/progress_controller_test',
@@ -168,7 +165,6 @@ var files = ['test/init_model_test',
   'test/views/main/alert_definitions_view_test',
   'test/views/main/alerts/manage_alert_groups_view_test',
   'test/views/main/alerts/manage_alert_notifications_view_test',
-  'test/views/main/admin/stack_version/stack_version_details_test',
   'test/views/main/admin/stack_upgrade/upgrade_version_box_view_test',
   'test/views/main/admin/stack_upgrade/upgrade_group_view_test',
   'test/views/main/admin/stack_upgrade/upgrade_task_view_test',

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/ambari-web/app/controllers.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers.js b/ambari-web/app/controllers.js
index b09710f..7e9c288 100644
--- a/ambari-web/app/controllers.js
+++ b/ambari-web/app/controllers.js
@@ -53,10 +53,6 @@ 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');
 require('controllers/main/admin/serviceAccounts_controller');
 require('controllers/main/admin/advanced');
 require('utils/polling');

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/ambari-web/app/controllers/main/admin/stack_and_upgrade_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/stack_and_upgrade_controller.js b/ambari-web/app/controllers/main/admin/stack_and_upgrade_controller.js
index 341084b..6970ff0 100644
--- a/ambari-web/app/controllers/main/admin/stack_and_upgrade_controller.js
+++ b/ambari-web/app/controllers/main/admin/stack_and_upgrade_controller.js
@@ -17,15 +17,14 @@
  */
 
 var App = require('app');
-var stringUtils = require('utils/string_utils');
 
 App.MainAdminStackAndUpgradeController = Em.Controller.extend(App.LocalStorage, {
   name: 'mainAdminStackAndUpgradeController',
 
   /**
-   * @type {Object|null}
+   * @type {boolean}
    */
-  serviceToInstall: null,
+  isLoaded: false,
 
   /**
    * @type {object}
@@ -47,7 +46,8 @@ App.MainAdminStackAndUpgradeController = Em.Controller.extend(App.LocalStorage,
 
   /**
    * version that currently applied to server
-   * @type {Object|null}
+   * should be plain object, because stored to localStorage
+   * @type {object|null}
    */
   currentVersion: null,
 
@@ -62,83 +62,86 @@ App.MainAdminStackAndUpgradeController = Em.Controller.extend(App.LocalStorage,
    */
   wizardStorageProperties: ['upgradeId', 'upgradeVersion', 'currentVersion'],
 
-  init: function () {
-    this.initDBProperties();
-  },
+  /**
+   * path to the mock json
+   * @type {String}
+   */
+  mockRepoUrl: '/data/stack_versions/repo_versions_all.json',
 
   /**
-   * restore data from localStorage
+   * api to get RepoVersions
+   * @type {String}
    */
-  initDBProperties: function () {
-    this.get('wizardStorageProperties').forEach(function (property) {
-      if (this.getDBProperty(property)) {
-        this.set(property, this.getDBProperty(property));
-      }
-    }, this);
-  },
+  realRepoUrl: function () {
+    //TODO correct url after api will be fixed
+    return App.get('apiPrefix') + App.get('stackVersionURL') +
+      '/repository_versions?fields=*,operating_systems/*,operating_systems/repositories/*,operatingSystems/*,operatingSystems/repositories/*';
+  }.property('App.stackVersionURL'),
 
   /**
-   * @type {Array}
+   * path to the mock json
+   * @type {String}
    */
-  services: function() {
-    return App.StackService.find().map(function(s) {
-      s.set('isInstalled', App.Service.find().someProperty('serviceName', s.get('serviceName')));
-      return s;
-    });
-  }.property('App.router.clusterController.isLoaded'),
+  mockStackUrl: '/data/stack_versions/stack_version_all.json',
 
   /**
-   * launch Add Service wizard
-   * @param event
+   * api to get ClusterStackVersions with repository_versions (use to init data load)
+   * @type {String}
    */
-  goToAddService: function (event) {
-    this.set('serviceToInstall', event.context);
-    App.get('router').transitionTo('main.serviceAdd');
-  },
+  realStackUrl: function () {
+    //TODO correct url after api will be fixed
+    return App.apiPrefix + '/clusters/' + App.get('clusterName') +
+      '/stack_versions?fields=*,repository_versions/*,repository_versions/operating_systems/repositories/*,repository_versions/operatingSystems/repositories/*';
+  }.property('App.clusterName'),
 
   /**
-   * call to fetch cluster stack versions
-   * @return {$.ajax}
+   * api to get ClusterStackVersions without repository_versions (use to update data)
+   * @type {String}
    */
-  loadVersionsInfo: function () {
-    return App.ajax.send({
-      name: 'admin.stack_versions.all',
-      sender: this,
-      data: {},
-      success: 'loadVersionsInfoSuccessCallback'
-    });
+  realUpdateUrl: function () {
+    return App.apiPrefix + '/clusters/' + App.get('clusterName') + '/stack_versions?fields=ClusterStackVersions/*';
+  }.property('App.clusterName'),
+
+  init: function () {
+    this.initDBProperties();
   },
 
   /**
-   * parse stack versions and
-   * set <code>currentVersion</code>
-   * set <code>targetVersions</code>
-   * @param data
+   * restore data from localStorage
    */
-  loadVersionsInfoSuccessCallback: function (data) {
-    var versions = this.parseVersionsData(data);
-    var current = versions.findProperty('state', 'CURRENT');
-    var targetVersions = versions.without(current).filter(function (version) {
-      //Only higher versions that have already been installed to all the hosts are shown
-      return (version.state === 'INSTALLED' &&
-        stringUtils.compareVersions(version.repository_version, current.repository_version) === 1);
-    });
-    this.set('currentVersion', current);
-    this.set('targetVersions', targetVersions);
+  initDBProperties: function () {
+    this.get('wizardStorageProperties').forEach(function (property) {
+      if (this.getDBProperty(property)) {
+        this.set(property, this.getDBProperty(property));
+      }
+    }, this);
   },
 
   /**
-   * parse ClusterStackVersions data to form common structure
-   * @param {object} data
-   * @return {Array}
-   */
-  parseVersionsData: function (data) {
-    return data.items.map(function (item) {
-      item.ClusterStackVersions.repository_name = item.repository_versions[0].RepositoryVersions.display_name;
-      item.ClusterStackVersions.repository_id = item.repository_versions[0].RepositoryVersions.id;
-      item.ClusterStackVersions.repository_version = item.repository_versions[0].RepositoryVersions.repository_version;
-      return item.ClusterStackVersions;
+   * load all data:
+   * - upgrade data
+   * - stack versions
+   * - repo versions
+   */
+  load: function () {
+    var dfd = $.Deferred();
+    var self = this;
+
+    this.loadUpgradeData(true).done(function() {
+      self.loadStackVersionsToModel(true).done(function () {
+        self.loadRepoVersionsToModel().done(function() {
+          var currentVersion = App.StackVersion.find().findProperty('state', 'CURRENT');
+          if (currentVersion) {
+            self.set('currentVersion', {
+              repository_version: currentVersion.get('repositoryVersion.repositoryVersion'),
+              repository_name: currentVersion.get('repositoryVersion.displayName'),
+            });
+          }
+          dfd.resolve();
+        });
+      });
     });
+    return dfd.promise();
   },
 
   /**
@@ -184,9 +187,9 @@ App.MainAdminStackAndUpgradeController = Em.Controller.extend(App.LocalStorage,
    */
   updateUpgradeData: function (newData) {
     var oldData = this.get('upgradeData'),
-        groupsMap = {},
-        itemsMap = {},
-        tasksMap = {};
+      groupsMap = {},
+      itemsMap = {},
+      tasksMap = {};
 
     if (Em.isNone(oldData)) {
       this.initUpgradeData(newData);
@@ -319,15 +322,20 @@ App.MainAdminStackAndUpgradeController = Em.Controller.extend(App.LocalStorage,
    * @param version
    */
   runPreUpgradeCheck: function(version) {
+    var params = {
+      value: version.get('repositoryVersion'),
+      label: version.get('displayName')
+    };
+
     if (App.get('supports.preUpgradeCheck')) {
       App.ajax.send({
         name: "admin.rolling_upgrade.pre_upgrade_check",
         sender: this,
-        data: version,
+        data: params,
         success: "runPreUpgradeCheckSuccess"
       });
     } else {
-      this.upgrade(version);
+      this.upgrade(params);
     }
   },
 
@@ -349,12 +357,57 @@ App.MainAdminStackAndUpgradeController = Em.Controller.extend(App.LocalStorage,
       this.upgrade(params);
     }
   },
+
   /**
-   * make call to resume upgrade process and show popup with current progress
+   * sends request to install repoVersion to the cluster
+   * and create clusterStackVersion resourse
+   * @param {Em.Object} repo
+   * @return {$.ajax}
+   * @method installRepoVersion
    */
-  resumeUpgrade: function () {
-    //TODO resume upgrade
-    this.openUpgradeDialog();
+  installRepoVersion: function (repo) {
+    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: 'installRepoVersionSuccess'
+    });
+  },
+
+  saveRepoOS: function () {
+    //TODO integrate with API
+  },
+
+  /**
+   * success callback for <code>installRepoVersion()<code>
+   * saves request id to the db
+   * @param data
+   * @param opt
+   * @param params
+   * @method installStackVersionSuccess
+   */
+  installRepoVersionSuccess: function (data, opt, params) {
+    App.db.set('repoVersionInstall', 'id', [data.Requests.id]);
+  },
+
+  /**
+   * opens a popup with installations state per host
+   * @param {Em.Object} version
+   * @method showProgressPopup
+   */
+  showProgressPopup: function(version) {
+    var popupTitle = Em.I18n.t('admin.stackVersions.details.install.hosts.popup.title').format(version.get('displayName'));
+    var requestIds = App.get('testMode') ? [1] : App.db.get('repoVersionInstall', 'id');
+    var hostProgressPopupController = App.router.get('highAvailabilityProgressPopupController');
+    hostProgressPopupController.initPopup(popupTitle, requestIds, this);
   },
 
   /**
@@ -388,5 +441,55 @@ App.MainAdminStackAndUpgradeController = Em.Controller.extend(App.LocalStorage,
    */
   openUpgradeDialog: function () {
     App.router.transitionTo('admin.stackUpgrade');
+  },
+
+  /**
+   * 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();
   }
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/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
deleted file mode 100644
index ef6182c..0000000
--- a/ambari-web/app/controllers/main/admin/stack_versions/repo_version_management_controller.js
+++ /dev/null
@@ -1,205 +0,0 @@
-/**
- * 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 () {
-    //TODO correct url after api will be fixed
-    return App.get('apiPrefix') + App.get('stackVersionURL') +
-      '/repository_versions?fields=*,operating_systems/*,operating_systems/repositories/*,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 () {
-    //TODO correct url after api will be fixed
-    return App.apiPrefix + '/clusters/' + App.get('clusterName') +
-      '/stack_versions?fields=*,repository_versions/*,repository_versions/operating_systems/repositories/*,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'),
-
-  /**
-   * 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();
-  },
-
-  /**
-   * loads all needed data
-   * @returns {$.Deferred().promise()}
-   * @method load
-   */
-  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');
-  },
-
-  /**
-   * runs <code>showHostsListPopup<code>
-   * @param event
-   * @returns {void}
-   * @method showHosts
-   */
-  showHosts: function(event) {
-    var status = event.contexts[0];
-    var version = event.contexts[1];
-    var hosts = event.contexts[2];
-    this.showHostsListPopup(status, version, hosts);
-  },
-
-  /**
-   * shows popup with listed hosts wich has current state of hostStackVersion
-   * @param {Object} status - status of repoverion
-   *    {id: "string", label: "string"}
-   * @param {string} version - repo version name
-   * @param {[string]} hosts - array of host containing current repo version in proper state
-   * @returns {App.ModalPopup}
-   * @method showHostsListPopup
-   */
-  showHostsListPopup: function(status, version, hosts) {
-    var self = this;
-    if (hosts.length) {
-      return App.ModalPopup.show({
-        bodyClass: Ember.View.extend({
-          title: Em.I18n.t('admin.stackVersions.hosts.popup.title').format(version, status.label, 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.label),
-        primary: Em.I18n.t('admin.stackVersions.hosts.popup.primary'),
-        secondary: Em.I18n.t('common.close'),
-        onPrimary: function() {
-          this.hide();
-          self.filterHostsByStack(version, status.id);
-        }
-      });
-    }
-  }
-});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/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
deleted file mode 100644
index 127930a..0000000
--- a/ambari-web/app/controllers/main/admin/stack_versions/repo_versions_controller.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * 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.RepoVersionsController = App.RepoVersionsManagementController.extend({
-  name: 'repoVersionsController',
-
-  content: function () {
-    return App.RepositoryVersion.find().filterProperty('stackVersion', null);
-  }.property('dataIsLoaded'),
-
-  /**
-   * installs repoversion to the cluster by running <code>installRepoVersion<code> method
-   * of <code>mainStackVersionsDetailsController<code> controller
-   * @param event
-   * @method installRepoVersion
-   */
-  installRepoVersion: function(event) {
-    App.get('router.mainStackVersionsDetailsController').installRepoVersion(event);
-  }
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/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
deleted file mode 100644
index 454c99d..0000000
--- a/ambari-web/app/controllers/main/admin/stack_versions/stack_version_details_controller.js
+++ /dev/null
@@ -1,193 +0,0 @@
-/**
- * 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.MainStackVersionsDetailsController = Em.Controller.extend({
-  name: 'mainStackVersionsDetailsController',
-
-  content: null,
-
-  /**
-   * timeOut function to load updated progress
-   * when install repo wersion is running
-   */
-  timeoutRef: null,
-
-  /**
-   * true if stack version install is in progress
-   * @type {Boolean}
-   */
-  installFailed: function() {
-    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.stackVersion.state') == "INSTALLING";
-  }.property('content.stackVersion.state'),
-
-  /**
-   * true if repo version is installed on all hosts but not upgraded
-   * @type {Boolean}
-   */
-  installComplete: function() {
-    return this.get('content.stackVersion.state')
-      && !["INSTALLING", "INSTALL_FAILED", "OUT_OF_SYNC"].contains(this.get('content.stackVersion.state'));
-  }.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') || ["INSTALL_FAILED", "OUT_OF_SYNC"].contains(this.get('content.stackVersion.state'));
-  }.property('content.stackVersion.state'),
-
-  /**
-   * true if repo version is current
-   * @type {Boolean}
-   */
-  current: function() {
-    return this.get('content.stackVersion.state') == "CURRENT";
-  }.property('content.stackVersion.state'),
-
-  /**
-   * counter that is shown on install button
-   * @type {Number}
-   */
-  hostsToInstall: function() {
-    return this.get('content.stackVersion') ? this.get('content.stackVersion.notInstalledHosts.length') : App.get('allHostNames.length');
-  }.property('content.stackVersion.notInstalledHosts.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.details.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'));
-      }
-    }, 3000));
-  },
-
-  /**
-   * 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.high_availability.polling',
-      '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')));
-      this.set('logs', data.tasks);
-    }
-  },
-
-  /**
-   * 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: 'installRepoVersionSuccess'
-    });
-  },
-
-  /**
-   * 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
-   */
-  installRepoVersionSuccess: 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);
-        self.doPolling();
-      }
-    });
-  }
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/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
deleted file mode 100644
index c61ac03..0000000
--- a/ambari-web/app/controllers/main/admin/stack_versions/stack_versions_controller.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * 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.MainStackVersionsController = App.RepoVersionsManagementController.extend({
-  name: 'mainStackVersionsController',
-
-  content: App.StackVersion.find()
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/ambari-web/app/controllers/main/service/add_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/add_controller.js b/ambari-web/app/controllers/main/service/add_controller.js
index e97ab09..9ecc85b 100644
--- a/ambari-web/app/controllers/main/service/add_controller.js
+++ b/ambari-web/app/controllers/main/service/add_controller.js
@@ -29,9 +29,12 @@ App.AddServiceController = App.WizardController.extend({
    */
   hideBackButton: true,
 
-  serviceToInstall: function() {
-    return App.get('router.mainAdminStackAndUpgradeController.serviceToInstall');
-  }.property('App.router.mainAdminStackAndUpgradeController.serviceToInstall'),
+  /**
+   * @type {object}
+   * @default null
+   */
+  serviceToInstall: null,
+
   /**
    * All wizards data will be stored in this variable
    *

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index f81e3a5..5fe6c4f 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -1296,29 +1296,13 @@ Em.I18n.translations = {
   'admin.misc.header': 'Service Users and Groups',
   'admin.misc.nothingToShow': 'No user accounts to display',
 
-  'admin.stackVersions.table.header.stack': "Stack",
-  'admin.stackVersions.table.header.version': "Version",
-  'admin.stackVersions.table.header.os': "OS",
-  'admin.stackVersions.table.header.installed': "Installed on",
-  'admin.stackVersions.table.header.current': "Current on",
-  'admin.stackVersions.table.empty': "No cluster stack versions to display",
-  'admin.repoVersions.table.empty': "No repository versions to display",
-
-  'admin.stackVersions.details.versionName': "Version Name",
-  'admin.stackVersions.details.installed.on': "Installed on",
-  'admin.stackVersions.details.current.on': "Current on",
-  'admin.stackVersions.details.not.installed.on': "Not installed on",
-  'admin.stackVersions.details.host': "host",
-  'admin.stackVersions.details.hosts': "hosts",
-  'admin.stackVersions.details.base.url': "Base Url",
-
-  'admin.stackVersions.details.hosts.btn.reinstall': "Reinstall on failed hosts",
-  'admin.stackVersions.details.hosts.btn.install': "Install to {0} hosts",
-  'admin.stackVersions.details.hosts.btn.installing': "Installing...",
-  'admin.stackVersions.details.hosts.btn.nothing': "Installed on all hosts.",
-  'admin.stackVersions.details.hosts.btn.goto.upgrade': "Proceed to upgrade",
-  'admin.stackVersions.details.hosts.btn.na': "Status not available",
-  'admin.stackVersions.details.install.hosts.popup.title': "Install {0} version",
+  'admin.stackVersions.filter.notInstalled': "Not Installed",
+  'admin.stackVersions.filter.upgradeReady': "Upgrade Ready",
+  'admin.stackVersions.manageVersions': "Manage Versions",
+  'admin.stackVersions.version.installNow': "Install Now",
+  'admin.stackVersions.version.performUpgrade': "Perform Upgrade",
+  'admin.stackVersions.version.upgrade.pause': "Upgrade: Action Required",
+  'admin.stackVersions.version.upgrade.running': "Upgrade: In Process",
 
   'admin.stackVersions.hosts.popup.header.current': "Current",
   'admin.stackVersions.hosts.popup.header.installed': "Installed",
@@ -1327,13 +1311,12 @@ Em.I18n.translations = {
   'admin.stackVersions.hosts.popup.title': "{0} Version is {1} on {2} hosts:",
   'admin.stackVersions.hosts.popup.primary': "Go to Hosts",
 
-  'admin.stackVersions.updateTab.title.available': "Updates Available ({0})",
-  'admin.stackVersions.updateTab.title.not.available': "No Updates Available",
+  'admin.stackVersions.details.install.hosts.popup.title': "Install {0} version",
 
   'admin.stackUpgrade.downgrade.proceed': "Proceed with Downgrade",
   'admin.stackUpgrade.downgrade.title': "Downgrade to {0}",
   'admin.stackUpgrade.downgrade.body': "Are you sure you wish to abort the upgrade process and downgrade to {0}",
-  'admin.stackUpgrade.title': "Stack and upgrade",
+  'admin.stackUpgrade.title': "Stack and Versions",
   'admin.stackUpgrade.hostsOnline': "{0}/{1} hosts online",
   'admin.stackUpgrade.state.available': "Upgrade Available",
   'admin.stackUpgrade.state.notAvailable': "No Upgrade Available",

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/ambari-web/app/routes/main.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/main.js b/ambari-web/app/routes/main.js
index 71446bb..b65aaa9 100644
--- a/ambari-web/app/routes/main.js
+++ b/ambari-web/app/routes/main.js
@@ -300,7 +300,7 @@ module.exports = Em.Route.extend({
        router.transitionTo('admin' + controller.get('category').capitalize());
        }, */
       route: '/',
-      redirectsTo: 'stackAndUpgrade'
+      redirectsTo: 'stackAndUpgrade.index'
     }),
 
     adminAuthentication: Em.Route.extend({
@@ -439,38 +439,36 @@ module.exports = Em.Route.extend({
       connectOutlets: function (router) {
         router.set('mainAdminController.category', "stackAndUpgrade");
         router.get('mainAdminController').connectOutlet('mainAdminStackAndUpgrade');
-      }
-    }),
-    stackUpgrade: require('routes/stack_upgrade_routes'),
-
-    adminStackVersions: Em.Route.extend({
-      route: '/versions',
-      enter: function (router) {
-        if (App.get('supports.stackUpgrade')) {
-          router.set('mainAdminController.category', "stackVersions");
-        } else {
-          router.transitionTo('admin.stackAndUpgrade');
-        }
       },
+
       index: Em.Route.extend({
         route: '/',
-        connectOutlets: function (router) {
-          router.get('mainAdminController').connectOutlet('mainStackVersions');
-        }
+        redirectsTo: 'services'
       }),
-      version: Em.Route.extend({
-        route: '/:repository_version_id',
-        connectOutlets: function (router, repoVersion) {
-          router.get('mainAdminController').connectOutlet('mainStackVersionsDetails', repoVersion);
+
+      services: Em.Route.extend({
+        route: '/services',
+        connectOutlets: function (router, context) {
+          router.get('mainAdminStackAndUpgradeController').connectOutlet('mainAdminStackServices');
         }
       }),
-      update: Em.Route.extend({
-        route: '/updates',
-        connectOutlets: function (router) {
-          router.get('mainAdminController').connectOutlet('repoVersions');
+
+      versions: Em.Route.extend({
+        route: '/versions',
+        connectOutlets: function (router, context) {
+          router.get('mainAdminStackAndUpgradeController').connectOutlet('MainAdminStackVersions');
         }
-      })
+      }),
+
+      stackNavigate: function (router, event) {
+        var parent = event.view._parentView;
+        parent.deactivateChildViews();
+        event.view.set('active', "active");
+        router.transitionTo(event.context);
+      }
     }),
+    stackUpgrade: require('routes/stack_upgrade_routes'),
+
     adminAdvanced: Em.Route.extend({
       route: '/advanced',
       connectOutlets: function (router) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/ambari-web/app/routes/stack_upgrade_routes.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/stack_upgrade_routes.js b/ambari-web/app/routes/stack_upgrade_routes.js
index be0f7e5..0f7ce20 100644
--- a/ambari-web/app/routes/stack_upgrade_routes.js
+++ b/ambari-web/app/routes/stack_upgrade_routes.js
@@ -57,7 +57,7 @@ module.exports = App.WizardRoute.extend({
         },
         closeWizard: function () {
           App.router.get('updateController').set('isWorking', true);
-          App.router.transitionTo('main.admin.stackAndUpgrade');
+          App.router.transitionTo('main.admin.stackAndUpgrade.versions');
           this.hide();
         }
       });

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/ambari-web/app/styles/application.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/application.less b/ambari-web/app/styles/application.less
index 0e13ff4..8a28084 100644
--- a/ambari-web/app/styles/application.less
+++ b/ambari-web/app/styles/application.less
@@ -6300,35 +6300,29 @@ i.icon-asterisks {
 }
 
 #stack-upgrade-page {
-  .upgrade-flow {
-    margin: 50px 0;
-    .box {
-      text-align: center;
-      .version-name {
-        padding: 15px 10px;
+  .version-box {
+    border: 1px black solid;
+    margin: 15px 15px 0 0;
+    padding: 5px;
+    a.not-active:hover {
+      text-decoration: none;
+    }
+    .state {
+      margin: 15px 0;
+      line-height: 30px;
+      i {
+        color: #0088cc;
+        font-size: 16px;
       }
-      select {
-        width: initial;
-        min-width: 80%;
-        margin: 10px;
+      .label {
+        padding: 5px 20px;
+        font-size: 14px;
       }
     }
-    .flex-width {
-      width: initial;
-      padding: 0 10px;
-      min-width: 140px;
+    .host-link a {
+      color: black;
     }
   }
-  .upgrade-flow>div {
-    height: 100px;
-  }
-  .go-to {
-    height: 30px;
-    font-size: 25px;
-    text-align: center;
-    margin-top: 30px;
-    color: #777;
-  }
 }
 
 #stack-upgrade-dialog {

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/ambari-web/app/templates/main/admin/stack_and_upgrade.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/stack_and_upgrade.hbs b/ambari-web/app/templates/main/admin/stack_and_upgrade.hbs
index ef2f65e..e0a7242 100644
--- a/ambari-web/app/templates/main/admin/stack_and_upgrade.hbs
+++ b/ambari-web/app/templates/main/admin/stack_and_upgrade.hbs
@@ -17,69 +17,6 @@
 }}
 
 <div id="stack-upgrade-page">
-  {{#if App.supports.stackUpgrade}}
-    <div class="header bottom-border">
-      <strong>{{t common.upgrade}}</strong>
-      <span class="pull-right">{{view.hostsOnlineLabel}}</span>
-    </div>
-    <div class="row-fluid upgrade-flow">
-      {{#view view.sourceVersionView classNames="span2 offset3 box flex-width"}}
-        <div class="version-name"><strong>{{view.versionName}}</strong></div>
-        <div>
-          {{view.hostsCount}}
-          &nbsp;{{pluralize view.hostsCount singular="t:admin.stackUpgrade.host" plural="t:admin.stackUpgrade.hosts"}}
-        </div>
-      {{/view}}
-      <div class="span1">
-        <div class="go-to"><i class="icon-arrow-right"></i></div>
-        <div>{{view.upgradeStateLabel}}</div>
-      </div>
-      {{#view view.targetVersionView classNames="span2 box flex-width"}}
-        {{view Ember.Select
-        classBinding="view.showSelect::hidden"
-        contentBinding="view.versionsSelectContent"
-        optionValuePath="content.value"
-        optionLabelPath="content.label"
-        selectionBinding="view.version"
-        }}
-        <div {{bindAttr class="view.showSelect:hidden :version-name"}}><strong>{{view.versionName}}</strong>
-        </div>
-        <div>
-          {{#if view.label}}
-            <button {{bindAttr class=":btn view.btnClass"}} {{action runAction target="view"}}>{{view.label}}</button>
-          {{/if}}
-        </div>
-      {{/view}}
-    </div>
-  {{/if}}
-  <div class="header bottom-border">
-    <strong>{{t common.stack}}: {{App.currentStackVersion}}</strong>
-  </div>
-  <table class="table table-bordered table-striped">
-    <thead>
-    <tr>
-      <th>{{t common.service}}</th>
-      <th>{{t common.version}}</th>
-      <th>{{t common.status}}</th>
-      <th>{{t common.description}}</th>
-    </tr>
-    </thead>
-    <tbody>
-    {{#each service in services}}
-      <tr>
-        <td class="service-display-name">{{service.displayName}}</td>
-        <td class="service-stack-version">{{service.stackVersion}}</td>
-        <td class="stack-version-state">
-          {{#if service.isInstalled}}
-            <span class="label label-success">{{t common.installed}}</span>
-          {{else}}
-            <a class="path-link" {{action goToAddService service.serviceName target="controller"}}>
-              {{t services.service.add}}</a>
-          {{/if}}
-        </td>
-        <td class="service-description">{{{service.comments}}}</td>
-      </tr>
-    {{/each}}
-    </tbody>
-  </table>
+  {{view App.MainAdminStackMenuView}}
+  {{outlet}}
 </div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/ambari-web/app/templates/main/admin/stack_upgrade/edit_repositories.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/stack_upgrade/edit_repositories.hbs b/ambari-web/app/templates/main/admin/stack_upgrade/edit_repositories.hbs
new file mode 100644
index 0000000..bb786b0
--- /dev/null
+++ b/ambari-web/app/templates/main/admin/stack_upgrade/edit_repositories.hbs
@@ -0,0 +1,46 @@
+{{!
+* 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.
+}}
+
+
+<div class="row-fluid">
+  <div class="span2"><strong>{{t common.os}}</strong></div>
+  <div class="span10 row-fluid">
+    <div class="span3"><strong>{{t common.name}}</strong></div>
+    <div class="span9"><strong>{{t admin.cluster.repositories.baseUrl}}</strong></div>
+  </div>
+</div>
+{{#each os in view.content.operatingSystems}}
+  <div class="row-fluid">
+    <div class="span2">
+      {{os.osType}}
+    </div>
+    <div class="span10">
+      {{#each repository in os.repositories}}
+        <div class="row-fluid">
+          <div class="span3">{{repository.repoName}}</div>
+          <div class="span9">{{view Ember.TextField}}</div>
+        </div>
+      {{/each}}
+    </div>
+  </div>
+{{/each}}
+
+<div>
+  {{view Ember.Checkbox checkedBinding="view.skipValidation"}}&nbsp;
+  {{t installer.step1.advancedRepo.skipValidation.message}}
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/ambari-web/app/templates/main/admin/stack_upgrade/services.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/stack_upgrade/services.hbs b/ambari-web/app/templates/main/admin/stack_upgrade/services.hbs
new file mode 100644
index 0000000..1be48db
--- /dev/null
+++ b/ambari-web/app/templates/main/admin/stack_upgrade/services.hbs
@@ -0,0 +1,46 @@
+{{!
+* 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.
+}}
+
+
+<table class="table table-bordered table-striped">
+  <thead>
+  <tr>
+    <th>{{t common.service}}</th>
+    <th>{{t common.version}}</th>
+    <th>{{t common.status}}</th>
+    <th>{{t common.description}}</th>
+  </tr>
+  </thead>
+  <tbody>
+  {{#each service in view.services}}
+    <tr>
+      <td class="service-display-name">{{service.displayName}}</td>
+      <td class="service-stack-version">{{service.stackVersion}}</td>
+      <td class="stack-version-state">
+        {{#if service.isInstalled}}
+          <span class="label label-success">{{t common.installed}}</span>
+        {{else}}
+          <a class="path-link" {{action goToAddService service.serviceName target="view"}}>
+            {{t services.service.add}}</a>
+        {{/if}}
+      </td>
+      <td class="service-description">{{{service.comments}}}</td>
+    </tr>
+  {{/each}}
+  </tbody>
+</table>

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_version_box.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_version_box.hbs b/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_version_box.hbs
new file mode 100644
index 0000000..b98567c
--- /dev/null
+++ b/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_version_box.hbs
@@ -0,0 +1,58 @@
+{{!
+* 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.
+}}
+
+<p class="align-center">
+  <strong>{{view.content.displayName}}</strong>
+  <a class="pull-right not-active" {{action editRepositories target="view"}}>
+    <i class="icon-edit"></i>
+  </a>
+</p>
+<p class="align-center state">
+  {{#if view.stateElement.isButton}}
+    <button class="btn btn-primary" {{action runAction view.stateElement target="view"}}>{{view.stateElement.text}}</button>
+  {{/if}}
+  {{#if view.stateElement.isLabel}}
+    <span {{bindAttr class="view.stateElement.class"}}>{{view.stateElement.text}}</span>
+  {{/if}}
+  {{#if view.stateElement.isLink}}
+    {{#if view.stateElement.iconClass}}
+      <i {{bindAttr class="view.stateElement.iconClass"}}></i>
+    {{/if}}
+    <a href="#" {{action runAction view.stateElement target="view"}}>{{view.stateElement.text}}</a>
+  {{/if}}
+</p>
+<div class="row-fluid host-link">
+  <div class="span4 align-center">
+    <div><a href="#" class="not-active"
+      {{action showHosts view.versionStateMap.not_installed view.content.repositoryVersion view.content.notInstalledHosts target="view"}}>
+      {{view.content.notInstalledHosts.length}}</a></div>
+    <div>{{t admin.stackVersions.filter.notInstalled}}</div>
+  </div>
+  <div class="span4 align-center">
+    <div><a href="#" class="not-active"
+      {{action showHosts view.versionStateMap.installed view.content.repositoryVersion view.content.installedHosts target="view"}}>
+      {{view.content.installedHosts.length}}</a></div>
+    <div>{{t common.installed}}</div>
+  </div>
+  <div class="span4 align-center">
+    <div><a href="#" class="not-active"
+      {{action showHosts view.versionStateMap.current view.content.repositoryVersion view.content.currentHosts target="view"}}>
+      {{view.content.currentHosts.length}}</a></div>
+    <div>{{t common.current}}</div>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/ambari-web/app/templates/main/admin/stack_upgrade/versions.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/stack_upgrade/versions.hbs b/ambari-web/app/templates/main/admin/stack_upgrade/versions.hbs
new file mode 100644
index 0000000..3a8287c
--- /dev/null
+++ b/ambari-web/app/templates/main/admin/stack_upgrade/versions.hbs
@@ -0,0 +1,34 @@
+{{!
+* 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.
+}}
+
+
+<div>
+  {{view view.filterView}}
+  {{#isAccessible upgrade_ONLY_ADMIN}}
+    <button class="btn pull-right" {{action goToVersions target="view"}}>{{t admin.stackVersions.manageVersions}}</button>
+  {{/isAccessible}}
+</div>
+<div class="row-fluid">
+  {{#if isLoaded}}
+    {{#each version in view.filteredVersions}}
+      {{view App.UpgradeVersionBoxView contentBinding="version"}}
+    {{/each}}
+  {{else}}
+    <div class="spinner"></div>
+  {{/if}}
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/ambari-web/app/views.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js
index 9971914..1991b06 100644
--- a/ambari-web/app/views.js
+++ b/ambari-web/app/views.js
@@ -121,12 +121,10 @@ require('views/main/admin/stack_upgrade/upgrade_wizard_view');
 require('views/main/admin/stack_upgrade/upgrade_version_box_view');
 require('views/main/admin/stack_upgrade/upgrade_group_view');
 require('views/main/admin/stack_upgrade/upgrade_task_view');
+require('views/main/admin/stack_upgrade/services_view');
+require('views/main/admin/stack_upgrade/versions_view');
+require('views/main/admin/stack_upgrade/menu_view');
 require('views/main/admin/stack_and_upgrade_view');
-require('views/main/admin/stack_versions/menu');
-require('views/main/admin/stack_versions/operating_systems');
-require('views/main/admin/stack_versions/repo_version_view');
-require('views/main/admin/stack_versions/stack_version_view');
-require('views/main/admin/stack_versions/stack_version_details_view');
 require('views/main/admin/advanced');
 require('views/main/admin/advanced/password');
 require('views/main/admin/audit');

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/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 2507f98..0c61d01 100644
--- a/ambari-web/app/views/main/admin.js
+++ b/ambari-web/app/views/main/admin.js
@@ -25,16 +25,9 @@ App.MainAdminView = Em.View.extend({
     var items = [];
     items.push({
       name: 'stackAndUpgrade',
-      url: 'stackAndUpgrade',
+      url: 'stackAndUpgrade.index',
       label: Em.I18n.t('admin.stackUpgrade.title')
     });
-    if (App.get('supports.stackUpgrade')) {
-      items.push({
-        name: 'stackVersions',
-        url: 'adminStackVersions.index',
-        label: Em.I18n.t('common.versions')
-      });
-    }
     items.push({
       name: 'serviceAccounts',
       url: 'adminServiceAccounts',

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/ambari-web/app/views/main/admin/stack_and_upgrade_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/stack_and_upgrade_view.js b/ambari-web/app/views/main/admin/stack_and_upgrade_view.js
index 3c90e74..ffa41c8 100644
--- a/ambari-web/app/views/main/admin/stack_and_upgrade_view.js
+++ b/ambari-web/app/views/main/admin/stack_and_upgrade_view.js
@@ -20,180 +20,6 @@ var App = require('app');
 var stringUtils = require('utils/string_utils');
 
 App.MainAdminStackAndUpgradeView = Em.View.extend({
-  templateName: require('templates/main/admin/stack_and_upgrade'),
-
-  /**
-   * update timer
-   * @type {number|null}
-   * @default null
-   */
-  updateTimer: null,
-
-  /**
-   * label with number of HEALTHY hosts
-   * @type {String}
-   */
-  hostsOnlineLabel: function () {
-    var hostsCountMap = App.router.get('mainHostController.hostsCountMap');
-    return Em.I18n.t('admin.stackUpgrade.hostsOnline').format(hostsCountMap.HEALTHY, hostsCountMap.TOTAL);
-  }.property('App.router.mainHostController.hostsCountMap'),
-
-  /**
-   * label that depict current upgrade process state
-   * @type {String}
-   */
-  upgradeStateLabel: function () {
-    switch (App.get('upgradeState')) {
-      case 'INIT':
-        return (this.get('controller.targetVersions.length') > 0) ? Em.I18n.t('admin.stackUpgrade.state.available') : "";
-      case 'QUEUED':
-      case 'PENDING':
-      case 'IN_PROGRESS':
-        return Em.I18n.t('admin.stackUpgrade.state.inProgress');
-      case 'TIMED_OUT':
-      case 'FAILED':
-      case 'HOLDING_FAILED':
-      case 'HOLDING_TIMED_OUT':
-      case 'HOLDING':
-        return Em.I18n.t('admin.stackUpgrade.state.paused');
-      case 'COMPLETED':
-        return Em.I18n.t('admin.stackUpgrade.state.completed');
-      default:
-        return "";
-    }
-  }.property('App.upgradeState', 'controller.targetVersions'),
-
-  /**
-   * load ClusterStackVersions data
-   */
-  willInsertElement: function () {
-    var self = this;
-    if (App.get('supports.stackUpgrade')) {
-      self.get('controller').loadVersionsInfo();
-      self.doPolling();
-    }
-  },
-
-  /**
-   * stop polling upgrade state
-   */
-  willDestroyElement: function () {
-    clearTimeout(this.get('updateTimer'));
-  },
-
-  /**
-   * poll Upgrade state
-   */
-  doPolling: function () {
-    var self = this;
-    this.set('updateTimer', setTimeout(function () {
-      //skip call if Upgrade wizard opened
-      if (App.router.get('updateController').get('isWorking')) {
-        self.get('controller').loadUpgradeData(true);
-      }
-      self.doPolling();
-    }, App.bgOperationsUpdateInterval));
-  },
-
-
-  /**
-   * box that display info about current version
-   * @type {Em.View}
-   */
-  sourceVersionView: App.UpgradeVersionBoxView.extend({
-    version: function () {
-      return this.get('controller.currentVersion');
-    }.property('controller.currentVersion'),
-    hostsCount: function () {
-      return this.get('version.host_states.CURRENT.length');
-    }.property('version.host_states.CURRENT.length')
-  }),
-
-  /**
-   * box that display info about target versions
-   * @type {Em.View}
-   */
-  targetVersionView: App.UpgradeVersionBoxView.extend({
-    /**
-     * method of controller called on click of target version button
-     * @type {string}
-     * @default null
-     */
-    method: null,
-
-    /**
-     * label of target version button
-     * @type {string}
-     */
-    label: "",
-    versions: function () {
-      return this.get('controller.targetVersions');
-    }.property('controller.targetVersions'),
-    btnClass: 'btn-success',
-    versionName: function () {
-      if (this.get('versions.length') === 0 && App.get('upgradeState') === 'INIT') return Em.I18n.t('admin.stackUpgrade.state.notAvailable');
-      return this.get('controller.upgradeVersion');
-    }.property('controller.upgradeVersion', 'versions.length', 'App.upgradeState'),
-    showSelect: function () {
-      return this.get('versions.length') > 0 && App.get('upgradeState') === 'INIT';
-    }.property('versions.length', 'App.upgradeState'),
-
-    /**
-     * fix for Ember.Select
-     * if Ember.Select initiated with empty content then after content is populated no option selected
-     */
-    initSelect: function () {
-      if (this.get('versions.length') > 0) this.set('version', this.get('versionsSelectContent')[0]);
-    }.observes('versions.length'),
-    version: null,
-    versionsSelectContent: function () {
-      return this.get('versions').map(function (version) {
-        return {
-          label: version.repository_name,
-          value: version.repository_version
-        }
-      });
-    }.property('versions.length'),
-
-    /**
-     * button properties:
-     * - method of controller which will be called on click <code>method</code>
-     * - label <code>label</code>
-     * @type {Object}
-     */
-    buttonObserver: function () {
-      var method = null,
-        label = "",
-        versions = this.get('versions');
-      switch (App.get('upgradeState')) {
-        case 'INIT':
-          if (this.get('versions.length') > 0) {
-            label = Em.I18n.t('common.upgrade');
-            method = 'runPreUpgradeCheck';
-          }
-          break;
-        case 'QUEUED':
-        case 'PENDING':
-        case 'IN_PROGRESS':
-          label = Em.I18n.t('admin.stackUpgrade.state.upgrading');
-          method = 'openUpgradeDialog';
-          break;
-        case 'TIMED_OUT':
-        case 'FAILED':
-        case 'HOLDING_FAILED':
-        case 'HOLDING_TIMED_OUT':
-        case 'HOLDING':
-          label = Em.I18n.t('admin.stackUpgrade.state.resume');
-          method = 'resumeUpgrade';
-          break;
-        case 'COMPLETED':
-          label = Em.I18n.t('common.finalize');
-          method = 'finalize';
-          break;
-      }
-      this.set('method', method);
-      this.set('label',  label);
-    }.observes('versions.length', 'App.upgradeState')
-  })
+  templateName: require('templates/main/admin/stack_and_upgrade')
 });
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/ambari-web/app/views/main/admin/stack_upgrade/menu_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/stack_upgrade/menu_view.js b/ambari-web/app/views/main/admin/stack_upgrade/menu_view.js
new file mode 100644
index 0000000..cf4b500
--- /dev/null
+++ b/ambari-web/app/views/main/admin/stack_upgrade/menu_view.js
@@ -0,0 +1,61 @@
+/**
+ * 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.MainAdminStackMenuView = Em.CollectionView.extend({
+  tagName: 'ul',
+  classNames: ["nav", "nav-tabs"],
+  defaultRoute: 'services',
+
+  content: [
+    Em.Object.create({
+      name: 'services',
+      label: Em.I18n.t('common.stack'),
+      routing: 'services'
+    }),
+    Em.Object.create({
+      name: 'versions',
+      label: Em.I18n.t('common.versions'),
+      routing: 'versions'
+    })
+  ],
+
+  didInsertElement: function () {
+    this.activateView();
+  },
+
+  activateView: function () {
+    var defaultRoute = App.router.get('currentState.name') || this.get('defaultRoute');
+    $.each(this._childViews, function () {
+      this.set('active', (this.get('content.routing') == defaultRoute) ? "active" : "");
+    });
+  },
+
+  deactivateChildViews: function () {
+    $.each(this._childViews, function () {
+      this.set('active', "");
+    });
+  },
+
+  itemViewClass: Em.View.extend({
+    classNameBindings: ["active"],
+    active: "",
+    template: Ember.Handlebars.compile('<a {{action stackNavigate view.content.routing }} href="#"> {{unbound view.content.label}}</a>')
+  })
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/ambari-web/app/views/main/admin/stack_upgrade/services_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/stack_upgrade/services_view.js b/ambari-web/app/views/main/admin/stack_upgrade/services_view.js
new file mode 100644
index 0000000..0b9bbb0
--- /dev/null
+++ b/ambari-web/app/views/main/admin/stack_upgrade/services_view.js
@@ -0,0 +1,43 @@
+/**
+ * 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.MainAdminStackServicesView = Em.View.extend({
+  templateName: require('templates/main/admin/stack_upgrade/services'),
+
+  /**
+   * @type {Array}
+   */
+  services: function() {
+    return App.StackService.find().map(function(s) {
+      s.set('isInstalled', App.Service.find().someProperty('serviceName', s.get('serviceName')));
+      return s;
+    });
+  }.property('App.router.clusterController.isLoaded'),
+
+  /**
+   * launch Add Service wizard
+   * @param event
+   */
+  goToAddService: function (event) {
+    App.router.get('addServiceController').set('serviceToInstall', event.context);
+    App.get('router').transitionTo('main.serviceAdd');
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/ambari-web/app/views/main/admin/stack_upgrade/upgrade_version_box_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/stack_upgrade/upgrade_version_box_view.js b/ambari-web/app/views/main/admin/stack_upgrade/upgrade_version_box_view.js
index 20ee0fe..49c700c 100644
--- a/ambari-web/app/views/main/admin/stack_upgrade/upgrade_version_box_view.js
+++ b/ambari-web/app/views/main/admin/stack_upgrade/upgrade_version_box_view.js
@@ -18,48 +18,158 @@
 
 
 var App = require('app');
+var stringUtils = require('utils/string_utils');
 
 App.UpgradeVersionBoxView = Em.View.extend({
+  templateName: require('templates/main/admin/stack_upgrade/upgrade_version_box'),
+  classNames: ['span4', 'version-box'],
+
   /**
-   * @type {string}
-   * @default null
+   * map containing version (id, label)
+   * this is used as param for <code>showHosts<code> method
+   * @type {Object}
    */
-  method: null,
+  versionStateMap: {
+    'current': {
+      'id': 'current',
+      'label': Em.I18n.t('admin.stackVersions.hosts.popup.header.current')
+    },
+    'installed': {
+      'id': 'installed',
+      'label': Em.I18n.t('admin.stackVersions.hosts.popup.header.installed')
+    },
+    'not_installed': {
+      'id': 'installing',
+      'label': Em.I18n.t('admin.stackVersions.hosts.popup.header.not_installed')
+    }
+  },
 
   /**
    * @type {object}
    * @default null
    */
-  version: null,
+  content: null,
 
   /**
-   * @type {string}
+   * object that describes how content should be displayed
+   * @type {Em.Object}
    */
-  versionName: function () {
-    if (Em.isNone(this.get('version'))) return "";
-    return this.get('version.repository_name');
-  }.property('version.repository_name'),
+  stateElement: function () {
+    var currentVersion = this.get('controller.currentVersion');
+    var upgradeVersion = this.get('controller.upgradeVersion');
+    var element = Em.Object.create();
+
+    if (this.get('content.status') === 'CURRENT') {
+      element.set('isLabel', true);
+      element.set('text', Em.I18n.t('common.current'));
+      element.set('class', 'label label-success');
+    } else if (['INIT', 'INSTALL_FAILED', 'OUT_OF_SYNC'].contains(this.get('content.status'))) {
+      element.set('isButton', true);
+      element.set('text', Em.I18n.t('admin.stackVersions.version.installNow'));
+      element.set('action', 'installRepoVersion');
+    } else if (this.get('content.status') === 'INSTALLING') {
+      element.set('iconClass', 'icon-cog');
+      element.set('isLink', true);
+      element.set('text', Em.I18n.t('hosts.host.stackVersions.status.installing'));
+      element.set('action', 'showProgressPopup');
+    } else if (this.get('content.status') === 'INSTALLED') {
+      if (this.get('content.displayName') === upgradeVersion) {
+        element.set('isLink', true);
+        element.set('action', 'openUpgradeDialog');
+        if (['HOLDING', 'HOLDING_FAILED'].contains(App.get('upgradeState'))) {
+          element.set('iconClass', 'icon-pause');
+          element.set('text', Em.I18n.t('admin.stackVersions.version.upgrade.pause'));
+        } else {
+          element.set('iconClass', 'icon-cog');
+          element.set('text', Em.I18n.t('admin.stackVersions.version.upgrade.running'));
+        }
+      } else if (stringUtils.compareVersions(this.get('content.repositoryVersion'), currentVersion.repository_version) === 1) {
+        element.set('isButton', true);
+        element.set('text', Em.I18n.t('admin.stackVersions.version.performUpgrade'));
+        element.set('action', 'runPreUpgradeCheck');
+      } else {
+        element.set('iconClass', 'icon-ok');
+        element.set('isLink', true);
+        element.set('text', Em.I18n.t('common.installed'));
+      }
+    }
+    return element;
+  }.property('content.status'),
 
   /**
-   * @type {string}
+   * run custom action of controller
+   * @param {object} event
    */
-  btnClass: 'btn-default',
+  runAction: function (event) {
+    var stateElement = event.context;
+    if (stateElement.get('action')) {
+      this.get('controller')[stateElement.get('action')](this.get('content'));
+    }
+  },
 
   /**
-   * @type {number}
+   * show popup with repositories to edit
+   * @return {App.ModalPopup}
    */
-  hostsCount: 0,
+  editRepositories: function () {
+    var self = this;
+    var repo = App.RepositoryVersion.find(this.get('content.id'));
+
+    return App.ModalPopup.show({
+      bodyClass: Ember.View.extend({
+        content: repo,
+        templateName: require('templates/main/admin/stack_upgrade/edit_repositories'),
+        skipValidation: false
+      }),
+      header: Em.I18n.t('common.repositories'),
+      primary: Em.I18n.t('common.save'),
+      disablePrimary: !(App.get('isAdmin') && !App.get('isOperator')),
+      onPrimary: function () {
+        this.hide();
+        self.get('controller').saveRepoOS();
+      }
+    });
+  },
 
   /**
-   * run action by name of method
+   * shows popup with listed hosts wich has current state of hostStackVersion
    * @param {object} event
-   * @return {boolean}
+   * @returns {App.ModalPopup}
+   * @method showHostsListPopup
    */
-  runAction: function (event) {
-    if (typeof this.get('controller')[this.get('method')] === 'function') {
-      this.get('controller')[this.get('method')](this.get('version'));
-      return true;
+  showHosts: function (event) {
+    var status = event.contexts[0];
+    var version = event.contexts[1];
+    var hosts = event.contexts[2];
+    var self = this;
+    if (hosts.length) {
+      return App.ModalPopup.show({
+        bodyClass: Ember.View.extend({
+          title: Em.I18n.t('admin.stackVersions.hosts.popup.title').format(version, status.label, 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.label),
+        primary: Em.I18n.t('admin.stackVersions.hosts.popup.primary'),
+        secondary: Em.I18n.t('common.close'),
+        onPrimary: function () {
+          this.hide();
+          self.filterHostsByStack(version, status.id);
+        }
+      });
     }
-    return false;
+  },
+
+  /**
+   * 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');
   }
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/ambari-web/app/views/main/admin/stack_upgrade/versions_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/stack_upgrade/versions_view.js b/ambari-web/app/views/main/admin/stack_upgrade/versions_view.js
new file mode 100644
index 0000000..b59a95f
--- /dev/null
+++ b/ambari-web/app/views/main/admin/stack_upgrade/versions_view.js
@@ -0,0 +1,168 @@
+/**
+ * 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');
+var stringUtils = require('utils/string_utils');
+
+App.MainAdminStackVersionsView = Em.View.extend({
+  templateName: require('templates/main/admin/stack_upgrade/versions'),
+
+  /**
+   * update timer
+   * @type {number|null}
+   * @default null
+   */
+  updateTimer: null,
+
+  /**
+   * @type {Array}
+   */
+  filterContent: [
+    {
+      label: Em.I18n.t('common.all'),
+      value: ''
+    },
+    {
+      label: Em.I18n.t('admin.stackVersions.filter.notInstalled'),
+      value: 'NOT_INSTALLED'
+    },
+    {
+      label: Em.I18n.t('common.installed'),
+      value: 'INSTALLED'
+    },
+    {
+      label: Em.I18n.t('admin.stackVersions.filter.upgradeReady'),
+      value: 'UPGRADE_READY'
+    },
+    {
+      label: Em.I18n.t('common.current'),
+      value: 'CURRENT'
+    }
+  ],
+
+  /**
+   * @type {object}
+   * @default null
+   */
+  filterSelected: null,
+
+  /**
+   * @type {Ember.Select}
+   * @class
+   */
+  filterView: Ember.Select.extend({
+    selectionBinding: 'parentView.filterSelected',
+    contentBinding: 'parentView.filterContent',
+    optionValuePath: "content.value",
+    optionLabelPath: "content.label"
+  }),
+
+  /**
+   * @type {Em.Array}
+   */
+  repoVersions: App.RepositoryVersion.find(),
+
+  /**
+   * @type {Em.Array}
+   */
+  stackVersions: App.StackVersion.find(),
+
+  /**
+   * @type {Array}
+   */
+  filteredVersions: function () {
+    var filter = this.get('filterSelected');
+    var currentVersion = this.get('controller.currentVersion');
+    var versions = this.get('repoVersions').map(function (version) {
+      var versionFormatted = Em.Object.create({
+        id: version.get('id'),
+        displayName: version.get('displayName'),
+        repositoryVersion: version.get('repositoryVersion'),
+        stackVersionType: version.get('stackVersionType'),
+        stackVersionNumber: version.get('stackVersionNumber'),
+        status: 'INIT',
+        notInstalledHosts: [],
+        installedHosts: [],
+        currentHosts: []
+      });
+      if (version.get('stackVersion')) {
+        versionFormatted.set('status', version.get('stackVersion.state'));
+        versionFormatted.set('notInstalledHosts', version.get('stackVersion.notInstalledHosts'));
+        versionFormatted.set('installedHosts', version.get('stackVersion.installedHosts'));
+        versionFormatted.set('currentHosts', version.get('stackVersion.currentHosts'));
+      }
+      return versionFormatted;
+    });
+
+    versions.sort(function (a, b) {
+      return stringUtils.compareVersions(a.get('repositoryVersion'), b.get('repositoryVersion'));
+    });
+
+    if (filter && filter.value) {
+      return versions.filter(function (version) {
+        if (version.get('status') === 'INSTALLED' && filter.value === 'UPGRADE_READY') {
+          return stringUtils.compareVersions(version.get('repositoryVersion'), currentVersion.repository_version) === 1;
+        } else if (filter.value === 'NOT_INSTALLED') {
+          return ['INIT', 'INSTALL_FAILED', 'INSTALLING', 'OUT_OF_SYNC'].contains(version.get('status'));
+        } else {
+          return version.get('status') === filter.value;
+        }
+      }, this);
+    }
+    return versions;
+  }.property('filterSelected', 'repoVersions.length', 'stackVersions.@each.state'),
+
+  /**
+   * route to versions in Admin View
+   */
+  goToVersions: function () {
+    window.location.replace('/views/ADMIN_VIEW/1.0.0/INSTANCE/#/stackVersions');
+  },
+
+  /**
+   * load ClusterStackVersions data
+   */
+  willInsertElement: function () {
+    this.doPolling();
+  },
+
+  /**
+   * stop polling upgrade state
+   */
+  willDestroyElement: function () {
+    clearTimeout(this.get('updateTimer'));
+  },
+
+  /**
+   * poll Upgrade state
+   */
+  doPolling: function () {
+    var self = this;
+    this.set('updateTimer', setTimeout(function () {
+      //skip call if Upgrade wizard opened
+      if (App.router.get('updateController').get('isWorking')) {
+        self.get('controller').load().done(function () {
+          self.set('controller.isLoaded', true);
+          self.doPolling();
+        });
+      }
+    }, App.bgOperationsUpdateInterval));
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/c59df55e/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
deleted file mode 100644
index 1f65b3c..0000000
--- a/ambari-web/app/views/main/admin/stack_versions/menu.js
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * 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.StackVersionMenuView = Em.CollectionView.extend({
-  tagName: 'ul',
-  classNames: ["nav", "nav-tabs"],
-  content:function(){
-    var menuItems = [
-      { label: Em.I18n.t('common.installed'), routing:'versions', url:"versions", active:"active"},
-      { label: Em.I18n.t('admin.stackVersions.updateTab.title.not.available'), routing:'updates', url:"versions/updates"}
-    ];
-    return menuItems;
-  }.property(),
-
-  init: function(){ this._super(); this.activateView(); },
-
-  activateView:function () {
-    var self = this;
-    self.changeNewRepoCount();
-    $.each(this._childViews, function () {
-      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', 'controller.dataIsLoaded'),
-
-  deactivateChildViews: function() {
-    $.each(this._childViews, function(){
-      this.set('active', "");
-    });
-  },
-
-  /**
-   * 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: "",
-    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/c59df55e/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
deleted file mode 100644
index ce47057..0000000
--- a/ambari-web/app/views/main/admin/stack_versions/operating_systems.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/** 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.OperatingSystemsView = Em.View.extend({
-
-  templateName: require('templates/main/admin/stack_versions/os_for_repo_versions'),
-
-  didInsertElement: function () {
-    this.set('isOsCollapsed', true);
-  },
-
-  toggleOs: function() {
-    if (this.get('hasMoreOs')) {
-      this.set('isOsCollapsed', !this.get('isOsCollapsed'));
-      this.$('.operating-systems').toggle();
-    }
-  },
-
-  hasMoreOs: function() {
-    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").toCapital();
-        break;
-      case 1:
-        return this.get('content.operatingSystems').getEach('osType');
-        break;
-      default :
-        return this.get('content.operatingSystems.length') + " " + Em.I18n.t("common.oss");
-    }
-  }.property('content.operatingSystems.length'),
-
-  labels: function() {
-    return this.get('content.operatingSystems') &&
-      this.get('content.operatingSystems').getEach('osType').join("<br/>");
-  }.property('content.operatingSystems.length')
-});
\ No newline at end of file