ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jai...@apache.org
Subject [1/3] ambari git commit: AMBARI-16940. VDF: support for selecting enabled + default Stacks. (Oleg, Joe, Andrii and Jaimin)
Date Sat, 28 May 2016 00:33:59 GMT
Repository: ambari
Updated Branches:
  refs/heads/trunk c5526333d -> 03600fa75


http://git-wip-us.apache.org/repos/asf/ambari/blob/03600fa7/ambari-web/app/templates/wizard/step1.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/wizard/step1.hbs b/ambari-web/app/templates/wizard/step1.hbs
index 56c62a2..e076d66 100644
--- a/ambari-web/app/templates/wizard/step1.hbs
+++ b/ambari-web/app/templates/wizard/step1.hbs
@@ -19,188 +19,200 @@
   <h2>{{t installer.step1.header}}</h2>
   <p class="alert alert-info">{{t installer.step1.body}}</p>
 
-  <label class="radio big-radio">{{view view.usePublicRepoRadioButton}} {{t installer.step1.selectUseRepoOptions.public}}
-      {{#unless view.selectedPublicRepoVersion}}
-          <a id="public-disabled-link" {{action "openPublicOptionDisabledWindow" target="view"}}>{{t installer.step1.selectUseRepoOptions.public.networkLost}}</a>
-      {{/unless}}
-  </label>
-
-    <form {{bindAttr class="optionsToSelect.useLocalRepo.isSelected:disabled :stack-version-selection :row-fluid"}}>
-      <div class="span3 select-version-label">
-        {{t installer.step1.selectUseRepoOptions.public.select}}
-      </div>
-      <div class="span7 right-stack-info">
-        {{#if view.selectedPublicRepoVersion}}
-          <div class="repo-list-button btn-group">
-            <button type="button" {{bindAttr class="optionsToSelect.useLocalRepo.isSelected:disabled :btn :btn-primary :dropdown-toggle"}} data-toggle="dropdown">
-              {{view.selectedPublicRepoVersion.displayName}} &nbsp;<span class="caret"></span>
-            </button>
-            <ul class="dropdown-menu available-repos-dropdown">
-              {{#if view.availableStackRepoList}}
-                {{#each repo in view.availableStackRepoList}}
-                  {{#if repo.repositoryVersion}}
-                    <li><a {{action "selectRepoInList" repo target="view"}}>{{repo.displayName}}</a></li>
-                  {{/if}}
-                {{/each}}
-              {{else}}
-                <li><a class="disabled">{{t installer.step1.usePublicRepo.ReposList.empty}}</a></li>
-              {{/if}}
-            </ul>
-          </div>
-        {{else}}
-          <button type="button" class="disabled btn btn-primary dropdown-toggle"}} data-toggle="dropdown">
-            {{t installer.step1.selectUseRepoOptions.public.networkLost.button}}
-          </button>
-        {{/if}}
-      </div>
-    </form>
-
-    {{!--Local repo loaded info below--}}
-  <label class="radio big-radio">{{view view.useLocalRepoRadioButton}} {{t installer.step1.selectUseRepoOptions.local}}</label>
-
-    <div id="upload-definition-file-panel" {{bindAttr class="optionsToSelect.usePublicRepo.isSelected:disabled"}}>
-      <div class="clearfix register-version-options row-fluid">
-        <div class="span5 option-radio-button">
-          <label class="local-option-label radio">
-            {{view view.uploadFileRadioButton}} {{t installer.step1.useLocalRepo.uploadFile}}
-          </label>
-        </div>
-        <div class="span7">
-          {{#if view.isFileApi}}
-            {{view App.VersionDefinitionFileUploader disabledBinding="view.fileBrowserDisabled"}}
-          {{/if}}
-        </div>
-      </div>
-      <div class="clearfix register-version-options row-fluid">
-        <div class="span5 option-radio-button">
-          <label class="local-option-label radio">
-            {{view view.enterUrlRadioButton}} {{t installer.step1.useLocalRepo.enterUrl}}
-          </label>
-        </div>
-        <div class="span7 vdf-url">
-          <div {{bindAttr class="optionsToSelect.useLocalRepo.enterUrl.name optionsToSelect.useLocalRepo.enterUrl.url.hasError:has-error }"}}>
-            {{view Ember.TextField valueBinding="optionsToSelect.useLocalRepo.enterUrl.url" placeholderBinding="optionsToSelect.useLocalRepo.enterUrl.placeholder" disabledBinding="view.enterUrlFieldDisabled"}}
-          </div>
-        </div>
-        <div class="span12 read-info-button">
-          <button {{bindAttr class="view.readInfoButtonDisabled:disabled :btn :btn-primary :pull-right"}}
-            {{action "readVersionInfo" target="controller"}}> {{t installer.step1.useLocalRepo.readButton}}</button>
-        </div>
-      </div>
+  {{! left tabs }}
+  <div class="row-fluid">
+    <div class="span2">
+      <ul class="nav nav-tabs tabs-left">
+        {{#each stack in availableStackTypes}}
+          <li {{bindAttr class="stack.isSelected:active"}}><a {{action "selectRepoInList" stack target="controller"}} href="#">{{stack.stackName}}</a></li>
+        {{/each}}
+      </ul>
     </div>
 
-    <form id="repoVersionInfoForm" class="form-horizontal" role="form" name="localVersionInfoForm" novalidate>
-      <div class="accordion-group details-panel">
-        <div class="accordion-heading">
-          <p>{{t installer.step1.useLocalRepo.infoForm.details.title}}</p>
-        </div>
-        <div class="accordion-body">
-          <div class="accordion-inner">
-            <div class="row-fluid">
-              <div class="span5 version-info-section">
-                <div class="row-fluid">
-                  <label class="control-label span5">{{t installer.step1.useLocalRepo.infoForm.details.stackName}}</label>
-                  <div class="version-info span5">{{controller.selectedStack.stackNameVersion}}</div>
-                  {{#if controller.selectedStack.isPatch}}
-                      <div class="span2 patch-icon"><i class="icon-umbrella"></i>&nbsp;{{t common.patch}}</div>
-                  {{/if}}
-                </div>
-                <div class="row-fluid">
-                  <label class="control-label span5">{{t installer.step1.useLocalRepo.infoForm.details.displayName}}</label>
-                  <div class="version-info span7">{{controller.selectedStack.displayName}}</div>
+    <div class="span10">
+      <div class="tab-content">
+        <div class="accordion-group details-panel">
+          <div class="accordion-body">
+            <div class="accordion-inner">
+              <div class="row-fluid">
+                <div class="version-info">
+                  <div class="btn-group">
+                    <button type="button" data-toggle="dropdown" class="btn dropdown-toggle btn-info">{{controller.selectedStack.displayName}} <span class="caret"></span></button>
+                    <ul class="dropdown-menu">
+                      {{#each stack in selectedStackType.visibleStacks}}
+                        <li>
+                          {{!view view.stackRadioButton stackBinding="stack"}}
+                          <a href="#" {{action "changeVersion" stack target="controller"}}>{{stack.displayName}}
+                            {{#if stack.stackDefault}}
+                              ({{t installer.step1.changeVersion.defaultVersion}})
+                            {{/if}}
+                          </a>
+                        </li>
+                      {{/each}}
+                      <li><a href="#" {{action "uploadVdf" target="controller"}}>{{t installer.step1.addVersion}} ...</a></li>
+                    </ul>
+                  </div>
                 </div>
-                <div class="row-fluid">
-                  <label class="control-label span5">{{t installer.step1.useLocalRepo.infoForm.details.version}}</label>
-                  <div class="version-info span7">{{controller.selectedStack.repositoryVersion}}</div>
+                <div class="version-contents-section">
+                  {{#unless servicesForSelectedStack}}
+                    <div class="alert alert-info" role="alert">{{t installer.step1.useLocalRepo.infoForm.content.empty}}</div>
+                  {{/unless}}
+                  <table class="table table-striped table-condensed">
+                  {{#each service in servicesForSelectedStack}}
+                    <tr>
+                      <td class="span4">{{service.displayName}}</td>
+                      <td class="span8">{{service.latestVersion}}</td>
+                    </tr>
+                  {{/each}}
+                  </table>
                 </div>
               </div>
-              <div class="span6 version-contents-section">
-                {{#unless view.selectedServices}}
-                  <div class="alert alert-info" role="alert">{{t installer.step1.useLocalRepo.infoForm.content.empty}}</div>
-                {{/unless}}
-                {{#each service in view.selectedServices}}
-                  <div class="clearfix row-fluid">
-                      <div class="version-info span10">{{service.displayName}} ({{service.version}})</div>
-                  </div>
-                {{/each}}
-              </div>
             </div>
           </div>
         </div>
       </div>
-      <div class="accordion-group repos-panel">
-        <div class="accordion-heading">
-          <p>{{t common.repositories}}</p>
-        </div>
-          <div class="accordion-body version-contents-body">
-            <div class="accordion-inner">
-              <div class="alert alert-info" role="alert">{{t installer.step1.useLocalRepo.infoForm.alert.baseUrl}}</div>
-              {{#if view.hasValidationErrors}}
-                <div class="alert alert-warning" role="alert">{{t installer.step1.useLocalRepo.infoForm.alert.warning}}</div>
-              {{/if}}
+    </div>
+  </div>
+  {{! left tabs end }}
 
-              <div class="clearfix repo-table-title row-fluid">
-                <div class="span2"><label>{{t common.os}}</label></div>
-                <div class="span2"><label>{{t common.name}}</label></div>
-                <div class="span7"><label>{{t installer.step1.advancedRepo.localRepo.column.baseUrl}}</label></div>
-              </div>
+  {{! Public Repository radio }}
+  <label class="radio big-radio">
+    {{view view.usePublicRepoRadioButton}} {{t installer.step1.selectUseRepoOptions.public}}
+    {{#if networkIssuesExist}}
+      <a id="public-disabled-link" {{action "openPublicOptionDisabledWindow" target="view"}}>{{t installer.step1.selectUseRepoOptions.public.networkLost}}</a>
+    {{/if}}
+  </label>
+  {{! Public Repository radio END }}
 
-              {{#each operatingSystem in view.operatingSystems}}
-                {{#if operatingSystem.isSelected}}
-                  <div class="clearfix row-fluid border-bottom">
-                    <div class="span2 os-type-label">
-                      <label>{{operatingSystem.osType}}</label>
-                    </div>
-                    <div class="span9">
-                      {{#each repository in operatingSystem.repositories}}
-                        <div class="repo-name-url row-fluid" {{bindAttr class="repository.hasError:has-error"}} >
-                          <label class="repo-name-label control-label span3">{{repository.repoId}}</label>
-                          <div class="validation-td span1">
-                            {{#if repository.validation}}
-                                {{view view.popoverView repositoryBinding="repository"}}
-                            {{/if}}
-                          </div>
-                          <div {{bindAttr class=":span8 :repo-url repository.invalidFormatError:textfield-error repository.invalidError:textfield-error"}}>
-                            {{view Ember.TextField valueBinding="repository.baseUrl" disabledBinding="controller.selectedStack.useRedhatSatellite"}}
-                          </div>
-                        </div>
-                      {{/each}}
-                    </div>
-                    <div {{bindAttr class=":span1 :remove-icon controller.selectedStack.useRedhatSatellite:disabled"}} {{action "removeOS" operatingSystem target="controller"}}><i class="icon-minus"></i>{{t common.remove}}</div>
-                  </div>
-                {{/if}}
-              {{/each}}
+  {{!--Local repo loaded info below--}}
+  <label class="radio big-radio">{{view view.useLocalRepoRadioButton}} {{t installer.step1.selectUseRepoOptions.local}}</label>
 
+  {{#if App.router.nextBtnClickInProgress}}
+    {{view App.SpinnerView}}
+  {{else}}
+  <form id="repoVersionInfoForm" class="form-horizontal" role="form" name="localVersionInfoForm" novalidate>
+
+    <div class="accordion-group repos-panel">
+      <div class="accordion-heading">
+        <p>{{t common.repositories}}</p>
+      </div>
+      <div class="accordion-body version-contents-body">
+        <div class="accordion-inner">
+          <div class="alert alert-info" role="alert">{{t installer.step1.useLocalRepo.infoForm.alert.baseUrl}}</div>
+          {{#if view.hasValidationErrors}}
+            <div class="alert alert-warning" role="alert">{{t installer.step1.useLocalRepo.infoForm.alert.warning}}</div>
+          {{/if}}
+
+          {{! OSes and Repositories }}
+          <div class="clearfix repo-table-title row-fluid">
+            <div class="span2"><label>{{t common.os}}</label></div>
+            <div class="span9">
+              <div class="span3"><label>{{t common.name}}</label></div>
+              <div class="span1"></div>
+              <div class="span8"><label>{{t installer.step1.advancedRepo.localRepo.column.baseUrl}}</label></div>
+            </div>
+            <div class="span1">
+              {{! Add OS }}
               <div class="add-os-button btn-group pull-right">
-                <button {{bindAttr class=":btn :dropdown-toggle view.isAddOsButtonDisabled:disabled"}} data-toggle="dropdown">
+                <button
+                  type="button" {{bindAttr data-original-title="view.addOsButtonTooltip"  class=":btn :dropdown-toggle :add-os-button view.isAddOsButtonDisabled:disabled"}}
+                  data-toggle="dropdown">
                   <i class="icon-plus"></i> {{t common.add}} &nbsp;<span class="caret"></span>
                 </button>
                 <ul class="dropdown-menu">
-                  {{#each operatingSystem in view.operatingSystems}}
+                  {{#each operatingSystem in selectedStack.operatingSystems}}
                     {{#unless operatingSystem.isSelected}}
                       <li><a {{action "addOS" operatingSystem target="controller"}}>{{operatingSystem.osType}}</a></li>
                     {{/unless}}
                   {{/each}}
                 </ul>
               </div>
-              <div id="skip-validation" {{bindAttr class="controller.selectedStack.useRedhatSatellite:disabled"}}>
-                <label>{{view Ember.Checkbox checkedBinding="skipValidationChecked" disabledBinding="controller.selectedStack.useRedhatSatellite" class="checkbox"}}{{t installer.step1.advancedRepo.skipValidation.message}}
-                  <i class="icon-question-sign" rel="skip-validation-tooltip"
-                     data-toggle="tooltip" {{translateAttr title="installer.step1.advancedRepo.skipValidation.tooltip"}}></i></label>
-              </div>
-              <div id="use-redhat">
-                <label>{{view Ember.Checkbox classNames="align-checkbox" checkedBinding="controller.selectedStack.useRedhatSatellite"}}{{t installer.step1.advancedRepo.useRedhatSatellite.message}}
-                  <i class="icon-question-sign" rel="use-redhat-tooltip"
-                    data-toggle="tooltip" {{translateAttr title="installer.step1.advancedRepo.useRedhatSatellite.tooltip"}}>
-                  </i>
-                </label>
-              </div>
+              {{! Add OS END}}
             </div>
           </div>
-      </div>
-    </form>
 
+          {{#each operatingSystem in selectedStack.operatingSystems}}
+            {{#if operatingSystem.isSelected}}
+              <div class="clearfix row-fluid border-bottom">
+                <div class="span2 os-type-label">
+                  <label>{{operatingSystem.osType}}</label>
+                </div>
+                <div class="span9 repo-name-url">
+                  {{#each repository in operatingSystem.repositories}}
+                    <div class="clearfix repo-name-url-inner">
+                      <div class="span3">
+                        <label class="repo-name-label control-label">{{repository.repoId}}</label>
+                      </div>
+                      <div class="validation-td span1">
+                        {{#if repository.validation}}
+                          {{view view.popoverView repositoryBinding="repository"}}
+                        {{/if}}
+                      </div>
+                      <div {{bindAttr class=":span8 :repo-url repository.invalidFormatError:textfield-error repository.invalidError:textfield-error"}}>
+                        {{view Ember.TextField placeholderBinding="repository.placeholder" valueBinding="repository.baseUrl" disabledBinding="controller.selectedStack.useRedhatSatellite"}}
+                          {{#if controller.selectedStack.usePublicRepo}}
+                            {{#if repository.undo}}
+                              <i class="icon-undo" data-toggle="tooltip"
+                                {{action "doRestoreDefaultValue" repository target="controller"}}
+                                {{translateAttr title="common.undo"}}>
+                              </i>
+                            {{/if}}
+                          {{else}}
+                            {{#if repository.notEmpty}}
+                              <i class="icon-undo" data-toggle="tooltip"
+                                {{action "doRestoreToEmpty" repository target="controller"}}
+                                {{translateAttr title="common.undo"}}>
+                              </i>
+                            {{/if}}
+                          {{/if}}
+                      </div>
+                    </div>
+                  {{/each}}
+                </div>
+                <div {{bindAttr class=":span1 :remove-icon controller.selectedStack.useRedhatSatellite:disabled"}} {{action "removeOS" operatingSystem target="controller"}}>
+                  <i class="icon-minus"></i>{{t common.remove}}</div>
+              </div>
+            {{/if}}
+          {{/each}}
+          {{! OSes and Repositories END }}
+
+          {{! Skip Repository Base URL validation }}
+          <div id="skip-validation" {{bindAttr class="controller.selectedStack.useRedhatSatellite:disabled"}}>
+            <label>
+              {{view Ember.Checkbox checkedBinding="skipValidationChecked" disabledBinding="controller.selectedStack.useRedhatSatellite" class="checkbox"}}
+              <span {{bindAttr class="controller.selectedStack.useRedhatSatellite:disabled"}}>{{t installer.step1.advancedRepo.skipValidation.message}}</span>
+              <i class="icon-question-sign" rel="skip-validation-tooltip"
+                 data-toggle="tooltip" {{translateAttr title="installer.step1.advancedRepo.skipValidation.tooltip"}}>
+              </i>
+            </label>
+          </div>
+          {{! Skip Repository Base URL validation END }}
+
+          {{! Use RedHat Satellite/Spacewalk }}
+          <div id="use-redhat">
+            <label>
+              {{view view.redhatCheckBoxView}}
+              <span {{bindAttr class=":redhat-label controller.selectedStack.usePublicRepo:disabled" data-original-title="view.redhatDisabledTooltip"}}>{{t installer.step1.advancedRepo.useRedhatSatellite.message}}</span>
+              <i class="icon-question-sign" rel="use-redhat-tooltip"
+                 data-toggle="tooltip" {{translateAttr title="installer.step1.advancedRepo.useRedhatSatellite.tooltip"}}>
+              </i>
+            </label>
+          </div>
+          {{! Use RedHat Satellite/Spacewalk END }}
+        </div>
+      </div>
+    </div>
+  </form>
+  {{/if}}
+  {{#if view.invalidFormatUrlExist}}
+    <div class="alert">{{t installer.step1.attentionNeeded}}</div>
+  {{/if}}
+  {{#if view.invalidUrlExist}}
+    <div class="alert">
+      {{t installer.step1.invalidURLAttention}}
+      <a href="javascript:void(null)" {{action "retryRepoUrls" target="view"}}>{{t installer.step1.retryRepoUrls}}</a>
+    </div>
+  {{/if}}
   <a class="btn pull-left installer-back-btn" {{action back}}>&larr; {{t common.back}}</a>
   <button class="btn btn-success pull-right" {{bindAttr disabled="view.isSubmitDisabled"}} {{action next}}>{{t common.next}} &rarr;</button>
-
 </div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/03600fa7/ambari-web/app/templates/wizard/step1/public_option_disabled_window_body.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/wizard/step1/public_option_disabled_window_body.hbs b/ambari-web/app/templates/wizard/step1/public_option_disabled_window_body.hbs
new file mode 100644
index 0000000..25cf49f
--- /dev/null
+++ b/ambari-web/app/templates/wizard/step1/public_option_disabled_window_body.hbs
@@ -0,0 +1,25 @@
+{{!
+* 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="public-disabled-message">{{t installer.step1.selectUseRepoOptions.public.networkLost.popup.msg}}</div>
+<ul>
+  <li class="public-disabled-option">{{t installer.step1.selectUseRepoOptions.public.networkLost.popup.msg1}}</li>
+  <li class="public-disabled-option">{{t installer.step1.selectUseRepoOptions.public.networkLost.popup.msg2}}</li>
+  <li class="public-disabled-option">{{t installer.step1.selectUseRepoOptions.public.networkLost.popup.msg3}}</li>
+</ul>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/03600fa7/ambari-web/app/templates/wizard/step1/vdf_upload.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/wizard/step1/vdf_upload.hbs b/ambari-web/app/templates/wizard/step1/vdf_upload.hbs
new file mode 100644
index 0000000..33fe6c8
--- /dev/null
+++ b/ambari-web/app/templates/wizard/step1/vdf_upload.hbs
@@ -0,0 +1,44 @@
+{{!
+* 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="clearfix register-version-options row-fluid">
+  {{#view "view.uploadFileView"}}
+    <div class="span5 option-radio-button">
+      <label class="local-option-label radio">
+        {{view view.uploadFileRadioButton}} {{t installer.step1.useLocalRepo.uploadFile}}
+      </label>
+    </div>
+    <div class="span12">
+      {{#if view.isFileApi}}
+        {{view view.fileInputView}}
+      {{/if}}
+    </div>
+  {{/view}}
+  {{#view "view.enterUrlView"}}
+    <div class="option-radio-button">
+      <label class="local-option-label radio">
+        {{view view.enterUrlRadioButton}} {{t installer.step1.useLocalRepo.enterUrl}}
+      </label>
+    </div>
+    <div class="span12 vdf-url">
+      <div {{bindAttr class="optionsToSelect.useLocalRepo.enterUrl.name optionsToSelect.useLocalRepo.enterUrl.url.hasError:has-error"}}>
+        {{view view.enterUrlField class="input-block-level" valueBinding="optionsToSelect.useLocalRepo.enterUrl.url" placeholderBinding="optionsToSelect.useLocalRepo.enterUrl.placeholder"}}
+      </div>
+    </div>
+  {{/view}}
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/03600fa7/ambari-web/app/utils/array_utils.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/array_utils.js b/ambari-web/app/utils/array_utils.js
index 643ed67..76914c4 100644
--- a/ambari-web/app/utils/array_utils.js
+++ b/ambari-web/app/utils/array_utils.js
@@ -16,6 +16,10 @@
  * limitations under the License.
  */
 
+function _parseId(id) {
+  return id.replace(/[^\d|\.]/g, '').split('.').map(function (i) {return parseInt(i, 10);});
+}
+
 module.exports = {
   /**
    *
@@ -52,5 +56,33 @@ module.exports = {
     });
 
     return intersection;
+  },
+
+  /**
+   * Callback for sorting models with `id`-property equal to something like version number: 'HDP-1.2.3', '4.2.52' etc
+   *
+   * @param {{id: string}} obj1
+   * @param {{id: string}} obj2
+   * @returns {number}
+   */
+  sortByIdAsVersion: function (obj1, obj2) {
+    var id1 = _parseId(Em.get(obj1, 'id'));
+    var id2 = _parseId(Em.get(obj2, 'id'));
+    var lId1 = id1.length;
+    var lId2 = id2.length;
+    var limit = lId1 > lId2 ? lId2 : lId1;
+    for (var i = 0; i < limit; i++) {
+      if (id1[i] > id2[i]) {
+        return 1;
+      }
+      if (id1[i] < id2[i]) {
+        return -1;
+      }
+    }
+    if (lId1 === lId2) {
+      return 0
+    }
+    return lId1 > lId2 ? 1 : -1;
   }
+
 };

http://git-wip-us.apache.org/repos/asf/ambari/blob/03600fa7/ambari-web/app/views/wizard/step1_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/wizard/step1_view.js b/ambari-web/app/views/wizard/step1_view.js
index a7af383..19be3bc 100644
--- a/ambari-web/app/views/wizard/step1_view.js
+++ b/ambari-web/app/views/wizard/step1_view.js
@@ -26,85 +26,39 @@ App.WizardStep1View = Em.View.extend({
   didInsertElement: function () {
     $("[rel=skip-validation-tooltip]").tooltip({ placement: 'right'});
     $("[rel=use-redhat-tooltip]").tooltip({ placement: 'right'});
-    if (this.get('controller.selectedStack') && this.get('controller.selectedStack.showAvailable')) {
+    $('.add-os-button,.redhat-label').tooltip();
+    if (this.get('controller.selectedStack.showAvailable')) {
       // first time load
-      this.set('controller.latestSelectedPublicRepoId',this.get('controller.selectedStack.id'));
+      if (this.get('controller.selectedStack.useRedhatSatellite')) {
+        // restore `use local repo` on page refresh
+        this.get('controller').useLocalRepo();
+      }
     } else {
       var selected = this.get('controller.content.stacks') && this.get('controller.content.stacks').findProperty('showAvailable');
-      if (selected) {
-        // get back from other steps, set default public repo as selected public
-        this.set('controller.latestSelectedPublicRepoId', selected.get('id'));
-      } else {
+      if (!selected) {
         // network disconnection
-        this.set('controller.latestSelectedPublicRepoId', null);
-        this.set('controller.optionsToSelect.useLocalRepo.isSelected', true);
-        this.set('controller.optionsToSelect.usePublicRepo.isSelected', false);
+        Em.trySet(this, 'controller.selectedStack.useLocalRepo', true);
+        Em.trySet(this, 'controller.selectedStack.usePublicRepo', false);
       }
     }
   },
 
-  /**
-   * =========================== Option "Use Public Repository" starts from here ==================
-   */
-
-  /**
-   * The public reo version shown on the dropdown button
-   */
-  selectedPublicRepoVersion: function () {
-    var selectedId = this.get('controller.latestSelectedPublicRepoId');
-    return selectedId ? this.get('controller.content.stacks').findProperty('id', selectedId): null;
-  }.property('controller.latestSelectedPublicRepoId'),
+  willDestroyElement: function () {
+    $("[rel=skip-validation-tooltip]").tooltip('destroy');
+    $("[rel=use-redhat-tooltip]").tooltip('destroy');
+    $('.add-os-button,.redhat-label').tooltip('destroy');
+  },
 
   /**
-   * List of other available stack repos within the same stack name
-   * @type {Em.Object[]}
+   * Show possible reasons why Public Repo is disabled
+   *
+   * @returns {App.ModalPopup}
    */
-  availableStackRepoList: function () {
-    var selectedStack = this.get('controller.selectedStack');
-    var availableStackRepos = this.get('controller.content.stacks').filter(function (item) {
-      return item.get('showAvailable') && item.get('id') != selectedStack.get('id');
-    });
-    return availableStackRepos.toArray().map(function (stack) {
-      return Em.Object.create({
-        id: stack.get('id'),
-        repositoryVersion: stack.get('repositoryVersion'),
-        displayName: stack.get('stackName') + "-" + stack.get('repositoryVersion'),
-        isSelected: false
-      });
-    });
-  }.property('controller.selectedStack'),
-
-  selectRepoInList: function (event) {
-    if (this.get('controller.optionsToSelect.useLocalRepo.isSelected')) return;
-    this.get('controller.content.stacks').setEach('isSelected', false);
-    this.get('controller.content.stacks').findProperty('id', event.context.id).set('isSelected', true);
-    this.set('controller.latestSelectedPublicRepoId',event.context.id);
-  },
-
-  selectedServices: function () {
-    var selectedStack = this.get('controller.selectedStack');
-    return Em.isNone(selectedStack) ? [] : selectedStack.get('stackServices').toArray().filter(function (service) {
-      return !service.get('isHidden');
-    }).map(function (service) {
-      return Em.Object.create({
-        displayName: service.get('displayName'),
-        version: service.get('latestVersion')
-      });
-    });
-  }.property('controller.selectedStack'),
-
   openPublicOptionDisabledWindow: function () {
     return App.ModalPopup.show({
       header: Em.I18n.t('installer.step1.selectUseRepoOptions.public.networkLost.popup.title'),
-      message: Em.I18n.t('installer.step1.selectUseRepoOptions.public.networkLost.popup.msg'),
-      option1: Em.I18n.t('installer.step1.selectUseRepoOptions.public.networkLost.popup.msg1'),
-      option2: Em.I18n.t('installer.step1.selectUseRepoOptions.public.networkLost.popup.msg2'),
-      option3: Em.I18n.t('installer.step1.selectUseRepoOptions.public.networkLost.popup.msg3'),
       bodyClass: Ember.View.extend({
-        template: Em.Handlebars.compile('<div class="public-disabled-message">{{message}}</div>' +
-          '<li class="public-disabled-option">{{option1}}</li>' +
-          '<li class="public-disabled-option">{{option2}}</li>' +
-          '<li class="public-disabled-option">{{option3}}</li>')
+        templateName: require('templates/wizard/step1/public_option_disabled_window_body')
       }),
       secondary: false
     });
@@ -112,9 +66,10 @@ App.WizardStep1View = Em.View.extend({
 
   /**
    * Disable submit button flag
+   *
    * @type {bool}
    */
-  isSubmitDisabled: Em.computed.or('controller.content.isCheckInProgress'),
+  isSubmitDisabled: Em.computed.or('invalidFormatUrlExist', 'isNoOsChecked', 'controller.content.isCheckInProgress'),
 
   /**
    * Onclick handler for recheck repos urls. Used in Advanced Repository Options.
@@ -123,164 +78,107 @@ App.WizardStep1View = Em.View.extend({
     App.router.get('installerController').checkRepoURL(this.get('controller'));
   },
 
-
-  /**
-   * =========================== Option "Use Local Repository" starts from here ==================
-   */
-
   /**
    * Checkbox for use Public repo
+   *
    * @type {Ember.Checkbox}
    */
   usePublicRepoRadioButton: Em.Checkbox.extend({
     tagName: 'input',
     attributeBindings: [ 'type', 'checked' ],
     classNames: [''],
-    checked: Em.computed.alias('controller.optionsToSelect.usePublicRepo.isSelected'),
+    checked: Em.computed.alias('controller.selectedStack.usePublicRepo'),
     type: 'radio',
-    disabled: function() {
-      return !this.get('controller.latestSelectedPublicRepoId');
-    }.property('controller.latestSelectedPublicRepoId'),
+    disabled: Em.computed.alias('controller.networkIssuesExist'),
 
     click: function () {
-      this.set('controller.optionsToSelect.usePublicRepo.isSelected', true);
-      this.set('controller.optionsToSelect.useLocalRepo.isSelected', false);
-      var latestSelectedPublicRepoId = this.get('controller.latestSelectedPublicRepoId');
-      if (latestSelectedPublicRepoId) {
-        this.get('controller.content.stacks').setEach('isSelected', false);
-        this.get('controller.content.stacks').findProperty('id', latestSelectedPublicRepoId).set('isSelected', true);
-      } else {
-        // make the 1st public repo as selected
-        this.get('controller.content.stacks').findProperty('id').set('isSelected', true);
-      }
+      this.get('controller').usePublicRepo();
     }
   }),
 
   /**
    * Checkbox for use Public repo
+   *
    * @type {Ember.Checkbox}
    */
   useLocalRepoRadioButton: Em.Checkbox.extend({
     tagName: 'input',
     attributeBindings: [ 'type', 'checked' ],
     classNames: [''],
-    checked: Em.computed.alias('controller.optionsToSelect.useLocalRepo.isSelected'),
+    checked: Em.computed.alias('controller.selectedStack.useLocalRepo'),
     type: 'radio',
 
     click: function () {
-      this.set('controller.optionsToSelect.useLocalRepo.isSelected', true);
-      this.set('controller.optionsToSelect.usePublicRepo.isSelected', false);
-      var latestSelectedLocalRepoId = this.get('controller.latestSelectedLocalRepoId');
-      if (latestSelectedLocalRepoId) {
-        this.get('controller.content.stacks').setEach('isSelected', false);
-        this.get('controller.content.stacks').findProperty('id', latestSelectedLocalRepoId).set('isSelected', true);
-      }
+      this.get('controller').useLocalRepo();
     }
   }),
 
   /**
-   * Checkbox for Use local Repo > Upload VDF file
-   * @type {Ember.Checkbox}
+   * User already selected all OSes
+   *
+   * @type {boolean}
    */
-  uploadFileRadioButton: Em.Checkbox.extend({
-    tagName: 'input',
-    attributeBindings: [ 'type', 'checked' ],
-    classNames: [''],
-    checked: Em.computed.alias('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected'),
-    type: 'radio',
-    disabled: function () {
-      return this.get("controller.optionsToSelect.usePublicRepo.isSelected");
-    }.property("controller.optionsToSelect.usePublicRepo.isSelected"),
-
-    click: function () {
-      this.set('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected', true);
-      this.set('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected', false);
-      this.set('controller.optionsToSelect.useLocalRepo.enterUrl.hasError', false);
-      this.set('controller.optionsToSelect.useLocalRepo.uploadFile.hasError', false);
-    }
-  }),
+  allOsesSelected: Em.computed.everyBy('controller.selectedStack.operatingSystems', 'isSelected', true),
 
   /**
-   * Checkbox for Use local Repo > Enter Url of VDF file
-   * @type {Ember.Checkbox}
+   * Disallow adding OS if all OSes are already added or user select <code>useRedhatSatellite</code>
+   *
+   * @type {boolean}
    */
-  enterUrlRadioButton: Em.Checkbox.extend({
-    tagName: 'input',
-    attributeBindings: [ 'type', 'checked' ],
-    classNames: [''],
-    checked: Em.computed.alias('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected'),
-    type: 'radio',
-    disabled: function () {
-      return this.get("controller.optionsToSelect.usePublicRepo.isSelected");
-    }.property("controller.optionsToSelect.usePublicRepo.isSelected"),
+  isAddOsButtonDisabled: Em.computed.or('allOsesSelected', 'controller.selectedStack.useRedhatSatellite'),
 
-    click: function () {
-      this.set('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected', true);
-      this.set('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected', false);
-      this.set('controller.optionsToSelect.useLocalRepo.enterUrl.hasError', false);
-      this.set('controller.optionsToSelect.useLocalRepo.uploadFile.hasError', false);
-    }
-  }),
-
- /*
-  * Is File API available
-  * @type {bool}
-  */
-  isFileApi: function () {
-    return window.File && window.FileReader && window.FileList;
-  }.property(),
-
-  fileBrowserDisabled: function () {
-    return this.get("controller.optionsToSelect.usePublicRepo.isSelected") || this.get("controller.optionsToSelect.useLocalRepo.enterUrl.isSelected");
-  }.property("controller.optionsToSelect.usePublicRepo.isSelected", "controller.optionsToSelect.useLocalRepo.enterUrl.isSelected"),
-  enterUrlFieldDisabled: function () {
-    return this.get("controller.optionsToSelect.usePublicRepo.isSelected") || this.get("controller.optionsToSelect.useLocalRepo.uploadFile.isSelected");
-  }.property("controller.optionsToSelect.usePublicRepo.isSelected", "controller.optionsToSelect.useLocalRepo.uploadFile.isSelected"),
-  readInfoButtonDisabled: function () {
-    if (this.get('controller.optionsToSelect.useLocalRepo.isSelected')) {
-      if(this.get('controller.optionsToSelect.useLocalRepo.uploadFile.isSelected')) {
-        return !this.get('controller.optionsToSelect.useLocalRepo.uploadFile.file');
-      } else if (this.get('controller.optionsToSelect.useLocalRepo.enterUrl.isSelected')) {
-        return !this.get('controller.optionsToSelect.useLocalRepo.enterUrl.url');
-      }
-    } else {
-      return true;
-    }
-  }.property('controller.optionsToSelect.useLocalRepo.isSelected', 'controller.optionsToSelect.useLocalRepo.uploadFile.isSelected',
-    'controller.optionsToSelect.useLocalRepo.uploadFile.file', 'controller.optionsToSelect.useLocalRepo.enterUrl.url'),
-
-  operatingSystems: function () {
-    var selectedStack = this.get('controller.selectedStack');
-    return Em.isNone(selectedStack) ? [] : selectedStack.get('operatingSystems');
-  }.property('controller.selectedStack'),
-
-  isAddOsButtonDisabled: function () {
-    return this.get('operatingSystems').get('length') == this.get('operatingSystems').filterProperty('isSelected').get('length') || this.get('controller.selectedStack.useRedhatSatellite') === true;
-  }.property('operatingSystems', 'operatingSystems.@each.isSelected', 'controller.selectedStack.useRedhatSatellite'),
+  /**
+   * Tooltip for Add OS Button
+   * Empty if this button is enabled
+   *
+   * @type {string}
+   */
+  addOsButtonTooltip: Em.computed.ifThenElse('allOsesSelected', Em.I18n.t('installer.step1.addOs.disabled.tooltip'), ''),
 
   /**
+   * Tooltip for useRedhatSatellite block
+   * Empty if usage Redhat is enabled
+   *
+   * @type {string}
+   */
+  redhatDisabledTooltip: Em.computed.ifThenElse('controller.selectedStack.usePublicRepo', Em.I18n.t('installer.step1.advancedRepo.useRedhatSatellite.disabled.tooltip'), ''),
+  /**
    * List of all repositories under selected stack operatingSystems
+   *
+   * @type {App.Repository[]}
    */
   allRepositories: function () {
-    var selectedStack = this.get('controller.selectedStack');
-    return Em.isNone(selectedStack) ? [] : selectedStack.get('repositories');
-  }.property('controller.selectedStack'),
+    return this.getWithDefault('controller.selectedStack.repositories', []);
+  }.property('controller.selectedStack.repositories.[]'),
 
   /**
    * Verify if some repo has invalid base-url
+   * Ignore if <code>useRedhatSatellite</code> is true for selected stack
+   *
    * @type {bool}
    */
-  invalidFormatUrlExist: Em.computed.someBy('allRepositories', 'invalidFormatError', true),
+  invalidFormatUrlExist: function () {
+    if (this.get('controller.selectedStack.useRedhatSatellite')) {
+      return false;
+    }
+    var allRepositories = this.get('allRepositories');
+    if (!allRepositories) {
+      return false;
+    }
+    return allRepositories.someProperty('invalidFormatError', true);
+  }.property('controller.selectedStack.useRedhatSatellite', 'allRepositories.@each.invalidFormatError'),
+
   /**
    * Verify if some invalid repo-urls exist
    * @type {bool}
    */
-  invalidUrlExist: Em.computed.someBy('allRepositories', 'validation', App.Repository.validation['INVALID']),
+  invalidUrlExist: Em.computed.someBy('allRepositories', 'validation', App.Repository.validation.INVALID),
+
   /**
    * If all repo links are unchecked
    * @type {bool}
    */
-  isNoOsChecked: Em.computed.everyBy('operatingSystems', 'isSelected', false),
+  isNoOsChecked: Em.computed.everyBy('controller.selectedStack.operatingSystems', 'isSelected', false),
 
   popoverView: Em.View.extend({
     tagName: 'i',
@@ -292,43 +190,46 @@ App.WizardStep1View = Em.View.extend({
   }),
 
   /**
+   * @type {Em.Checkbox}
+   */
+  redhatCheckBoxView: Em.Checkbox.extend({
+    attributeBindings: [ 'type', 'checked' ],
+    checkedBinding: 'controller.selectedStack.useRedhatSatellite',
+    classNames: ['checkbox'],
+    disabledBinding: 'controller.selectedStack.usePublicRepo',
+    click: function () {
+      // click triggered before value is toggled, so if-statement is inverted
+      if (!this.get('controller.selectedStack.useRedhatSatellite')) {
+        App.ModalPopup.show({
+          header: Em.I18n.t('common.important'),
+          secondary: false,
+          bodyClass: Ember.View.extend({
+            template: Ember.Handlebars.compile(Em.I18n.t('installer.step1.advancedRepo.useRedhatSatellite.warning'))
+          })
+        });
+      }
+    }
+  }),
+
+  /**
    * Handler when editing any repo BaseUrl
+   *
    * @method editLocalRepository
    */
   editLocalRepository: function () {
     //upload to content
     var repositories = this.get('allRepositories');
+    if (!repositories) {
+      return;
+    }
     repositories.forEach(function (repository) {
-      if (repository.get('lastBaseUrl') != repository.get('baseUrl')) {
+      if (repository.get('lastBaseUrl') !== repository.get('baseUrl')) {
         repository.setProperties({
           lastBaseUrl: repository.get('baseUrl'),
-          validation: App.Repository.validation['PENDING']
+          validation: App.Repository.validation.PENDING
         });
       }
     }, this);
   }.observes('allRepositories.@each.baseUrl')
 
-});
-
-
-App.VersionDefinitionFileUploader = Em.View.extend({
-  template: Em.Handlebars.compile('<input type="file" {{bindAttr disabled="view.disabled"}} />'),
-
-  classNames: ['vdf-input-indentation'],
-
-  change: function (e) {
-    var self = this;
-    if (e.target.files && e.target.files.length == 1) {
-      var file = e.target.files[0];
-      var reader = new FileReader();
-
-      reader.onload = (function () {
-        return function (e) {
-          self.get("controller").setVDFFile(e.target.result);
-        };
-      })(file);
-      reader.readAsText(file);
-    }
-  }
-
 });
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/03600fa7/ambari-web/karma.conf.js
----------------------------------------------------------------------
diff --git a/ambari-web/karma.conf.js b/ambari-web/karma.conf.js
index 1a03381..b11cf76 100644
--- a/ambari-web/karma.conf.js
+++ b/ambari-web/karma.conf.js
@@ -78,6 +78,8 @@ module.exports = function(config) {
       'vendor/scripts/jquery.flexibleArea.js',
       'vendor/scripts/FileSaver.js',
       'vendor/scripts/Blob.js',
+      'vendor/scripts/moment.js',
+      'vendor/scripts/moment-timezone-with-data-2010-2020.js',
       'vendor/**/*.js',
       'app/templates/**/*.hbs',
       'app!(assets)/**/!(karma_setup|tests).js',
@@ -108,7 +110,7 @@ module.exports = function(config) {
     },
 
     preprocessors: {
-//      '!(vendor|node_modules|test)/**/!(karma_setup|tests).js': 'coverage',
+      '!(vendor|node_modules|test)/**/!(karma_setup|tests).js': 'coverage',
       'app/templates/**/*.hbs': ['ember-precompiler-brunch', 'common-require'],
       'app!(assets)/**/!(karma_setup|tests).js': ['common-require'],
       'test/**/*.js': ['common-require']
@@ -123,7 +125,7 @@ module.exports = function(config) {
     // test results reporter to use
     // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
 //    reporters: ['progress', 'coverage'],
-    reporters: ['progress'],
+    reporters: ['progress', 'coverage'],
 
 
     // web server port
@@ -160,6 +162,6 @@ module.exports = function(config) {
 
     // Continuous Integration mode
     // if true, it capture browsers, run tests and exit
-    singleRun: false
+    singleRun: true
   });
 };

http://git-wip-us.apache.org/repos/asf/ambari/blob/03600fa7/ambari-web/test/controllers/installer_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/installer_test.js b/ambari-web/test/controllers/installer_test.js
index 303c8a4..e799467 100644
--- a/ambari-web/test/controllers/installer_test.js
+++ b/ambari-web/test/controllers/installer_test.js
@@ -1210,4 +1210,23 @@ describe('App.InstallerController', function () {
     });
   });
 
+  describe('#postVersionDefinitionFileErrorCallback', function () {
+
+    beforeEach(function () {
+      sinon.stub(App, 'showAlertPopup', Em.K);
+    });
+
+    afterEach(function () {
+      App.showAlertPopup.restore();
+    });
+
+    it('should delete VDF-data', function () {
+      App.db.setLocalRepoVDFData({});
+      expect(App.db.getLocalRepoVDFData()).to.not.be.an.object;
+      installerController.postVersionDefinitionFileErrorCallback({}, {}, {}, {}, {dfd: $.Deferred()});
+      expect(App.db.getLocalRepoVDFData()).to.be.undefined;
+    });
+
+  });
+
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/03600fa7/ambari-web/test/controllers/wizard/step1_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/wizard/step1_test.js b/ambari-web/test/controllers/wizard/step1_test.js
new file mode 100644
index 0000000..01344cb
--- /dev/null
+++ b/ambari-web/test/controllers/wizard/step1_test.js
@@ -0,0 +1,212 @@
+/**
+ * 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 wizardStep1Controller;
+
+var stacks = [
+  App.Stack.createRecord({
+    "id": "HDP-2.4",
+    "stackName": "HDP",
+    "stackVersion": "2.4"
+  }),
+  App.Stack.createRecord({
+    "id": "HDP-2.5-2.5.0.0",
+    "stackName": "HDP",
+    "stackVersion": "2.5"
+  }),
+  App.Stack.createRecord({
+    "id": "HDP-2.5",
+    "stackName": "HDP",
+    "stackVersion": "2.5"
+  }),
+  App.Stack.createRecord({
+    "id": "HDP-2.3.ECS",
+    "stackName": "HDP",
+    "stackVersion": "2.3.ECS"
+  }),
+  App.Stack.createRecord({
+    "id": "HDP-2.3",
+    "stackName": "HDP",
+    "stackVersion": "2.3"
+  }),
+  App.Stack.createRecord({
+    "id": "HDP-2.2",
+    "stackName": "HDP",
+    "stackVersion": "2.2"
+  }),
+  App.Stack.createRecord({
+    "id": "HDP-2.4-2.4.1.1-12345",
+    "stackName": "HDP",
+    "stackVersion": "2.4"
+  })
+];
+
+function getController() {
+  return App.WizardStep1Controller.create({content: Em.Object.create({stacks: stacks})});
+}
+
+describe('App.WizardStep1Controller', function () {
+
+  beforeEach(function() {
+    wizardStep1Controller = getController();
+  });
+
+  App.TestAliases.testAsComputedFindBy(getController(), 'selectedStack', 'content.stacks', 'isSelected', true);
+
+  App.TestAliases.testAsComputedFindBy(getController(), 'selectedStackType', 'availableStackTypes', 'isSelected', true);
+
+  App.TestAliases.testAsComputedFilterBy(getController(), 'servicesForSelectedStack', 'selectedStack.stackServices', 'isHidden', false);
+
+  App.TestAliases.testAsComputedEveryBy(getController(), 'networkIssuesExist', 'content.stacks', 'stackDefault', true);
+
+  describe('#usePublicRepo', function () {
+
+    beforeEach(function () {
+      wizardStep1Controller.get('content.stacks').findProperty('id', 'HDP-2.5-2.5.0.0').setProperties({
+        isSelected: true,
+        useRedhatSatellite: true,
+        usePublicRepo: false,
+        useLocalRepo: true,
+      });
+      wizardStep1Controller.usePublicRepo();
+    });
+
+    it('correct stack is selected', function () {
+      expect(wizardStep1Controller.get('selectedStack.id')).to.be.equal('HDP-2.5-2.5.0.0');
+    });
+
+    it('`useRedhatSatellite` is set `false`', function () {
+      expect(wizardStep1Controller.get('selectedStack.useRedhatSatellite')).to.be.false;
+    });
+
+    it('`usePublicRepo` is set `true`', function () {
+      expect(wizardStep1Controller.get('selectedStack.usePublicRepo')).to.be.true;
+    });
+
+    it('`useLocalRepo` is set `false`', function () {
+      expect(wizardStep1Controller.get('selectedStack.useLocalRepo')).to.be.false;
+    });
+
+  });
+
+  describe('#useLocalRepo', function () {
+
+    beforeEach(function () {
+      wizardStep1Controller.get('content.stacks').findProperty('id', 'HDP-2.5-2.5.0.0').setProperties({
+        isSelected: true,
+        usePublicRepo: true,
+        useLocalRepo: false,
+      });
+      wizardStep1Controller.useLocalRepo();
+    });
+
+    it('correct stack is selected', function () {
+      expect(wizardStep1Controller.get('selectedStack.id')).to.be.equal('HDP-2.5-2.5.0.0');
+    });
+
+    it('`usePublicRepo` is set `false`', function () {
+      expect(wizardStep1Controller.get('selectedStack.usePublicRepo')).to.be.false;
+    });
+
+    it('`useLocalRepo` is set `true`', function () {
+      expect(wizardStep1Controller.get('selectedStack.useLocalRepo')).to.be.true;
+    });
+
+  });
+
+  describe('#selectStackBy', function () {
+
+    it('select by `id`', function () {
+      wizardStep1Controller.selectStackBy('id', 'HDP-2.5-2.5.0.0');
+      expect(wizardStep1Controller.get('selectedStack.id')).to.be.equal('HDP-2.5-2.5.0.0');
+      expect(wizardStep1Controller.get('content.stacks').filterProperty('isSelected')).to.have.property('length').equal(1);
+    });
+
+    it('select by `stackNameVersion`', function () {
+      wizardStep1Controller.selectStackBy('stackNameVersion', 'HDP-2.5');
+      expect(wizardStep1Controller.get('selectedStack.id')).to.be.equal('HDP-2.5-2.5.0.0'); // `HDP-2.5-2.5.0.0`-id is before `HDP-2.5`-id
+      expect(wizardStep1Controller.get('content.stacks').filterProperty('isSelected')).to.have.property('length').equal(1);
+    });
+
+  });
+
+  describe('#availableStackTypes', function () {
+
+    it('stack types are sorted desc', function () {
+      expect(wizardStep1Controller.get('availableStackTypes').mapProperty('stackName')).to.be.eql(['HDP-2.5', 'HDP-2.4', 'HDP-2.3.ECS', 'HDP-2.3', 'HDP-2.2']);
+    });
+
+  });
+
+  describe('#readInfoIsNotProvided', function () {
+
+    Em.A([
+      {
+        options: {
+          uploadFile: {isSelected: false},
+          enterUrl: {isSelected: false}
+        },
+        m: 'url and file are not selected',
+        e: false
+      },
+      {
+        options: {
+          uploadFile: {isSelected: false},
+          enterUrl: {isSelected: true, url: ''}
+        },
+        m: 'url is selected but not provided',
+        e: true
+      },
+      {
+        options: {
+          uploadFile: {isSelected: false},
+          enterUrl: {isSelected: true, url: ' url'}
+        },
+        m: 'url is selected and provided',
+        e: false
+      },
+      {
+        options: {
+          uploadFile: {isSelected: true, file: ''},
+          enterUrl: {isSelected: false}
+        },
+        m: 'file is selected but not provided',
+        e: true
+      },
+      {
+        options: {
+          uploadFile: {isSelected: true, file: 'path'},
+          enterUrl: {isSelected: false}
+        },
+        m: 'file is selected and provided',
+        e: false
+      }
+    ]).forEach(function (test) {
+
+      it(test.m, function () {
+        wizardStep1Controller.set('optionsToSelect.useLocalRepo', test.options);
+        expect(wizardStep1Controller.get('readInfoIsNotProvided')).to.be.equal(test.e);
+      });
+
+    });
+
+  });
+
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/03600fa7/ambari-web/test/mixins/common/configs/config_recommendation_parser_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mixins/common/configs/config_recommendation_parser_test.js b/ambari-web/test/mixins/common/configs/config_recommendation_parser_test.js
index 8572772..1b84509 100644
--- a/ambari-web/test/mixins/common/configs/config_recommendation_parser_test.js
+++ b/ambari-web/test/mixins/common/configs/config_recommendation_parser_test.js
@@ -508,13 +508,13 @@ describe('App.ConfigRecommendationParser', function() {
     it('add new file name', function() {
       instanceObject.set('modifiedFileNames', ['someFile']);
       instanceObject.addModifiedFileName('otherFile');
-      expect(instanceObject.get('modifiedFileNames').join(',')).to.eql('someFile,otherFile');
+      expect(instanceObject.get('modifiedFileNames').join(',')).to.be.equal('someFile,otherFile');
     });
 
     it('do not add file that already in list', function() {
       instanceObject.set('modifiedFileNames', ['someFile']);
       instanceObject.addModifiedFileName('someFile');
-      expect(instanceObject.get('modifiedFileNames').join(',')).to.eql('someFile');
+      expect(instanceObject.get('modifiedFileNames').join(',')).to.be.equal('someFile');
     });
   });
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/03600fa7/ambari-web/test/utils/array_utils_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/utils/array_utils_test.js b/ambari-web/test/utils/array_utils_test.js
index ec7c5d8..110e2b8 100644
--- a/ambari-web/test/utils/array_utils_test.js
+++ b/ambari-web/test/utils/array_utils_test.js
@@ -122,4 +122,47 @@ describe('array_utils', function () {
 
   });
 
+  describe('#sortByIdAsVersion', function () {
+
+    Em.A([
+      {
+        c: [{id: '1.2.4'}, {id: '1.2.5'}, {id: '1.2.3'}],
+        m: 'Items without letters and with same length',
+        e: ['1.2.3', '1.2.4', '1.2.5']
+      },
+      {
+        c: [{id: 'HDP-1.2.4'}, {id: 'HDP-1.2.5'}, {id: 'HDP-1.2.3'}],
+        m: 'Items with letters and with same length',
+        e: ['HDP-1.2.3', 'HDP-1.2.4', 'HDP-1.2.5']
+      },
+      {
+        c: [{id: 'HDP-1.2.4.2'}, {id: 'HDP-1.2.4.1'}, {id: 'HDP-1.2.3'}],
+        m: 'Items with letters and with custom length',
+        e: ['HDP-1.2.3', 'HDP-1.2.4.1', 'HDP-1.2.4.2']
+      },
+      {
+        c: [{id: 'HDP-1.2.4.2.3'}, {id: 'HDP-1.2.4.11.3'}, {id: 'HDP-1.2.3'}],
+        m: 'Items with letters and with double digits',
+        e: ['HDP-1.2.3', 'HDP-1.2.4.2.3', 'HDP-1.2.4.11.3']
+      },
+      {
+        c: [{id: 'HDP-1.2.3.2'}, {id: 'HDP-1.2.4'}, {id: 'HDP-1.2.3'}],
+        m: 'Items with letters and with custom length (2)',
+        e: ['HDP-1.2.3', 'HDP-1.2.3.2', 'HDP-1.2.4']
+      },
+      {
+        c: [{id: 'HDP-1.2.3'}, {id: 'HDP-1.2.4'}, {id: 'HDP-1.2.3'}],
+        m: 'Items with letters and equal ids',
+        e: ['HDP-1.2.3', 'HDP-1.2.3', 'HDP-1.2.4']
+      }
+    ]).forEach(function (test) {
+
+      it(test.m, function () {
+        expect(test.c.sort(arrayUtils.sortByIdAsVersion).mapProperty('id')).to.be.eql(test.e);
+      });
+
+    });
+
+  });
+
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/03600fa7/ambari-web/test/views/common/host_progress_popup_body_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/common/host_progress_popup_body_view_test.js b/ambari-web/test/views/common/host_progress_popup_body_view_test.js
index 282d31c..5343dc9 100644
--- a/ambari-web/test/views/common/host_progress_popup_body_view_test.js
+++ b/ambari-web/test/views/common/host_progress_popup_body_view_test.js
@@ -221,20 +221,35 @@ describe('App.HostProgressPopupBodyView', function () {
       ];
 
       cases.forEach(function(test) {
-        it(test.m, function() {
-          assert.equal(Em.get(view, 'hostInfoLoaded'), true, 'hostInfoLoaded should be true on init');
-          this.HostModelStub.returns(test.hosts);
-          this.isLogSearchInstalled.returns(test.isLogSearchInstalled);
-          this.logSearchSupported.returns(test.logSearchSupported);
-          if (test.requestFailed) {
-            this.updateCtrlStub.returns($.Deferred().reject().promise());
-          } else {
-            this.updateCtrlStub.returns($.Deferred().resolve().promise());
-          }
-          Em.set(view, 'hostInfoLoaded', false);
-          view.preloadHostModel(test.hostName);
-          assert.equal(App.router.get('updateController').updateLogging.called, test.e.updateLoggingCalled, 'updateLogging call validation');
-          assert.equal(Em.get(view, 'hostInfoLoaded'), true, 'in result hostInfoLoaded should be always true');
+        describe(test.m, function() {
+
+          beforeEach(function () {
+            this.HostModelStub.returns(test.hosts);
+            this.isLogSearchInstalled.returns(test.isLogSearchInstalled);
+            this.logSearchSupported.returns(test.logSearchSupported);
+            if (test.requestFailed) {
+              this.updateCtrlStub.returns($.Deferred().reject().promise());
+            } else {
+              this.updateCtrlStub.returns($.Deferred().resolve().promise());
+            }
+          });
+
+          it('hostInfoLoaded should be true on init', function () {
+            expect(Em.get(view, 'hostInfoLoaded')).to.be.true;
+          });
+
+          it('updateLogging call validation', function () {
+            Em.set(view, 'hostInfoLoaded', false);
+            view.preloadHostModel(test.hostName);
+            expect(App.router.get('updateController').updateLogging.called).to.be.equal(test.e.updateLoggingCalled);
+          });
+
+          it('in result hostInfoLoaded should be always true', function () {
+            Em.set(view, 'hostInfoLoaded', false);
+            view.preloadHostModel(test.hostName);
+            expect(Em.get(view, 'hostInfoLoaded')).to.be.true;
+          });
+
         });
       }, this);
     });

http://git-wip-us.apache.org/repos/asf/ambari/blob/03600fa7/ambari-web/test/views/wizard/step1_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/wizard/step1_view_test.js b/ambari-web/test/views/wizard/step1_view_test.js
index 070cb59..f94720a 100644
--- a/ambari-web/test/views/wizard/step1_view_test.js
+++ b/ambari-web/test/views/wizard/step1_view_test.js
@@ -20,7 +20,6 @@ var App = require('app');
 require('views/wizard/step1_view');
 
 var view;
-var controller;
 
 function getView() {
   return App.WizardStep1View.create();
@@ -28,208 +27,16 @@ function getView() {
 
 describe('App.WizardStep1View', function () {
 
-  describe('#operatingSystems', function () {
-    beforeEach(function () {
-      sinon.stub(App.Stack, 'find', function () {
-        return [
-          Ember.Object.create({
-            id: 'HDP-1.3-1234',
-            stackName: 'HDP',
-            stackVersion: '1.3',
-            active: true,
-            operatingSystems: [
-              Ember.Object.create({
-                id: 'HDP-1.3-1234-redhat5',
-                osType: 'redhat5',
-                isSelected: false,
-                repositories: [
-                  Ember.Object.create({
-                    id: 'redhat5-HDP-1.3',
-                    isSelected: false
-                  }),
-                  Ember.Object.create({
-                    id: 'redhat5-HDP-UTILS-1.1.0.19',
-                    isSelected: false
-                  })
-                ]
-              }),
-              Ember.Object.create({
-                id: 'HDP-1.3-1234-redhat6',
-                osType: 'redhat6',
-                isSelected: false,
-                repositories: [
-                  Ember.Object.create({
-                    id: 'redhat6-HDP-1.3',
-                    isSelected: false
-                  }),
-                  Ember.Object.create({
-                    id: 'redhat6-HDP-UTILS-1.1.0.19',
-                    isSelected: false
-                  })
-                ]
-              })
-            ],
-            isSelected: false
-          }),
-          Ember.Object.create({
-            id: 'HDP-2.1',
-            stackName: 'HDP',
-            stackVersion: '2.1',
-            active: true,
-            operatingSystems: [
-              Ember.Object.create({
-                id: 'HDP-2.1-redhat5',
-                osType: 'redhat5',
-                isSelected: true,
-                repositories: [
-                  Ember.Object.create({
-                    id: 'redhat5-HDP-2.1',
-                    isSelected: true,
-                    baseUrl: "http://public-repo-1.hortonworks.com/HDP/centos5/2.x/updates/2.1.5.0",
-                    latestBaseUrl: "http://public-repo-1.hortonworks.com/HDP/centos5/2.x/updates/2.1.5.0"
-                  }),
-                  Ember.Object.create({
-                    id: 'redhat5-HDP-UTILS-1.1.0.19',
-                    isSelected: true,
-                    baseUrl: "http://s3.amazonaws.com/dev.hortonworks.com/HDP-UTILS-1.1.0.19/repos/centos5",
-                    latestBaseUrl: "http://s3.amazonaws.com/dev.hortonworks.com/HDP-UTILS-1.1.0.19/repos/centos5"
-                  })
-                ]
-              }),
-              Ember.Object.create({
-                id: 'HDP-2.1-redhat6',
-                osType: 'redhat6',
-                isSelected: true,
-                repositories: [
-                  Ember.Object.create({
-                    id: 'redhat6-HDP-2.1',
-                    isSelected: true,
-                    baseUrl: "http://public-repo-1.hortonworks.com/HDP/centos6/2.x/updates/2.1.5.0",
-                    latestBaseUrl: "http://public-repo-1.hortonworks.com/HDP/centos6/2.x/updates/2.1.5.0"
-                  }),
-                  Ember.Object.create({
-                    id: 'redhat6-HDP-UTILS-1.1.0.19',
-                    isSelected: true,
-                    baseUrl: "http://s3.amazonaws.com/dev.hortonworks.com/HDP-UTILS-1.1.0.19/repos/centos6",
-                    latestBaseUrl: "http://s3.amazonaws.com/dev.hortonworks.com/HDP-UTILS-1.1.0.19/repos/centos6"
-                  })
-                ]
-              })
-            ],
-            repositories: [
-              Ember.Object.create({
-                id: 'redhat5-HDP-2.1',
-                isSelected: true,
-                baseUrl: "http://public-repo-1.hortonworks.com/HDP/centos5/2.x/updates/2.1.5.0",
-                latestBaseUrl: "http://public-repo-1.hortonworks.com/HDP/centos5/2.x/updates/2.1.5.0"
-              }),
-              Ember.Object.create({
-                id: 'redhat5-HDP-UTILS-1.1.0.19',
-                isSelected: true,
-                baseUrl: "http://s3.amazonaws.com/dev.hortonworks.com/HDP-UTILS-1.1.0.19/repos/centos5",
-                latestBaseUrl: "http://s3.amazonaws.com/dev.hortonworks.com/HDP-UTILS-1.1.0.19/repos/centos5"
-              }),
-              Ember.Object.create({
-                id: 'redhat6-HDP-2.1',
-                isSelected: true,
-                baseUrl: "http://public-repo-1.hortonworks.com/HDP/centos6/2.x/updates/2.1.5.0",
-                latestBaseUrl: "http://public-repo-1.hortonworks.com/HDP/centos6/2.x/updates/2.1.5.0"
-              }),
-              Ember.Object.create({
-                id: 'redhat6-HDP-UTILS-1.1.0.19',
-                isSelected: true,
-                baseUrl: "http://s3.amazonaws.com/dev.hortonworks.com/HDP-UTILS-1.1.0.19/repos/centos6",
-                latestBaseUrl: "http://s3.amazonaws.com/dev.hortonworks.com/HDP-UTILS-1.1.0.19/repos/centos6"
-              })
-            ],
-            isSelected: true
-          })
-        ];
-      });
-    });
-
-    afterEach(function () {
-      App.Stack.find.restore();
-    });
-
-    describe('should create repo groups from repo list', function () {
-
-      var repositories;
-      beforeEach(function () {
-        controller = App.WizardStep1Controller.create({
-          content: {
-            stacks: App.Stack.find()
-          }
-        });
-
-        view = App.WizardStep1View.create({'controller': controller});
-        view.set('$', function () {
-          return Em.Object.create({hide: Em.K, toggle: Em.K});
-        });
-        repositories = view.get('allRepositories');
-      });
-
-      it('operatingSystems.length', function () {
-        expect(view.get('operatingSystems.length')).to.equal(2);
-      });
-
-      it('operatingSystems.0.osType', function () {
-        expect(view.get('operatingSystems')[0].get('osType')).to.equal('redhat5');
-      });
-
-      it('operatingSystems.1.osType', function () {
-        expect(view.get('operatingSystems')[1].get('osType')).to.equal('redhat6');
-      });
-
-      it('operatingSystems.0.isSelected', function () {
-        expect(view.get('operatingSystems')[0].get('isSelected')).to.be.true;
-      });
-
-      it('operatingSystems.1.isSelected', function () {
-        expect(view.get('operatingSystems')[1].get('isSelected')).to.be.true;
-      });
-
-      it('operatingSystems.0.repositories', function () {
-        expect(view.get('operatingSystems')[0].get('repositories')).to.eql([repositories[0], repositories[1]]);
-      });
-
-      it('operatingSystems.1.repositories', function () {
-        expect(view.get('operatingSystems')[1].get('repositories')).to.eql([repositories[2], repositories[3]]);
-      });
-
-    });
-
-  });
-
-  describe('#invalidFormatUrlExist', function () {
-
-    controller = App.WizardStep1Controller.create({
-      content: {
-        stacks: App.Stack.find()
-      }
-    });
-    view = App.WizardStep1View.create();
-    view.reopen({
-      controller: controller
-    });
-    view.set('$', function () {
-      return Em.Object.create({hide: Em.K, toggle: Em.K});
-    });
-
-    it(view.get('allRepositories').mapProperty('invalidFormatError').join(', '), function () {
-      expect(view.get('invalidFormatUrlExist')).to.equal(false);
-    });
+  beforeEach(function () {
+    view = getView();
   });
 
-  App.TestAliases.testAsComputedEveryBy(getView(), 'isNoOsChecked', 'operatingSystems', 'isSelected', false);
+  App.TestAliases.testAsComputedEveryBy(getView(), 'isNoOsChecked', 'controller.selectedStack.operatingSystems', 'isSelected', false);
 
-  App.TestAliases.testAsComputedOr(getView(), 'isSubmitDisabled', ['controller.content.isCheckInProgress']);
+  App.TestAliases.testAsComputedOr(getView(), 'isSubmitDisabled', ['invalidFormatUrlExist', 'isNoOsChecked', 'controller.content.isCheckInProgress']);
 
   App.TestAliases.testAsComputedSomeBy(getView(), 'invalidUrlExist', 'allRepositories', 'validation', App.Repository.validation.INVALID);
 
-  App.TestAliases.testAsComputedSomeBy(getView(), 'invalidFormatUrlExist', 'allRepositories', 'invalidFormatError', true);
-
-
   describe('#editLocalRepository', function () {
 
     it('should update repository', function () {


Mime
View raw message