Repository: ambari Updated Branches: refs/heads/branch-2.0.0 c6e363be6 -> 455a0a804
AMBARI-9871. Need to adjust UI for HDP 2.0/2.1 Stacks with versions (onechiporenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/455a0a80 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/455a0a80 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/455a0a80 Branch: refs/heads/branch-2.0.0 Commit: 455a0a804fa94d0a893b5a619dc162fe6b970534 Parents: c6e363b Author: Oleg Nechiporenko <[email protected]> Authored: Mon Mar 2 18:46:09 2015 +0200 Committer: Oleg Nechiporenko <[email protected]> Committed: Mon Mar 2 18:46:09 2015 +0200 ---------------------------------------------------------------------- .../app/scripts/controllers/NavbarCtrl.js | 10 +- .../ui/admin-web/app/views/leftNavbar.html | 2 +- ambari-web/app/assets/test/tests.js | 2 + ambari-web/app/config.js | 2 + .../controllers/global/cluster_controller.js | 3 + .../main/admin/stack_and_upgrade_controller.js | 57 ++++- ambari-web/app/routes/main.js | 7 +- ambari-web/app/styles/stack_versions.less | 113 ++++++++++ .../main/admin/stack_upgrade/services.hbs | 78 ++++++- ambari-web/app/templates/main/host.hbs | 6 +- .../views/main/admin/stack_upgrade/menu_view.js | 29 +-- .../main/admin/stack_upgrade/services_view.js | 218 +++++++++++++++++++ ambari-web/app/views/main/host/menu.js | 66 +++--- .../main/admin/stack_upgrade/menu_view_test.js | 56 +++++ ambari-web/test/views/main/host/menu_test.js | 71 ++++++ 15 files changed, 666 insertions(+), 54 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/455a0a80/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/NavbarCtrl.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/NavbarCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/NavbarCtrl.js index f44a10f..2f33ae4 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/NavbarCtrl.js +++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/NavbarCtrl.js @@ -18,8 +18,9 @@ 'use strict'; angular.module('ambariAdminConsole') -.controller('NavbarCtrl',['$scope', 'Cluster', '$location', 'Alert', 'ROUTES', 'ConfirmationModal', '$rootScope', function($scope, Cluster, $location, Alert, ROUTES, ConfirmationModal, $rootScope) { +.controller('NavbarCtrl',['$scope', 'Cluster', '$location', 'Alert', 'ROUTES', 'ConfirmationModal', '$rootScope', 'Stack', function($scope, Cluster, $location, Alert, ROUTES, ConfirmationModal, $rootScope, Stack) { $scope.cluster = null; + $scope.totalRepos = 0; $scope.editCluster = { name : '', editingName : false @@ -28,6 +29,13 @@ angular.module('ambariAdminConsole') function loadClusterData() { Cluster.getStatus().then(function (cluster) { $scope.cluster = cluster; + Stack.allRepos({version: '', + cluster: { + options: [], + current: null + }}, {}).then(function (repos) { + $scope.totalRepos = repos.itemTotal; + }); if (cluster && cluster.Clusters.provisioning_state === 'INIT') { setTimeout(loadClusterData, 1000); } http://git-wip-us.apache.org/repos/asf/ambari/blob/455a0a80/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html index c332f80..4795ec8 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html +++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html @@ -69,7 +69,7 @@ <li><p class="noclusters">No clusters</p></li> </ul> </div> - <ul class="nav nav-pills nav-stacked" ng-show="cluster"> + <ul class="nav nav-pills nav-stacked" ng-show="cluster && totalRepos > 0"> <li ng-class="{active: isActive('stackVersions.list')}"> <a href="#/stackVersions">Versions</a> </li> http://git-wip-us.apache.org/repos/asf/ambari/blob/455a0a80/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 ef2e202..f0cbfb5 100644 --- a/ambari-web/app/assets/test/tests.js +++ b/ambari-web/app/assets/test/tests.js @@ -179,6 +179,7 @@ var files = ['test/init_model_test', 'test/views/main/admin/stack_upgrade/upgrade_wizard_view_test', 'test/views/main/admin/stack_upgrade/version_view_test', 'test/views/main/admin/stack_upgrade/services_view_test', + 'test/views/main/admin/stack_upgrade/menu_view_test', 'test/views/main/dashboard/config_history_view_test', 'test/views/main/dashboard/widget_test', 'test/views/main/dashboard/widgets_test', @@ -197,6 +198,7 @@ var files = ['test/init_model_test', 'test/views/main/dashboard/widgets/namenode_cpu_test', 'test/views/main/host/details_test', 'test/views/main/host/summary_test', + 'test/views/main/host/menu_test', 'test/views/main/host/stack_versions_view_test', 'test/views/main/host/details/host_component_view_test', 'test/views/main/host/details/host_component_views/decommissionable_test', http://git-wip-us.apache.org/repos/asf/ambari/blob/455a0a80/ambari-web/app/config.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/config.js b/ambari-web/app/config.js index 235f57f..02bf616 100644 --- a/ambari-web/app/config.js +++ b/ambari-web/app/config.js @@ -56,6 +56,8 @@ App.healthStatusRed = '#ff0000'; App.healthStatusGreen = '#5AB400'; App.healthStatusOrange = '#FF8E00'; +App.stackVersionsAvailable = true; + // experimental features are automatically enabled if running on brunch server App.enableExperimental = false; http://git-wip-us.apache.org/repos/asf/ambari/blob/455a0a80/ambari-web/app/controllers/global/cluster_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/global/cluster_controller.js b/ambari-web/app/controllers/global/cluster_controller.js index 5ca4a0b..ba3db08 100644 --- a/ambari-web/app/controllers/global/cluster_controller.js +++ b/ambari-web/app/controllers/global/cluster_controller.js @@ -325,6 +325,9 @@ App.ClusterController = Em.Controller.extend({ } App.router.get('mainAdminStackAndUpgradeController').initDBProperties(); App.router.get('mainAdminStackAndUpgradeController').loadUpgradeData(true); + App.router.get('mainAdminStackAndUpgradeController').loadStackVersionsToModel(true).done(function () { + App.set('stackVersionsAvailable', App.StackVersion.find().content.length > 0); + }); }, loadRootService: function () { http://git-wip-us.apache.org/repos/asf/ambari/blob/455a0a80/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 5daa092..aad5b46 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 @@ -693,5 +693,60 @@ App.MainAdminStackAndUpgradeController = Em.Controller.extend(App.LocalStorage, var currentVersionObject = App.RepositoryVersion.find().findProperty('status', 'CURRENT'); var versionName = currentVersionObject && currentVersionObject.get('stackVersionType'); App.set('isStormMetricsSupported', versionName != 'HDP' || stringUtils.compareVersions(versionNumber, '2.2.2') > -1 || !versionNumber); - }.observes('currentVersion.repository_version') + }.observes('currentVersion.repository_version'), + + /** + * get the installed repositories of HDP from server + */ + loadRepositories: function () { + if (App.router.get('clusterController.isLoaded')) { + var nameVersionCombo = App.get('currentStackVersion'); + var stackName = nameVersionCombo.split('-')[0]; + var stackVersion = nameVersionCombo.split('-')[1]; + App.ajax.send({ + name: 'cluster.load_repositories', + sender: this, + data: { + stackName: stackName, + stackVersion: stackVersion + }, + success: 'loadRepositoriesSuccessCallback', + error: 'loadRepositoriesErrorCallback' + }); + } + }.observes('App.router.clusterController.isLoaded'), + + loadRepositoriesSuccessCallback: function (data) { + var allRepos = []; + data.items.forEach(function (os) { + os.repositories.forEach(function (repository) { + var osType = repository.Repositories.os_type; + var repo = Em.Object.create({ + baseUrl: repository.Repositories.base_url, + osType: osType, + repoId: repository.Repositories.repo_id, + repoName : repository.Repositories.repo_name, + stackName : repository.Repositories.stack_name, + stackVersion : repository.Repositories.stack_version, + isFirst: false + }); + var group = allRepos.findProperty('name', osType); + if (!group) { + group = { + name: osType, + repositories: [] + }; + repo.set('isFirst', true); + allRepos.push(group); + } + group.repositories.push(repo); + }); + }, this); + allRepos.stackVersion = App.get('currentStackVersionNumber'); + this.set('allRepos', allRepos); + }, + + loadRepositoriesErrorCallback: function (request, ajaxOptions, error) { + console.log('Error message is: ' + request.responseText); + } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/455a0a80/ambari-web/app/routes/main.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/routes/main.js b/ambari-web/app/routes/main.js index 43dbf3c..7ad5dc3 100644 --- a/ambari-web/app/routes/main.js +++ b/ambari-web/app/routes/main.js @@ -240,7 +240,12 @@ module.exports = Em.Route.extend(App.RouterRedirections, { stackVersions: Em.Route.extend({ route: '/stackVersions', connectOutlets: function (router, context) { - router.get('mainHostDetailsController').connectOutlet('mainHostStackVersions'); + if (App.get('stackVersionsAvailable')) { + router.get('mainHostDetailsController').connectOutlet('mainHostStackVersions'); + } + else { + router.transitionTo('summary'); + } } }), http://git-wip-us.apache.org/repos/asf/ambari/blob/455a0a80/ambari-web/app/styles/stack_versions.less ---------------------------------------------------------------------- diff --git a/ambari-web/app/styles/stack_versions.less b/ambari-web/app/styles/stack_versions.less index 5c54ea3..6fd2954 100644 --- a/ambari-web/app/styles/stack_versions.less +++ b/ambari-web/app/styles/stack_versions.less @@ -271,3 +271,116 @@ width: 97%; } } + +.admin-cluster { + .repositories-table { + margin-bottom: 10px; + border: 1px solid #dddddd; + overflow: auto; + div { + float: left; + min-height: 1px; + } + .thead { + width: 100%; + .th { + font-weight: bold; + padding: 8px; + } + .os-th { + width: 10%; + } + .name-th { + width: 16%; + } + .url-th { + width: 66%; + } + } + .tbody { + width: 100%; + .trow { + width: 100%; + border-top: 1px solid #dddddd; + padding-top: 8px; + .os-td { + padding-top: 4px; + padding-left: 8px; + width: 9%; + } + .sub-trow { + width: 100%; + min-height: 39px; + .name-td { + width: 16%; + padding-top: 4px; + } + .url-td { + width: 60%; + .ember-text-field { + width: 100%; + margin: -1px -1px -1px -2px; + } + } + .url-text-td { + width: 70%; + padding-top: 4px; + padding-left: 3px; + overflow: auto; + } + .edit-td { + width: 8%; + padding-top: 4px; + padding-left: 5px; + a { + cursor: pointer; + } + } + .edit-buttons-td { + // save or cancel + width: 9%; + } + .clear-td { + width: 3%; + padding-top: 5px; + padding-left: 12px; + a { + cursor: pointer; + text-decoration: none; + } + .icon-remove-sign { + color: #808080; + } + } + } + } + } + .textfield-error input { + border-color: #b94a48; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + } + .disabled-textfield input { + color: #808080; + disabled: disabled; + pointer-events: none; + cursor: default; + background: #E4E4E4; + } + .disabled-label { + color: #808080; + } + } + #skip-validation { + margin-top: 10px; + .checkbox { + margin-left: 3px; + margin-right: 8px; + margin-top: 0px; + } + .icon-question-sign { + color: @blue; + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/455a0a80/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 index 80cf302..56d13bf 100644 --- a/ambari-web/app/templates/main/admin/stack_upgrade/services.hbs +++ b/ambari-web/app/templates/main/admin/stack_upgrade/services.hbs @@ -27,7 +27,7 @@ </tr> </thead> <tbody> - {{#each service in view.services}} + {{#each service in view.services}} <tr> <td class="service-display-name">{{service.displayName}}</td> <td class="service-stack-version">{{service.serviceVersion}}</td> @@ -41,6 +41,80 @@ </td> <td class="service-description">{{{service.comments}}}</td> </tr> - {{/each}} + {{/each}} </tbody> </table> + +{{#unless App.stackVersionsAvailable}} + + <div class="header"> + <strong>{{t admin.cluster.repositories.repositories}}</strong> + </div> + <ul class="nav nav-tabs"> + <li class="active"> + <a href="javascript:void(null);">{{view.allRepositoriesGroups.stackVersion}}</a> + </li> + </ul> + + <div class="admin-cluster"> + <div class="repositories-table"> + <div class="thead"> + <div class="th os-th">{{t common.os}}</div> + <div class="th name-th">{{t common.name}}</div> + <div class="th url-th">{{t installer.step1.advancedRepo.localRepo.column.baseUrl}}</div> + </div> + <div class="tbody"> + {{#each repoGroup in view.allRepositoriesGroups}} + <div class="trow"> + <div class="os-td"> + <label> + <span class="os">{{repoGroup.name}}</span> + </label> + </div> + <div style="width:89%"> + {{#each repository in repoGroup.repositories}} + <div class="sub-trow"> + <div class="name-td">{{repository.repoId}}</div> + <!--edit mode for current url--> + {{#if repository.onEdit}} + <div {{bindAttr class=":url-td repository.empty-error:textfield-error repository.invalid-error:textfield-error"}}> + {{view Ember.TextField valueBinding="repository.baseUrl"}} + </div> + <div class="clear-td"> + {{#if repository.clearAll}} + <a {{action "clearGroupLocalRepository" repository target="view" }}> + <i class="icon-remove-sign"></i> + </a> + {{/if}} + </div> + <div class="edit-buttons-td"> + <a class="btn" {{action doCancel repository target="view"}}>{{t common.cancel}}</a> + </div> + <div class="edit-buttons-td"> + {{#if repository.empty-error}} + <a class="btn btn-primary" disabled="disabled">{{t common.save}}</a> + {{else}} + <a class="btn btn-primary" {{action saveRepoUrls repository target="view"}}>{{t common.save}}</a> + {{/if}} + </div> + <!--non-edit mode for current url--> + {{else}} + <div class="url-text-td"> + {{repository.baseUrl}} + </div> + <div class="edit-td"> + <a {{action "onEditClick" repository target="view" }}> + <i class="icon-edit"></i> {{t common.edit}} + </a> + </div> + {{/if}} + </div> + {{/each}} + </div> + </div> + {{/each}} + </div> + </div> + </div> + +{{/unless}} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/455a0a80/ambari-web/app/templates/main/host.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/host.hbs b/ambari-web/app/templates/main/host.hbs index 3474686..ec3ba93 100644 --- a/ambari-web/app/templates/main/host.hbs +++ b/ambari-web/app/templates/main/host.hbs @@ -68,7 +68,7 @@ {{view view.parentView.memorySort}} {{view view.parentView.diskUsageSort}} {{view view.parentView.loadAvgSort}} - <th {{bindAttr class="App.supports.stackUpgrade::hidden :sort-view-11"}}> + <th {{bindAttr class="App.supports.stackUpgrade::hidden App.stackVersionsAvailable::hidden :sort-view-11"}}> {{t hosts.host.menu.stackVersions}} </th> <th class="sort-view-6">{{t common.components}}</th> @@ -84,7 +84,7 @@ <th>{{view view.ramFilterView}}</th> <th> </th> <th>{{view view.loadAvgFilterView}}</th> - <th {{bindAttr class="App.supports.stackUpgrade::hidden"}}> + <th {{bindAttr class="App.supports.stackUpgrade::hidden App.stackVersionsAvailable::hidden"}}> {{view view.versionsFilterView}} </th> <th>{{view view.componentsFilterView}}</th> @@ -132,7 +132,7 @@ </td> <td class="load-avg">{{host.loadAvg}}</td> - <td {{bindAttr class="App.supports.stackUpgrade::hidden view.hasSingleVersion:not-active-link :host-table-versions"}}> + <td {{bindAttr class="App.supports.stackUpgrade::hidden App.stackVersionsAvailable::hidden view.hasSingleVersion:not-active-link :host-table-versions"}}> <a href="#" class="expander black" {{action toggleVersions target="view"}}> {{#unless view.hasSingleVersion}} <span {{bindAttr class="view.isVersionsCollapsed:icon-caret-right:icon-caret-down"}}></span> http://git-wip-us.apache.org/repos/asf/ambari/blob/455a0a80/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 index cf4b500..1006013 100644 --- a/ambari-web/app/views/main/admin/stack_upgrade/menu_view.js +++ b/ambari-web/app/views/main/admin/stack_upgrade/menu_view.js @@ -23,18 +23,21 @@ App.MainAdminStackMenuView = Em.CollectionView.extend({ 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' - }) - ], + content: function () { + return [ + 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', + hidden: !App.get('stackVersionsAvailable') + }) + ] + }.property('App.stackVersionsAvailable'), didInsertElement: function () { this.activateView(); @@ -56,6 +59,6 @@ App.MainAdminStackMenuView = Em.CollectionView.extend({ itemViewClass: Em.View.extend({ classNameBindings: ["active"], active: "", - template: Ember.Handlebars.compile('<a {{action stackNavigate view.content.routing }} href="#"> {{unbound view.content.label}}</a>') + template: Ember.Handlebars.compile('{{#unless view.content.hidden}}<a {{action stackNavigate view.content.routing }} href="#"> {{unbound view.content.label}}</a>{{/unless}}') }) }); http://git-wip-us.apache.org/repos/asf/ambari/blob/455a0a80/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 index 3d8e6dc..b36e5f3 100644 --- a/ambari-web/app/views/main/admin/stack_upgrade/services_view.js +++ b/ambari-web/app/views/main/admin/stack_upgrade/services_view.js @@ -33,6 +33,12 @@ App.MainAdminStackServicesView = Em.View.extend({ }); }.property('App.router.clusterController.isLoaded'), + didInsertElement: function () { + if (!App.get('stackVersionsAvailable')) { + this.get('controller').loadRepositories(); + } + }, + /** * launch Add Service wizard * @param event @@ -44,5 +50,217 @@ App.MainAdminStackServicesView = Em.View.extend({ App.router.get('addServiceController').set('serviceToInstall', event.context); App.get('router').transitionTo('main.serviceAdd'); } + }, + + /** + * List of all repo-groups + * @type {Object[][]} + */ + allRepositoriesGroups: function () { + var repos = this.get('controller.allRepos'); + var reposGroup = []; + var repositories = []; + reposGroup.set('stackVersion', App.get('currentStackVersionNumber')); + if (repos) { + repos.forEach(function (group) { + group.repositories.forEach (function(repo) { + var cur_repo = Em.Object.create({ + 'repoId': repo.repoId, + 'id': repo.repoId + '-' + repo.osType, + 'repoName' : repo.repoName, + 'stackName' : repo.stackName, + 'stackVersion' : repo.stackVersion, + 'baseUrl': repo.baseUrl, + 'originalBaseUrl': repo.baseUrl, + 'osType': repo.osType, + 'onEdit': false, + 'empty-error': !repo.baseUrl, + 'undo': false, + 'clearAll': repo.baseUrl + }); + var cur_group = reposGroup.findProperty('name', group.name); + if (!cur_group) { + var cur_group = Ember.Object.create({ + name: group.name, + repositories: [] + }); + reposGroup.push(cur_group); + } + cur_group.repositories.push(cur_repo); + repositories.push(cur_repo); + }); + }); + } + this.set('allRepos', repositories); + return reposGroup; + }.property('controller.allRepos'), + + /** + * Onclick handler for edit action of each repo, enter edit mode + * @param {object} event + */ + onEditClick:function (event) { + var targetRepo = this.get('allRepos').findProperty('id', event.context.get('id')); + if (targetRepo) { + targetRepo.set('onEdit', true); + } + }, + + /** + * Onclick handler for undo action of each repo group + * @method undoGroupLocalRepository + * @param {object} event + */ + undoGroupLocalRepository: function (event) { + this.doActionForGroupLocalRepository(event, 'originalBaseUrl'); + }, + + /** + * Handler for clear icon click + * @method clearGroupLocalRepository + * @param {object} event + */ + clearGroupLocalRepository: function (event) { + this.doActionForGroupLocalRepository(event, ''); + }, + + /** + * Common handler for repo groups actions + * @method doActionForGroupLocalRepository + * @param {object} event + * @param {string} newBaseUrlField + */ + doActionForGroupLocalRepository: function (event, newBaseUrlField) { + var targetRepo = this.get('allRepos').findProperty('id', event.context.get('id')); + if (targetRepo) { + targetRepo.set('baseUrl', Em.isEmpty(newBaseUrlField) ? '' : Em.get(targetRepo, newBaseUrlField)); + } + }, + + /** + * Handler when editing any repo group BaseUrl + * @method editGroupLocalRepository + */ + editGroupLocalRepository: function (event) { + var repos = this.get('allRepos'); + repos.forEach(function (targetRepo) { + targetRepo.set('undo', targetRepo.get('baseUrl') != targetRepo.get('originalBaseUrl')); + targetRepo.set('clearAll', targetRepo.get('baseUrl')); + targetRepo.set('empty-error', !targetRepo.get('baseUrl')); + + }); + }.observes('[email protected]'), + + /** + * onSuccess callback for save Repo URL. + */ + doSaveRepoUrlsSuccessCallback: function (response, request, data) { + var id = data.repoId + '-' + data.osType; + console.log('Success in check Repo URL. data repoId+osType: ' + id); + var targetRepo = this.get('allRepos').findProperty('id', id); + if (!targetRepo) { + return; + } else { + + var modalCloseHandler = function() { + this.hide(); + targetRepo.set('baseUrl', data.data.Repositories.base_url); + targetRepo.set('originalBaseUrl', data.data.Repositories.base_url); + targetRepo.set('onEdit', false); + }; + + App.ModalPopup.show({ + header: Em.I18n.t('admin.cluster.repositories.popup.header.success'), + secondary: null, + onPrimary: modalCloseHandler, + onClose: modalCloseHandler, + message: Em.I18n.t('admin.cluster.repositories.popup.body.success'), + bodyClass: Em.View.extend({ + template: Em.Handlebars.compile('<div class="alert alert-success">{{{message}}}</div>') + }) + }) + } + }, + + /** + * onError callback for save Repo URL. + */ + doSaveRepoUrlsErrorCallback: function (request, ajaxOptions, error, data) { + console.log('Error in check Repo URL. The baseURL sent is: ' + data.data); + var self = this; + var id = data.url.split('/')[10] + '-' + data.url.split('/')[8]; + var targetRepo = this.get('allRepos').findProperty('id', id); + if (!targetRepo) { + return; + } else { + App.ModalPopup.show({ + header: Em.I18n.t('admin.cluster.repositories.popup.header.fail'), + primary: Em.I18n.t('common.saveAnyway'), + secondary: Em.I18n.t('common.revert'), + third: Em.I18n.t('common.cancel'), + onPrimary: function () { + // save anyway: Go ahead and save with Repo URL validation turned off and close Dialog when done. + this.hide(); + self.doSaveRepoUrls(id, false); + }, + onSecondary: function () { + // Revert: Close dialog, revert URL value, go back to non-Edit mode + this.hide(); + targetRepo.set('baseUrl', targetRepo.get('originalBaseUrl')); + targetRepo.set('onEdit', false); + }, + onThird: function () { + // cancel: Close dialog but stay in Edit mode + this.hide(); + }, + message: Em.I18n.t('admin.cluster.repositories.popup.body.fail'), + bodyClass: Em.View.extend({ + template: Em.Handlebars.compile('<div class="alert alert-warning">{{{message}}}</div>') + }) + }) + } + }, + + /** + * Check validation and Save the customized local urls + */ + doSaveRepoUrls: function (id, verifyBaseUrl) { + var targetRepo = this.get('allRepos').findProperty('id', id); + var verifyBaseUrl = verifyBaseUrl; + App.ajax.send({ + name: 'wizard.advanced_repositories.valid_url', + sender: this, + data: { + stackName: targetRepo.stackName, + stackVersion: targetRepo.stackVersion, + repoId: targetRepo.repoId, + osType: targetRepo.osType, + data: { + 'Repositories': { + 'base_url': targetRepo.baseUrl, + "verify_base_url": verifyBaseUrl + } + } + }, + success: 'doSaveRepoUrlsSuccessCallback', + error: 'doSaveRepoUrlsErrorCallback' + }); + }, + /** + * Check validation and Save the customized local urls + */ + saveRepoUrls: function (event) { + this.doSaveRepoUrls(event.context.get('id'), true); + }, + + /** + * on click handler 'Cancel' for current repo in edit mode + */ + doCancel: function (event) { + var targetRepo = this.get('allRepos').findProperty('id', event.context.get('id')); + if (targetRepo) { + targetRepo.set('baseUrl', targetRepo.get('originalBaseUrl')); + targetRepo.set('onEdit', false); + } } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/455a0a80/ambari-web/app/views/main/host/menu.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/host/menu.js b/ambari-web/app/views/main/host/menu.js index d1c26d7..2df638e 100644 --- a/ambari-web/app/views/main/host/menu.js +++ b/ambari-web/app/views/main/host/menu.js @@ -23,37 +23,39 @@ App.MainHostMenuView = Em.CollectionView.extend({ classNames: ["nav", "nav-tabs"], host: null, - content: [ - Em.Object.create({ - name: 'summary', - label: Em.I18n.t('common.summary'), - routing: 'summary', - id: 'host-details-summary-tab' - }), - Em.Object.create({ - name: 'configs', - label: Em.I18n.t('common.configs'), - routing: 'configs', - id: 'host-details-summary-configs' - }), - Em.Object.create({ - name: 'alerts', - label: Em.I18n.t('hosts.host.alerts.label'), - routing: 'alerts', - badgeText: '0', - badgeClasses: 'label', - id: 'host-details-summary-alerts' - }), - Em.Object.create({ - name: 'versions', - label: Em.I18n.t('hosts.host.menu.stackVersions'), - routing: 'stackVersions', - hidden: function() { - return !App.get('supports.stackUpgrade') - }.property('App.get.supports.stackUpgrade'), - id: 'host-details-summary-version' - }) - ], + content: function () { + return [ + Em.Object.create({ + name: 'summary', + label: Em.I18n.t('common.summary'), + routing: 'summary', + id: 'host-details-summary-tab' + }), + Em.Object.create({ + name: 'configs', + label: Em.I18n.t('common.configs'), + routing: 'configs', + id: 'host-details-summary-configs' + }), + Em.Object.create({ + name: 'alerts', + label: Em.I18n.t('hosts.host.alerts.label'), + routing: 'alerts', + badgeText: '0', + badgeClasses: 'label', + id: 'host-details-summary-alerts' + }), + Em.Object.create({ + name: 'versions', + label: Em.I18n.t('hosts.host.menu.stackVersions'), + routing: 'stackVersions', + hidden: function () { + return !App.get('supports.stackUpgrade') || !App.get('stackVersionsAvailable') + }.property('App.supports.stackUpgrade'), + id: 'host-details-summary-version' + }) + ]; + }.property('App.stackVersionsAvailable'), /** * Update Alerts menu option counter text and class @@ -102,4 +104,4 @@ App.MainHostMenuView = Em.CollectionView.extend({ '{{view.content.badgeText}}' + '</span> {{/if}}</a>{{/unless}}') }) -}); \ No newline at end of file +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/455a0a80/ambari-web/test/views/main/admin/stack_upgrade/menu_view_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/main/admin/stack_upgrade/menu_view_test.js b/ambari-web/test/views/main/admin/stack_upgrade/menu_view_test.js new file mode 100644 index 0000000..ad02d39 --- /dev/null +++ b/ambari-web/test/views/main/admin/stack_upgrade/menu_view_test.js @@ -0,0 +1,56 @@ +/** + * 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 view; + +describe('App.MainAdminStackMenuView', function () { + + beforeEach(function () { + view = App.MainAdminStackMenuView.create({}); + }); + + describe('#content', function () { + + afterEach(function () { + App.get.restore(); + }); + + Em.A([ + { + stackVersionsAvailable: true, + m: '`versions` is visible', + e: false + }, + { + stackVersionsAvailable: false, + m: '`versions` is invisible', + e: true + } + ]).forEach(function (test) { + it(test.m, function () { + var stub = sinon.stub(App, 'get'); + stub.withArgs('stackVersionsAvailable').returns(test.stackVersionsAvailable); + view.propertyDidChange('content'); + expect(view.get('content').findProperty('name', 'versions').get('hidden')).to.equal(test.e); + }); + }); + + }); + +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/455a0a80/ambari-web/test/views/main/host/menu_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/main/host/menu_test.js b/ambari-web/test/views/main/host/menu_test.js new file mode 100644 index 0000000..71468dc --- /dev/null +++ b/ambari-web/test/views/main/host/menu_test.js @@ -0,0 +1,71 @@ +/** + * 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 view; + +describe('App.MainHostMenuView', function () { + + beforeEach(function () { + view = App.MainHostMenuView.create({}); + }); + + describe('#content', function () { + + afterEach(function () { + App.get.restore(); + }); + + Em.A([ + { + stackVersionsAvailable: true, + stackUpgrade: true, + m: '`versions` is visible', + e: false + }, + { + stackVersionsAvailable: true, + stackUpgrade: false, + m: '`versions` is invisible (1)', + e: true + }, + { + stackVersionsAvailable: false, + stackUpgrade: true, + m: '`versions` is invisible (2)', + e: true + }, + { + stackVersionsAvailable: false, + stackUpgrade: false, + m: '`versions` is invisible (3)', + e: true + } + ]).forEach(function (test) { + it(test.m, function () { + var stub = sinon.stub(App, 'get'); + stub.withArgs('stackVersionsAvailable').returns(test.stackVersionsAvailable); + stub.withArgs('supports.stackUpgrade').returns(test.stackUpgrade); + view.propertyDidChange('content'); + expect(view.get('content').findProperty('name', 'versions').get('hidden')).to.equal(test.e); + }); + }); + + }); + +});
