AMBARI-22304 Add search box filter to Config History page. (atkach)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/479cf86a Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/479cf86a Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/479cf86a Branch: refs/heads/branch-feature-AMBARI-14714 Commit: 479cf86ac3c17c8dcaba89280fb2dc5c9012523b Parents: 655e0a7 Author: Andrii Tkach <[email protected]> Authored: Wed Oct 25 15:40:59 2017 +0300 Committer: Andrii Tkach <[email protected]> Committed: Wed Oct 25 15:40:59 2017 +0300 ---------------------------------------------------------------------- ambari-web/app/assets/test/tests.js | 2 + .../main/dashboard/config_history_controller.js | 92 ++----- ambari-web/app/routes/main.js | 2 - ambari-web/app/templates/main/alerts.hbs | 2 +- .../templates/main/dashboard/config_history.hbs | 23 +- ambari-web/app/templates/main/host.hbs | 2 +- ambari-web/app/utils/ajax/ajax.js | 4 + ambari-web/app/views.js | 2 + ambari-web/app/views/common/search_box_view.js | 165 +++++++++++++ .../app/views/main/alerts/alert_search_box.js | 161 ++----------- .../main/dashboard/config_history_search_box.js | 221 +++++++++++++++++ .../views/main/dashboard/config_history_view.js | 101 -------- .../app/views/main/host/combo_search_box.js | 44 +--- .../test/views/common/search_box_view_test.js | 240 +++++++++++++++++++ .../views/main/alerts/alert_search_box_test.js | 74 +----- .../dashboard/config_history_search_box_test.js | 207 ++++++++++++++++ .../main/dashboard/config_history_view_test.js | 188 +-------------- .../views/main/host/combo_search_box_test.js | 66 +---- 18 files changed, 908 insertions(+), 688 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/479cf86a/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 fe0dd17..de81764 100644 --- a/ambari-web/app/assets/test/tests.js +++ b/ambari-web/app/assets/test/tests.js @@ -295,6 +295,7 @@ var files = [ 'test/views/main/admin/service_auto_start/component_auto_start_test', 'test/views/main/admin/service_auto_start_test', 'test/views/main/dashboard/config_history_view_test', + 'test/views/main/dashboard/config_history_search_box_test', 'test/views/main/dashboard/widget_test', 'test/views/main/dashboard/widgets_test', 'test/views/main/dashboard/widgets/text_widget_test', @@ -382,6 +383,7 @@ var files = [ 'test/views/common/form/spinner_input_view_test', 'test/views/common/form/manage_kdc_credentials_form_test', 'test/views/common/log_file_search_view_test', + 'test/views/common/search_box_view_test', 'test/views/wizard/step3/hostLogPopupBody_view_test', 'test/views/wizard/step3/hostWarningPopupBody_view_test', 'test/views/wizard/step3/hostWarningPopupFooter_view_test', http://git-wip-us.apache.org/repos/asf/ambari/blob/479cf86a/ambari-web/app/controllers/main/dashboard/config_history_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/dashboard/config_history_controller.js b/ambari-web/app/controllers/main/dashboard/config_history_controller.js index 5197ad9..ae3057d 100644 --- a/ambari-web/app/controllers/main/dashboard/config_history_controller.js +++ b/ambari-web/app/controllers/main/dashboard/config_history_controller.js @@ -103,79 +103,6 @@ App.MainConfigHistoryController = Em.ArrayController.extend(App.TableServerMixin } ], - modifiedFilter: Em.Object.create({ - content: [ - { - value: 'Any', - label: Em.I18n.t('any') - }, - { - value: 'Past 1 hour', - label: 'Past 1 hour' - }, - { - value: 'Past 1 Day', - label: 'Past 1 Day' - }, - { - value: 'Past 2 Days', - label: 'Past 2 Days' - }, - { - value: 'Past 7 Days', - label: 'Past 7 Days' - }, - { - value: 'Past 14 Days', - label: 'Past 14 Days' - }, - { - value: 'Past 30 Days', - label: 'Past 30 Days' - } - ], - optionValue: 'Any', - filterModified: function () { - var time = ""; - var curTime = new Date().getTime(); - - switch (this.get('optionValue.value')) { - case 'Past 1 hour': - time = curTime - 3600000; - break; - case 'Past 1 Day': - time = curTime - 86400000; - break; - case 'Past 2 Days': - time = curTime - 172800000; - break; - case 'Past 7 Days': - time = curTime - 604800000; - break; - case 'Past 14 Days': - time = curTime - 1209600000; - break; - case 'Past 30 Days': - time = curTime - 2592000000; - break; - case 'Any': - time = ""; - break; - } - this.set("actualValues", { - endTime: '', - startTime: time - }); - }.observes('optionValue'), - cancel: function () { - this.set('optionValue', this.get('content').findProperty('value', 'Any')); - }, - actualValues: Em.Object.create({ - startTime: "", - endTime: "" - }) - }), - /** * load all data components required by config history table * - total counter of service config versions(called in parallel) @@ -276,5 +203,24 @@ App.MainConfigHistoryController = Em.ArrayController.extend(App.TableServerMixin } }); return sortParams; + }, + + /** + * + * @param {string} name + */ + getSearchBoxSuggestions: function(name) { + const dfd = $.Deferred(); + const key = this.get('filterProps').findProperty('name', name).key; + App.ajax.send({ + name: 'service.serviceConfigVersions.get.suggestions', + sender: this, + data: { + key + } + }) + .done((data) => {dfd.resolve(data.items.mapProperty(key).uniq());}) + .fail(() => {dfd.resolve([]);}); + return dfd.promise(); } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/479cf86a/ambari-web/app/routes/main.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/routes/main.js b/ambari-web/app/routes/main.js index 5ba7c3d..194fb14 100644 --- a/ambari-web/app/routes/main.js +++ b/ambari-web/app/routes/main.js @@ -225,7 +225,6 @@ module.exports = Em.Route.extend(App.RouterRedirections, { connectOutlets: function (router, context) { App.loadTimer.start('Hosts Page'); router.get('mainController').connectOutlet('mainHost'); - router.get('mainHostController').connectOutlet('mainHostComboSearchBox'); } }), @@ -375,7 +374,6 @@ module.exports = Em.Route.extend(App.RouterRedirections, { route: '/', connectOutlets: function (router, context) { router.get('mainController').connectOutlet('mainAlertDefinitions'); - router.get('mainAlertDefinitionsController').connectOutlet('MainAlertDefinitionSearchBox'); } }), http://git-wip-us.apache.org/repos/asf/ambari/blob/479cf86a/ambari-web/app/templates/main/alerts.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/alerts.hbs b/ambari-web/app/templates/main/alerts.hbs index 1ce2c91..a111728 100644 --- a/ambari-web/app/templates/main/alerts.hbs +++ b/ambari-web/app/templates/main/alerts.hbs @@ -34,7 +34,7 @@ </div> </div> <div class="row search-box-row hide"> - {{outlet}} + {{view App.MainAlertDefinitionSearchBoxView}} </div> <table class="table advanced-header-table table-hover alerts-table" id="alert-definitions-table"> <thead> http://git-wip-us.apache.org/repos/asf/ambari/blob/479cf86a/ambari-web/app/templates/main/dashboard/config_history.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/dashboard/config_history.hbs b/ambari-web/app/templates/main/dashboard/config_history.hbs index bc6ef7c..3a1967a 100644 --- a/ambari-web/app/templates/main/dashboard/config_history.hbs +++ b/ambari-web/app/templates/main/dashboard/config_history.hbs @@ -18,7 +18,20 @@ <div id="config_history" class="container-wrap-table"> <div class="row"> - <h2 class="table-title col-md-12">{{t dashboard.configHistory.title}}</h2> + <h2 class="table-title col-md-2">{{t dashboard.configHistory.title}}</h2> + <div class="table-controls row col-sm-10 pull-right"> + <div class="col-sm-12"> + <div class="VS-open-box pull-right"> + <button class="btn btn-default"> + <i class="icon-search"></i> + </button> + <div class="popup-arrow-up hide"></div> + </div> + </div> + </div> + </div> + <div class="row search-box-row hide"> + {{view App.MainConfigHistorySearchBoxView}} </div> <table class="table advanced-header-table table-hover"> <thead> @@ -29,14 +42,6 @@ {{view view.parentView.authorSort}} {{view view.parentView.notesSort}} {{/view}} - - <tr class="filter-row config-history-filter-row"> - <th class="first cg-service">{{view view.serviceFilterView}}</th> - <th class="cg-name">{{view view.configGroupFilterView}}</th> - <th class="cg-created">{{view view.modifiedFilterView}}</th> - <th class="cg-author">{{view view.authorFilterView}}</th> - <th class="cg-notes">{{view view.notesFilterView}}</th> - </tr> </thead> <tbody class="services-menu"> {{#if view.filteringComplete}} http://git-wip-us.apache.org/repos/asf/ambari/blob/479cf86a/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 992c6b1..b823b9b 100644 --- a/ambari-web/app/templates/main/host.hbs +++ b/ambari-web/app/templates/main/host.hbs @@ -35,7 +35,7 @@ </div> </div> <div class="row search-box-row hide"> - {{outlet}} + {{view App.MainHostComboSearchBoxView}} </div> <table class="table advanced-header-table table-hover" id="hosts-table"> <thead> http://git-wip-us.apache.org/repos/asf/ambari/blob/479cf86a/ambari-web/app/utils/ajax/ajax.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js index c32d8d4..3f85dfdc 100644 --- a/ambari-web/app/utils/ajax/ajax.js +++ b/ambari-web/app/utils/ajax/ajax.js @@ -2831,6 +2831,10 @@ var urls = { } } }, + 'service.serviceConfigVersions.get.suggestions': { + real: '/clusters/{clusterName}/configurations/service_config_versions?fields={key}&minimal_response=true', + mock: '' + }, 'service.serviceConfigVersion.revert': { 'real': '/clusters/{clusterName}', 'mock': '', http://git-wip-us.apache.org/repos/asf/ambari/blob/479cf86a/ambari-web/app/views.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js index 8ffa8f5..394e390 100644 --- a/ambari-web/app/views.js +++ b/ambari-web/app/views.js @@ -35,6 +35,7 @@ require('views/common/chart/pie'); require('views/common/chart/linear'); require('views/common/chart/linear_time'); require('views/common/modal_popup'); +require('views/common/search_box_view'); require('views/common/modal_popups/alert_popup'); require('views/common/modal_popups/edit_dashboard_widget_popup'); require('views/common/modal_popups/manage_kdc_credentials_popup'); @@ -286,6 +287,7 @@ require('views/main/dashboard/widgets/yarn_memory'); require('views/main/dashboard/widgets/supervisor_live'); require('views/main/dashboard/widgets/flume_agent_live'); require('views/main/dashboard/config_history_view'); +require('views/main/dashboard/config_history_search_box'); require('views/main/service'); http://git-wip-us.apache.org/repos/asf/ambari/blob/479cf86a/ambari-web/app/views/common/search_box_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/search_box_view.js b/ambari-web/app/views/common/search_box_view.js new file mode 100644 index 0000000..8a61d4e --- /dev/null +++ b/ambari-web/app/views/common/search_box_view.js @@ -0,0 +1,165 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var App = require('app'); + +App.SearchBoxView = Em.View.extend({ + templateName: require('templates/main/host/combo_search_box'), + errMsg: '', + classNames: ['col-sm-12'], + keyFilterMap: [], + + didInsertElement: function () { + this.initVS(); + this.restoreComboFilterQuery(); + this.showHideClearButton(); + this.initOpenVSButton(); + }, + + showErrMsg: function(category) { + this.set('errMsg', category.attributes.value + " " + Em.I18n.t('hosts.combo.search.invalidCategory')); + }, + + clearErrMsg: function() { + this.set('errMsg', '') + }, + + initOpenVSButton: function() { + $('.VS-open-box button').click(function() { + $('.VS-open-box .popup-arrow-up, .search-box-row').toggleClass('hide'); + }); + }, + + initVS: function() { + window.visualSearch = VS.init({ + container: $('#combo_search_box'), + query: '', + showFacets: true, + delay: 500, + placeholder: Em.I18n.t('common.search'), + unquotable: [ + 'text' + ], + callbacks: { + search: this.search.bind(this), + facetMatches: this.facetMatches.bind(this), + valueMatches: this.valueMatches.bind(this) + } + }); + }, + + /** + * 'search' callback for visualsearch.js + * @param query + * @param searchCollection + */ + search: function (query, searchCollection) { + this.clearErrMsg(); + this.showHideClearButton(); + var invalidFacet = this.findInvalidFacet(searchCollection); + if (invalidFacet) { + this.showErrMsg(invalidFacet); + } + var tableView = this.get('parentView'); + App.db.setComboSearchQuery(tableView.get('controller.name'), query); + var filterConditions = this.createFilterConditions(searchCollection); + tableView.updateComboFilter(filterConditions); + }, + + /** + * 'facetMatches' callback for visualsearch.js + * @param callback + */ + facetMatches: function (callback) { + callback(this.get('keyFilterMap').mapProperty('label'), {preserveOrder: true}); + }, + + valueMatches: Em.K, + + /** + * + * @param {Array} values + * @param {string} facetValue + */ + rejectUsedValues: function(values, facetValue) { + return values.reject(function (item) { + return visualSearch.searchQuery.values(facetValue).indexOf(item) >= 0; + }) + }, + + /** + * + * @param {object} searchCollection + * @returns {!object} + */ + findInvalidFacet: function(searchCollection) { + const map = this.get('keyFilterMap'); + return searchCollection.models.find((facet) => { + return !map.someProperty('label', facet.attributes.category); + }); + }, + + showHideClearButton: function () { + if (visualSearch.searchQuery.length > 0) { + $('.VS-cancel-search-box').removeClass('hide'); + } else { + $('.VS-cancel-search-box').addClass('hide'); + } + }, + + restoreComboFilterQuery: function() { + const query = App.db.getComboSearchQuery(this.get('parentView.controller.name')); + if (query) { + visualSearch.searchBox.setQuery(query); + } + }, + + /** + * + * @param {object} searchCollection + * @returns {Array} + */ + createFilterConditions: function (searchCollection) { + const filterConditions = []; + const map = this.get('keyFilterMap'); + + searchCollection.models.forEach((model) => { + const filter = model.attributes; + const category = map.findProperty('label', filter.category); + if (category) { + filterConditions.push({ + skipFilter: false, + iColumn: category.column, + value: this.mapLabelToValue(category.key, filter.value), + type: category.type + }); + } + }); + return filterConditions; + }, + + /** + * + * @param {string} category + * @param {string} label + * @returns {string} + */ + mapLabelToValue: function(category, label) { + return label; + } +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/479cf86a/ambari-web/app/views/main/alerts/alert_search_box.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/alerts/alert_search_box.js b/ambari-web/app/views/main/alerts/alert_search_box.js index eebd7ee..07fa336 100644 --- a/ambari-web/app/views/main/alerts/alert_search_box.js +++ b/ambari-web/app/views/main/alerts/alert_search_box.js @@ -18,79 +18,51 @@ var App = require('app'); -App.MainAlertDefinitionSearchBoxView = Em.View.extend({ - templateName: require('templates/main/host/combo_search_box'), - errMsg: '', - classNames: ['col-sm-12'], - - didInsertElement: function () { - this.initVS(); - this.restoreComboFilterQuery(); - this.showHideClearButton(); - this.initOpenVSButton(); - }, - - initOpenVSButton: function() { - $('.VS-open-box button').click(function() { - $('.VS-open-box .popup-arrow-up, .search-box-row').toggleClass('hide'); - }); - }, - - initVS: function() { - window.visualSearch = VS.init({ - container: $('#combo_search_box'), - query: '', - showFacets: true, - delay: 500, - placeholder: Em.I18n.t('common.search'), - unquotable: [ - 'text' - ], - callbacks: { - search: this.search.bind(this), - facetMatches: this.facetMatches.bind(this), - valueMatches: this.valueMatches.bind(this) - } - }); - }, +App.MainAlertDefinitionSearchBoxView = App.SearchBoxView.extend({ /** * describe filter columns - * @type {object} + * @type {Array} * @const */ - keyFilterMap: { - 'Status': { + keyFilterMap: [ + { + label: Em.I18n.t('common.status'), key: 'summary', type: 'alert_status', column: 2 }, - 'Alert Definition Name': { + { + label: Em.I18n.t('alerts.table.header.definitionName'), key: 'label', type: 'string', column: 1 }, - 'Service': { + { + label: Em.I18n.t('common.service'), key: 'serviceName', type: 'select', column: 3 }, - 'Last Status Changed': { + { + label: Em.I18n.t('alerts.table.header.lastTriggered'), key: 'lastTriggered', type: 'date', column: 5 }, - 'State': { + { + label: Em.I18n.t('alerts.table.state'), key: 'enabled', type: 'enable_disable', column: 6 }, - 'Group': { + { + label: Em.I18n.t('common.group'), key: 'groups', type: 'alert_group', column: 7 } - }, + ], enabledDisabledMap: { 'enabled': Em.I18n.t('alerts.table.state.enabled'), @@ -113,32 +85,6 @@ App.MainAlertDefinitionSearchBoxView = Em.View.extend({ groupsNameIdMap: {}, /** - * 'search' callback for visualsearch.js - * @param query - * @param searchCollection - */ - search: function (query, searchCollection) { - this.clearErrMsg(); - this.showHideClearButton(); - var invalidFacet = this.findInvalidFacet(searchCollection); - if (invalidFacet) { - this.showErrMsg(invalidFacet); - } - var tableView = this.get('parentView.parentView'); - App.db.setComboSearchQuery(tableView.get('controller.name'), query); - var filterConditions = this.createFilterConditions(searchCollection); - tableView.updateComboFilter(filterConditions); - }, - - /** - * 'facetMatches' callback for visualsearch.js - * @param callback - */ - facetMatches: function (callback) { - callback(Object.keys(this.get('keyFilterMap')), {preserveOrder: true}); - }, - - /** * 'valueMatches' callback for visualsearch.js * @param facetValue * @param searchTerm @@ -146,7 +92,7 @@ App.MainAlertDefinitionSearchBoxView = Em.View.extend({ */ valueMatches: function (facetValue, searchTerm, callback) { this.showHideClearButton(); - switch (this.get('keyFilterMap')[facetValue].key) { + switch (this.get('keyFilterMap').findProperty('label', facetValue).key) { case 'summary': this.getSummaryAvailableValues(facetValue, callback); break; @@ -230,75 +176,6 @@ App.MainAlertDefinitionSearchBoxView = Em.View.extend({ /** * - * @param {Array} values - * @param {string} facetValue - */ - rejectUsedValues: function(values, facetValue) { - return values.reject(function (item) { - return visualSearch.searchQuery.values(facetValue).indexOf(item) >= 0; - }) - }, - - /** - * - * @param {object} searchCollection - * @returns {!object} - */ - findInvalidFacet: function(searchCollection) { - const map = this.get('keyFilterMap'); - return searchCollection.models.find((facet) => { - return !map[facet.attributes.category]; - }); - }, - - showErrMsg: function(category) { - this.set('errMsg', category.attributes.value + " " + Em.I18n.t('hosts.combo.search.invalidCategory')); - }, - - clearErrMsg: function() { - this.set('errMsg', '') - }, - - showHideClearButton: function () { - if (visualSearch.searchQuery.length > 0) { - $('.VS-cancel-search-box').removeClass('hide'); - } else { - $('.VS-cancel-search-box').addClass('hide'); - } - }, - - restoreComboFilterQuery: function() { - const query = App.db.getComboSearchQuery(this.get('parentView.parentView.controller.name')); - if (query) { - visualSearch.searchBox.setQuery(query); - } - }, - - /** - * - * @param {object} searchCollection - * @returns {Array} - */ - createFilterConditions: function (searchCollection) { - const filterConditions = []; - const map = this.get('keyFilterMap'); - - searchCollection.models.forEach((model) => { - const filter = model.attributes; - if (map[filter.category]) { - filterConditions.push({ - skipFilter: false, - iColumn: map[filter.category].column, - value: this.mapLabelToValue(filter.category, filter.value), - type: map[filter.category].type - }); - } - }); - return filterConditions; - }, - - /** - * * @param {string} category * @param {string} label */ @@ -307,9 +184,9 @@ App.MainAlertDefinitionSearchBoxView = Em.View.extend({ const groupsNameIdMap = this.get('groupsNameIdMap'); switch (category) { - case 'State': + case 'enabled': return Object.keys(enabledDisabledMap)[Object.values(enabledDisabledMap).indexOf(label)]; - case 'Group': + case 'groups': return groupsNameIdMap[label]; default: return label; http://git-wip-us.apache.org/repos/asf/ambari/blob/479cf86a/ambari-web/app/views/main/dashboard/config_history_search_box.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/dashboard/config_history_search_box.js b/ambari-web/app/views/main/dashboard/config_history_search_box.js new file mode 100644 index 0000000..fee26c8 --- /dev/null +++ b/ambari-web/app/views/main/dashboard/config_history_search_box.js @@ -0,0 +1,221 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var App = require('app'); + +App.MainConfigHistorySearchBoxView = App.SearchBoxView.extend({ + + /** + * @type {Array} + * @const + */ + modifiedOptions: [ + 'Past 1 hour', + 'Past 1 Day', + 'Past 2 Days', + 'Past 7 Days', + 'Past 14 Days', + 'Past 30 Days' + ], + + /** + * describe filter columns + * @type {Array} + * @const + */ + keyFilterMap: [ + { + label: Em.I18n.t('common.service'), + key: 'serviceVersion', + type: 'select', + column: 1 + }, + { + label: Em.I18n.t('common.configGroup'), + key: 'configGroup', + type: 'select', + column: 2 + }, + { + label: Em.I18n.t('dashboard.configHistory.table.created.title'), + key: 'createTime', + type: 'range', + column: 3 + }, + { + label: Em.I18n.t('common.author'), + key: 'author', + type: 'string', + column: 4 + }, + { + label: Em.I18n.t('common.notes'), + key: 'notes', + type: 'string', + column: 5 + } + ], + + /** + * populated dynamically in <code>getGroupsAvailableValues<code> + * @type {object} + */ + groupsNameIdMap: {}, + + /** + * 'valueMatches' callback for visualsearch.js + * @param facetValue + * @param searchTerm + * @param callback + */ + valueMatches: function (facetValue, searchTerm, callback) { + this.showHideClearButton(); + switch (this.get('keyFilterMap').findProperty('label', facetValue).key) { + case 'serviceVersion': + this.getServiceVersionAvailableValues(facetValue, callback); + break; + case 'configGroup': + this.getConfigGroupAvailableValues(facetValue, callback); + break; + case 'createTime': + this.getCreateTimeAvailableValues(facetValue, callback); + break; + case 'author': + this.getAuthorAvailableValues(facetValue, callback); + break; + case 'notes': + this.getNotesAvailableValues(facetValue, callback); + break; + } + }, + + /** + * + * @param {string} facetValue + * @param {Function} callback + */ + getServiceVersionAvailableValues: function(facetValue, callback) { + callback(this.rejectUsedValues(App.StackService.find().mapProperty('displayName'), facetValue), {preserveOrder: true}); + }, + + /** + * + * @param {string} facetValue + * @param {Function} callback + */ + getConfigGroupAvailableValues: function(facetValue, callback) { + const configGroups = App.ServiceConfigVersion.find().mapProperty('groupName').uniq().compact(); + callback(this.rejectUsedValues(configGroups, facetValue)); + this.requestFacetSuggestions(facetValue, callback); + }, + + /** + * + * @param {string} facetValue + * @param {Function} callback + */ + getCreateTimeAvailableValues: function(facetValue, callback) { + callback(this.rejectUsedValues(this.get('modifiedOptions'), facetValue), {preserveOrder: true}); + }, + + /** + * + * @param {string} facetValue + * @param {Function} callback + */ + getAuthorAvailableValues: function(facetValue, callback) { + callback(this.rejectUsedValues(App.ServiceConfigVersion.find().mapProperty('author').uniq(), facetValue)); + this.requestFacetSuggestions(facetValue, callback); + }, + + /** + * + * @param {string} facetValue + * @param {Function} callback + */ + getNotesAvailableValues: function(facetValue, callback) { + callback(this.rejectUsedValues(App.ServiceConfigVersion.find().mapProperty('notes').uniq(), facetValue)); + this.requestFacetSuggestions(facetValue, callback); + }, + + + /** + * request suggestions for facet from server + * @param {string} facetValue + * @param {Function} callback + */ + requestFacetSuggestions: function (facetValue, callback) { + const name = this.get('keyFilterMap').findProperty('label', facetValue).key; + this.get('controller').getSearchBoxSuggestions(name).done((suggestions) => { + if (suggestions.length) { + callback(suggestions); + } + }); + }, + + /** + * + * @param {string} category + * @param {string} label + */ + mapLabelToValue: function(category, label) { + switch (category) { + case 'createTime': + return this.computeCreateTimeRange(label); + case 'serviceVersion': + return App.StackService.find().findProperty('displayName', label).get('serviceName'); + default: + return label; + } + }, + + /** + * + * @param {string} value + * @returns {Array} [startTime, endTime] + */ + computeCreateTimeRange: function(value) { + let time = ""; + const curTime = App.dateTime(); + + switch (value) { + case 'Past 1 hour': + time = curTime - 3600000; + break; + case 'Past 1 Day': + time = curTime - 86400000; + break; + case 'Past 2 Days': + time = curTime - 172800000; + break; + case 'Past 7 Days': + time = curTime - 604800000; + break; + case 'Past 14 Days': + time = curTime - 1209600000; + break; + case 'Past 30 Days': + time = curTime - 2592000000; + break; + case 'Any': + time = ""; + break; + } + return [time, '']; + } +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/479cf86a/ambari-web/app/views/main/dashboard/config_history_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/dashboard/config_history_view.js b/ambari-web/app/views/main/dashboard/config_history_view.js index 2808de3..4376067 100644 --- a/ambari-web/app/views/main/dashboard/config_history_view.js +++ b/ambari-web/app/views/main/dashboard/config_history_view.js @@ -72,12 +72,6 @@ App.MainConfigHistoryView = App.TableView.extend(App.TableServerViewMixin, { clearTimeout(this.get('controller.timeoutRef')); }, - updateFilter: function (iColumn, value, type) { - if (!this.get('isInitialRendering')) { - this._super(iColumn, value, type); - } - }, - sortView: sort.serverWrapperView, versionSort: sort.fieldView.extend({ column: 1, @@ -106,81 +100,6 @@ App.MainConfigHistoryView = App.TableView.extend(App.TableServerViewMixin, { displayName: Em.I18n.t('common.notes') }), - serviceFilterView: filters.createSelectView({ - column: 1, - fieldType: 'filter-input-width', - content: function () { - return [ - { - value: '', - label: Em.I18n.t('common.all') - } - ].concat(App.StackService.find().map(function (service) { - return { - value: service.get('serviceName'), - label: service.get('displayName') - } - })); - }.property('App.router.clusterController.isLoaded'), - onChangeValue: function () { - this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'select'); - } - }), - - configGroupFilterView: filters.createSelectView({ - column: 2, - fieldType: 'filter-input-width', - content: [], - observeContent: function() { - var groupName = App.ServiceConfigVersion.find().mapProperty('groupName').uniq().compact(); - // list of group names can only grow since config versions not removable - if (groupName.length >= this.get('content.length')) { - this.set('content', [ - { - value: '', - label: Em.I18n.t('common.all') - } - ].concat(groupName.map(function (item) { - return { - value: item, - label: item - } - }))); - } - }.observes('parentView.isInitialRendering', 'parentView.pageContent'), - onChangeValue: function () { - this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'select'); - } - }), - - modifiedFilterView: filters.createSelectView({ - column: 3, - appliedEmptyValue: ["", ""], - fieldType: 'filter-input-width,modified-filter', - emptyValue: 'Any', - contentBinding: "controller.modifiedFilter.content", - onChangeValue: function () { - this.set("controller.modifiedFilter.optionValue", this.get('selected')); - this.get('parentView').updateFilter(this.get('column'), [this.get('controller.modifiedFilter.actualValues.startTime'), this.get('controller.modifiedFilter.actualValues.endTime')], 'range'); - } - }), - - authorFilterView: filters.createTextView({ - column: 4, - fieldType: 'filter-input-width', - onChangeValue: function () { - this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'string'); - } - }), - - notesFilterView: filters.createTextView({ - column: 5, - fieldType: 'filter-input-width', - onChangeValue: function () { - this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'string'); - } - }), - ConfigVersionView: Em.View.extend({ tagName: 'tr', showLessNotes: true, @@ -209,18 +128,6 @@ App.MainConfigHistoryView = App.TableView.extend(App.TableServerViewMixin, { }, /** - * Clear all filter values, update filter conditions in the localStorage and update table data with API-request - * - * @method clearFilters - * @override - */ - clearFilters: function () { - this._super(); - this.saveAllFilterConditions(); - this.refresh(); - }, - - /** * callback executed after refresh call done * @method refreshDone */ @@ -236,13 +143,5 @@ App.MainConfigHistoryView = App.TableView.extend(App.TableServerViewMixin, { App.db.setStartIndex(this.get('controller.name'), this.get('startIndex')); }.observes('startIndex'), - /** - * associations between host property and column index - * @type {Array} - */ - colPropAssoc: function () { - return this.get('controller.colPropAssoc'); - }.property('controller.colPropAssoc'), - filter: Em.K }); http://git-wip-us.apache.org/repos/asf/ambari/blob/479cf86a/ambari-web/app/views/main/host/combo_search_box.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/host/combo_search_box.js b/ambari-web/app/views/main/host/combo_search_box.js index b77e877..a582286 100644 --- a/ambari-web/app/views/main/host/combo_search_box.js +++ b/ambari-web/app/views/main/host/combo_search_box.js @@ -18,25 +18,10 @@ var App = require('app'); -App.MainHostComboSearchBoxView = Em.View.extend({ - templateName: require('templates/main/host/combo_search_box'), +App.MainHostComboSearchBoxView = App.SearchBoxView.extend({ healthStatusCategories: require('data/host/categories'), - errMsg: '', serviceMap : {}, - classNames: ['col-sm-12'], - - didInsertElement: function () { - this.initVS(); - this.restoreComboFilterQuery(); - this.showHideClearButton(); - this.initOpenVSButton(); - }, - - initOpenVSButton: function() { - $('.VS-open-box button').click(function() { - $('.VS-open-box .popup-arrow-up, .search-box-row').toggleClass('hide'); - }); - }, + controllerBinding: 'App.router.mainHostComboSearchBoxController', initVS: function() { this.setupLabelMap(); @@ -68,7 +53,7 @@ App.MainHostComboSearchBoxView = Em.View.extend({ if (invalidFacet) { this.showErrMsg(invalidFacet); } - var tableView = this.get('parentView.parentView'); + var tableView = this.get('parentView'); App.db.setComboSearchQuery(tableView.get('controller.name'), query); var filterConditions = this.createFilterConditions(searchCollection); tableView.updateComboFilter(filterConditions); @@ -280,29 +265,6 @@ App.MainHostComboSearchBoxView = Em.View.extend({ return result; }, - showErrMsg: function(category) { - this.set('errMsg', category.attributes.value + " " + Em.I18n.t('hosts.combo.search.invalidCategory')); - }, - - clearErrMsg: function() { - this.set('errMsg', '') - }, - - showHideClearButton: function () { - if (visualSearch.searchQuery.toJSON().length > 0) { - $('.VS-cancel-search-box').removeClass('hide'); - } else { - $('.VS-cancel-search-box').addClass('hide'); - } - }, - - restoreComboFilterQuery: function() { - var query = App.db.getComboSearchQuery(this.get('parentView.parentView.controller.name')); - if (query) { - visualSearch.searchBox.setQuery(query); - } - }, - getHostComponentList: function() { var hostComponentList = []; App.MasterComponent.find().rejectProperty('totalCount', 0).toArray() http://git-wip-us.apache.org/repos/asf/ambari/blob/479cf86a/ambari-web/test/views/common/search_box_view_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/common/search_box_view_test.js b/ambari-web/test/views/common/search_box_view_test.js new file mode 100644 index 0000000..53100e8 --- /dev/null +++ b/ambari-web/test/views/common/search_box_view_test.js @@ -0,0 +1,240 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var App = require('app'); +require('views/common/search_box_view'); + +describe('App.SearchBoxView', function () { + var view; + + beforeEach(function () { + view = App.SearchBoxView.create({ + parentView: Em.Object.create({ + updateComboFilter: Em.K, + controller: { + name: 'ctrl1' + } + }), + keyFilterMap: [ + { + label: 'l1', + key: 'key1', + type: 'type1', + column: 1 + } + ] + }); + }); + + describe('#didInsertElement', function() { + beforeEach(function() { + sinon.stub(view, 'initVS'); + sinon.stub(view, 'restoreComboFilterQuery'); + sinon.stub(view, 'showHideClearButton'); + sinon.stub(view, 'initOpenVSButton'); + view.didInsertElement(); + }); + afterEach(function() { + view.initVS.restore(); + view.restoreComboFilterQuery.restore(); + view.showHideClearButton.restore(); + view.initOpenVSButton.restore(); + }); + + it('initVS should be called', function() { + expect(view.initVS.calledOnce).to.be.true; + }); + + it('restoreComboFilterQuery should be called', function() { + expect(view.restoreComboFilterQuery.calledOnce).to.be.true; + }); + + it('showHideClearButton should be called', function() { + expect(view.showHideClearButton.calledOnce).to.be.true; + }); + + it('initOpenVSButton should be called', function() { + expect(view.initOpenVSButton.calledOnce).to.be.true; + }); + }); + + describe('#showErrMsg', function() { + it('should set errMsg', function() { + view.showErrMsg({attributes: {value: 'val1'}}); + expect(view.get('errMsg')).to.be.equal('val1 ' + Em.I18n.t('hosts.combo.search.invalidCategory')); + }); + }); + + describe('#clearErrMsg', function() { + it('should set errMsg', function() { + view.set('errMsg', 'aaa'); + view.clearErrMsg(); + expect(view.get('errMsg')).to.be.empty; + }); + }); + + describe('#initVS', function() { + beforeEach(function() { + sinon.stub(VS, 'init'); + }); + afterEach(function() { + VS.init.restore(); + }); + + it('VS.init should be called', function() { + view.initVS(); + expect(VS.init.calledOnce).to.be.true; + }); + }); + + describe('#search', function() { + beforeEach(function() { + sinon.stub(view, 'clearErrMsg'); + sinon.stub(view, 'showHideClearButton'); + sinon.stub(view, 'findInvalidFacet').returns({}); + sinon.stub(view, 'showErrMsg'); + sinon.stub(App.db, 'setComboSearchQuery'); + sinon.stub(view, 'createFilterConditions').returns([]); + sinon.stub(view.get('parentView'), 'updateComboFilter'); + view.search('query', []); + }); + afterEach(function() { + view.clearErrMsg.restore(); + view.showHideClearButton.restore(); + view.findInvalidFacet.restore(); + view.showErrMsg.restore(); + App.db.setComboSearchQuery.restore(); + view.createFilterConditions.restore(); + view.get('parentView').updateComboFilter.restore(); + }); + + it('clearErrMsg should be called', function() { + expect(view.clearErrMsg.calledOnce).to.be.true; + }); + + it('showHideClearButton should be called', function() { + expect(view.showHideClearButton.calledOnce).to.be.true; + }); + + it('showErrMsg should be called', function() { + expect(view.showErrMsg.calledOnce).to.be.true; + }); + + it('App.db.setComboSearchQuery should be called', function() { + expect(App.db.setComboSearchQuery.calledWith('ctrl1', 'query')).to.be.true; + }); + + it('createFilterConditions should be called', function() { + expect(view.createFilterConditions.calledWith([])).to.be.true; + }); + + it('updateComboFilter should be called', function() { + expect(view.get('parentView').updateComboFilter.calledWith([])).to.be.true; + }); + }); + + describe('#facetMatches', function() { + it('callback should be called', function() { + var callback = sinon.spy(); + view.facetMatches(callback); + expect(callback.calledWith(view.get('keyFilterMap').mapProperty('label'), {preserveOrder: true})).to.be.true; + }); + }); + + describe('#findInvalidFacet', function() { + it('should return invalid facet', function() { + var searchCollection = { + models: [ + { + attributes: { + category: 'wrong' + } + }, + { + attributes: { + category: view.get('keyFilterMap').mapProperty('label')[0] + } + } + ] + }; + expect(view.findInvalidFacet(searchCollection)).to.be.eql(searchCollection.models[0]); + }); + }); + + describe('#restoreComboFilterQuery', function() { + beforeEach(function() { + sinon.stub(App.db, 'getComboSearchQuery').returns('query'); + visualSearch = { + searchBox: { + setQuery: sinon.spy() + } + }; + }); + afterEach(function() { + App.db.getComboSearchQuery.restore(); + }); + + it('visualSearch.searchBox.setQuery should be called', function() { + view.restoreComboFilterQuery(); + expect(visualSearch.searchBox.setQuery.calledWith('query')).to.be.true; + }); + }); + + describe('#createFilterConditions', function() { + + it('should return empty when no correct category passed', function() { + var searchCollection = { + models: [ + { + attributes: { + category: 'wrong' + } + } + ] + }; + expect(view.createFilterConditions(searchCollection)).to.be.empty; + }); + + it('should return filter condition when correct category passed', function() { + var searchCollection = { + models: [ + { + attributes: { + category: view.get('keyFilterMap').mapProperty('label')[0], + value: 'val1' + } + } + ] + }; + expect(view.createFilterConditions(searchCollection)).to.be.eql([ + { + "iColumn": 1, + "skipFilter": false, + "type": "type1", + "value": 'val1' + } + ]); + }); + }); + + describe('#mapLabelToValue', function() { + it('should return label', function() { + expect(view.mapLabelToValue('cat1', 'l1')).to.be.equal('l1'); + }); + }); +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/479cf86a/ambari-web/test/views/main/alerts/alert_search_box_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/main/alerts/alert_search_box_test.js b/ambari-web/test/views/main/alerts/alert_search_box_test.js index f5ff79c..4264f8a 100644 --- a/ambari-web/test/views/main/alerts/alert_search_box_test.js +++ b/ambari-web/test/views/main/alerts/alert_search_box_test.js @@ -26,37 +26,10 @@ describe('App.MainAlertDefinitionDetailsView', function () { view = App.MainAlertDefinitionSearchBoxView.create({ controller: Em.Object.create() }); + sinon.stub(view, 'rejectUsedValues').returns([]); }); - - describe('#initVS', function() { - beforeEach(function() { - sinon.stub(VS, 'init'); - }); - afterEach(function() { - VS.init.restore(); - }); - - it('VS.init should be called', function() { - view.initVS(); - expect(VS.init.calledOnce).to.be.true; - }); - }); - - describe('#facetMatches', function() { - var mock = { - callback: Em.K - }; - beforeEach(function() { - sinon.spy(mock, 'callback'); - }); - afterEach(function() { - mock.callback.restore(); - }); - - it('callback should be called', function() { - view.facetMatches(mock.callback); - expect(mock.callback.calledOnce).to.be.true; - }); + afterEach(function() { + view.rejectUsedValues.restore(); }); describe('#valueMatches', function() { @@ -116,13 +89,6 @@ describe('App.MainAlertDefinitionDetailsView', function () { }); describe('#getSummaryAvailableValues', function() { - beforeEach(function() { - sinon.stub(view, 'rejectUsedValues').returns([]); - }); - afterEach(function() { - view.rejectUsedValues.restore(); - }); - it('callback should be called', function() { var callback = sinon.spy(); view.getSummaryAvailableValues('', callback); @@ -131,13 +97,6 @@ describe('App.MainAlertDefinitionDetailsView', function () { }); describe('#getLabelAvailableValues', function() { - beforeEach(function() { - sinon.stub(view, 'rejectUsedValues').returns([]); - }); - afterEach(function() { - view.rejectUsedValues.restore(); - }); - it('callback should be called', function() { var callback = sinon.spy(); view.getLabelAvailableValues('', callback); @@ -146,13 +105,6 @@ describe('App.MainAlertDefinitionDetailsView', function () { }); describe('#getServiceAvailableValues', function() { - beforeEach(function() { - sinon.stub(view, 'rejectUsedValues').returns([]); - }); - afterEach(function() { - view.rejectUsedValues.restore(); - }); - it('callback should be called', function() { var callback = sinon.spy(); view.getServiceAvailableValues('', callback); @@ -161,13 +113,6 @@ describe('App.MainAlertDefinitionDetailsView', function () { }); describe('#getTriggeredAvailableValues', function() { - beforeEach(function() { - sinon.stub(view, 'rejectUsedValues').returns([]); - }); - afterEach(function() { - view.rejectUsedValues.restore(); - }); - it('callback should be called', function() { var callback = sinon.spy(); view.getTriggeredAvailableValues('', callback); @@ -176,13 +121,6 @@ describe('App.MainAlertDefinitionDetailsView', function () { }); describe('#getEnabledAvailableValues', function() { - beforeEach(function() { - sinon.stub(view, 'rejectUsedValues').returns([]); - }); - afterEach(function() { - view.rejectUsedValues.restore(); - }); - it('callback should be called', function() { var callback = sinon.spy(); view.getEnabledAvailableValues('', callback); @@ -192,7 +130,6 @@ describe('App.MainAlertDefinitionDetailsView', function () { describe('#getGroupsAvailableValues', function() { beforeEach(function() { - sinon.stub(view, 'rejectUsedValues').returns([]); sinon.stub(App.AlertGroup, 'find').returns([ Em.Object.create({ id: 1, @@ -201,7 +138,6 @@ describe('App.MainAlertDefinitionDetailsView', function () { ]); }); afterEach(function() { - view.rejectUsedValues.restore(); App.AlertGroup.find.restore(); }); @@ -217,12 +153,12 @@ describe('App.MainAlertDefinitionDetailsView', function () { describe('#mapLabelToValue', function() { it('should return value of State filter', function() { - expect(view.mapLabelToValue('State', Em.I18n.t('alerts.table.state.enabled'))).to.be.equal('enabled'); + expect(view.mapLabelToValue('enabled', Em.I18n.t('alerts.table.state.enabled'))).to.be.equal('enabled'); }); it('should return value of Group filter', function() { view.set('groupsNameIdMap', {'l1': 1}); - expect(view.mapLabelToValue('Group', 'l1')).to.be.equal(1); + expect(view.mapLabelToValue('groups', 'l1')).to.be.equal(1); }); it('should return value of filter', function() { http://git-wip-us.apache.org/repos/asf/ambari/blob/479cf86a/ambari-web/test/views/main/dashboard/config_history_search_box_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/main/dashboard/config_history_search_box_test.js b/ambari-web/test/views/main/dashboard/config_history_search_box_test.js new file mode 100644 index 0000000..236d3df --- /dev/null +++ b/ambari-web/test/views/main/dashboard/config_history_search_box_test.js @@ -0,0 +1,207 @@ +/** + * 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.MainConfigHistorySearchBoxView', function () { + + beforeEach(function () { + view = App.MainConfigHistorySearchBoxView.create({ + controller: Em.Object.create({ + getSearchBoxSuggestions: function() { + return { + done: function(clb) { + clb([{}]); + } + } + } + }) + }); + sinon.stub(view, 'rejectUsedValues').returns([]); + }); + + afterEach(function() { + view.rejectUsedValues.restore(); + }); + + describe('#valueMatches', function() { + beforeEach(function() { + sinon.stub(view, 'showHideClearButton'); + sinon.stub(view, 'getServiceVersionAvailableValues'); + sinon.stub(view, 'getConfigGroupAvailableValues'); + sinon.stub(view, 'getCreateTimeAvailableValues'); + sinon.stub(view, 'getAuthorAvailableValues'); + sinon.stub(view, 'getNotesAvailableValues'); + }); + afterEach(function() { + view.showHideClearButton.restore(); + view.getServiceVersionAvailableValues.restore(); + view.getConfigGroupAvailableValues.restore(); + view.getCreateTimeAvailableValues.restore(); + view.getAuthorAvailableValues.restore(); + view.getNotesAvailableValues.restore(); + }); + + it('showHideClearButton should be called', function() { + view.valueMatches(Em.I18n.t('common.service')); + expect(view.showHideClearButton.calledOnce).to.be.true; + }); + + it('getServiceVersionAvailableValues should be called', function() { + view.valueMatches(Em.I18n.t('common.service'), '', Em.K); + expect(view.getServiceVersionAvailableValues.calledWith(Em.I18n.t('common.service'))).to.be.true; + }); + + it('getConfigGroupAvailableValues should be called', function() { + view.valueMatches(Em.I18n.t('common.configGroup'), '', Em.K); + expect(view.getConfigGroupAvailableValues.calledWith(Em.I18n.t('common.configGroup'))).to.be.true; + }); + + it('getCreateTimeAvailableValues should be called', function() { + view.valueMatches(Em.I18n.t('dashboard.configHistory.table.created.title'), '', Em.K); + expect(view.getCreateTimeAvailableValues.calledWith(Em.I18n.t('dashboard.configHistory.table.created.title'))).to.be.true; + }); + + it('getAuthorAvailableValues should be called', function() { + view.valueMatches(Em.I18n.t('common.author'), '', Em.K); + expect(view.getAuthorAvailableValues.calledWith(Em.I18n.t('common.author'))).to.be.true; + }); + + it('getNotesAvailableValues should be called', function() { + view.valueMatches(Em.I18n.t('common.notes'), '', Em.K); + expect(view.getNotesAvailableValues.calledWith(Em.I18n.t('common.notes'))).to.be.true; + }); + }); + + describe('#getServiceVersionAvailableValues', function() { + it('callback should be called', function() { + var callback = sinon.spy(); + view.getServiceVersionAvailableValues('', callback); + expect(callback.calledWith([], {preserveOrder: true})).to.be.true; + }); + }); + + describe('#getConfigGroupAvailableValues', function() { + beforeEach(function() { + sinon.stub(view, 'requestFacetSuggestions'); + }); + afterEach(function() { + view.requestFacetSuggestions(); + }); + + it('callback should be called', function() { + var callback = sinon.spy(); + view.getConfigGroupAvailableValues('', callback); + expect(callback.calledWith([])).to.be.true; + }); + + it('requestFacetSuggestions should be called', function() { + var callback = sinon.spy(); + view.getConfigGroupAvailableValues('', callback); + expect(view.requestFacetSuggestions.calledWith('', callback)).to.be.true; + }); + }); + + describe('#getCreateTimeAvailableValues', function() { + it('callback should be called', function() { + var callback = sinon.spy(); + view.getCreateTimeAvailableValues('', callback); + expect(callback.calledWith([], {preserveOrder: true})).to.be.true; + }); + }); + + describe('#getAuthorAvailableValues', function() { + beforeEach(function() { + sinon.stub(view, 'requestFacetSuggestions'); + }); + afterEach(function() { + view.requestFacetSuggestions(); + }); + + it('callback should be called', function () { + var callback = sinon.spy(); + view.getAuthorAvailableValues('', callback); + expect(callback.calledWith([])).to.be.true; + }); + + it('requestFacetSuggestions should be called', function() { + var callback = sinon.spy(); + view.getAuthorAvailableValues('', callback); + expect(view.requestFacetSuggestions.calledWith('', callback)).to.be.true; + }); + }); + + describe('#getNotesAvailableValues', function() { + beforeEach(function() { + sinon.stub(view, 'requestFacetSuggestions'); + }); + afterEach(function() { + view.requestFacetSuggestions(); + }); + + it('callback should be called', function() { + var callback = sinon.spy(); + view.getNotesAvailableValues('', callback); + expect(callback.calledWith([])).to.be.true; + }); + + it('requestFacetSuggestions should be called', function() { + var callback = sinon.spy(); + view.getNotesAvailableValues('', callback); + expect(view.requestFacetSuggestions.calledWith('', callback)).to.be.true; + }); + }); + + describe('#mapLabelToValue', function() { + beforeEach(function() { + sinon.stub(view, 'computeCreateTimeRange').returns([1,2]); + sinon.stub(App.StackService, 'find').returns([ + Em.Object.create({ + displayName: 's1', + serviceName: 'S1' + }) + ]); + }); + afterEach(function() { + view.computeCreateTimeRange.restore(); + App.StackService.find.restore(); + }); + + it('should return value of State filter', function() { + expect(view.mapLabelToValue('enabled', Em.I18n.t('alerts.table.state.enabled'))).to.be.equal(Em.I18n.t('alerts.table.state.enabled')); + }); + + it('should return value of createTime filter', function() { + expect(view.mapLabelToValue('createTime', 'l1')).to.be.eql([1, 2]); + }); + + it('should return value of serviceVersion filter', function() { + expect(view.mapLabelToValue('serviceVersion', 's1')).to.be.equal('S1'); + }); + }); + + describe('#requestFacetSuggestions', function() { + it('callback should be called', function() { + var callback = sinon.spy(); + view.requestFacetSuggestions(view.get('keyFilterMap').mapProperty('label')[0], callback); + expect(callback.calledWith([{}])).to.be.true; + }); + }); +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/479cf86a/ambari-web/test/views/main/dashboard/config_history_view_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/main/dashboard/config_history_view_test.js b/ambari-web/test/views/main/dashboard/config_history_view_test.js index da9ce31..a104e25 100644 --- a/ambari-web/test/views/main/dashboard/config_history_view_test.js +++ b/ambari-web/test/views/main/dashboard/config_history_view_test.js @@ -37,6 +37,7 @@ describe('App.MainConfigHistoryView', function() { } ], doPolling: Em.K, + updateFilter: Em.K, load: function () { return {done: Em.K}; }, @@ -54,161 +55,6 @@ describe('App.MainConfigHistoryView', function() { }); }); - describe("#serviceFilterView", function () { - var subView = view.get('serviceFilterView').create({ - parentView: view - }); - - before(function () { - sinon.stub(App.StackService, 'find').returns([Em.Object.create({ - serviceName: 'S1', - displayName: 's1' - })]) - }); - after(function () { - App.StackService.find.restore(); - }); - it("content", function () { - expect(subView.get('content')).to.eql([ - { - "value": "", - "label": Em.I18n.t('common.all') - }, - { - "value": "S1", - "label": "s1" - } - ]); - }); - - before(function () { - sinon.stub(view, 'updateFilter', Em.K); - }); - after(function () { - view.updateFilter.restore(); - }); - it("call onChangeValue()", function () { - subView.set('column', 1); - subView.set('value', 'value'); - subView.onChangeValue(); - expect(view.updateFilter.calledWith(1, 'value', 'select')).to.be.true; - }); - }); - - describe("#configGroupFilterView", function () { - var subView = view.get('configGroupFilterView').create({ - parentView: view - }); - - before(function () { - sinon.stub(App.ServiceConfigVersion, 'find').returns([ - Em.Object.create({groupName: 'G1'}), - Em.Object.create({groupName: 'G1'}), - Em.Object.create({groupName: 'Default'}), - Em.Object.create({groupName: null}) - ]); - }); - after(function () { - App.ServiceConfigVersion.find.restore(); - }); - it("content", function () { - subView.observeContent(); - expect(subView.get('content')).to.eql([ - { - value: '', - label: Em.I18n.t('common.all') - }, - { - value: 'G1', - label: 'G1' - }, - { - value: 'Default', - label: 'Default' - } - ]); - }); - - before(function () { - sinon.stub(view, 'updateFilter', Em.K); - }); - after(function () { - view.updateFilter.restore(); - }); - it("call onChangeValue()", function () { - subView.set('column', 1); - subView.set('value', 'value'); - subView.onChangeValue(); - expect(view.updateFilter.calledWith(1, 'value', 'select')).to.be.true; - }); - }); - - /** - * for now we don't use this method - describe("#modifiedFilterView", function () { - var subView = view.get('modifiedFilterView').create({ - parentView: view, - controller: { - modifiedFilter: { - actualValues: { - startTime: 0, - endTime: 1 - } - } - } - }); - - before(function () { - sinon.stub(view, 'updateFilter', Em.K); - }); - after(function () { - view.updateFilter.restore(); - }); - it("call onTimeChange()", function () { - subView.set('column', 1); - subView.onTimeChange(); - expect(view.updateFilter.calledWith(1, [0, 1], 'range')).to.be.true; - }); - });*/ - - describe("#authorFilterView", function () { - var subView = view.get('authorFilterView').create({ - parentView: view - }); - - before(function () { - sinon.stub(view, 'updateFilter', Em.K); - }); - after(function () { - view.updateFilter.restore(); - }); - it("call onChangeValue()", function () { - subView.set('column', 1); - subView.set('value', 'value'); - subView.onChangeValue(); - expect(view.updateFilter.calledWith(1, 'value', 'string')).to.be.true; - }); - }); - - describe("#notesFilterView", function () { - var subView = view.get('notesFilterView').create({ - parentView: view - }); - - before(function () { - sinon.stub(view, 'updateFilter', Em.K); - }); - after(function () { - view.updateFilter.restore(); - }); - it("call onChangeValue()", function () { - subView.set('column', 1); - subView.set('value', 'value'); - subView.onChangeValue(); - expect(view.updateFilter.calledWith(1, 'value', 'string')).to.be.true; - }); - }); - describe("#ConfigVersionView", function () { var subView; before(function () { @@ -289,35 +135,6 @@ describe('App.MainConfigHistoryView', function() { }); }); - describe('#updateFilter()', function () { - var cases = [ - { - isInitialRendering: false, - updateFilterCalled: true, - title: 'updateFilter should be called' - }, - { - isInitialRendering: true, - updateFilterCalled: false, - title: 'updateFilter should not be called' - } - ]; - beforeEach(function () { - sinon.stub(view, 'saveFilterConditions', Em.K); - view.set('filteringComplete', true); - }); - afterEach(function () { - view.saveFilterConditions.restore(); - }); - cases.forEach(function (item) { - it(item.title, function () { - view.set('isInitialRendering', item.isInitialRendering); - view.updateFilter(1, 'value', 'string'); - expect(view.get('saveFilterConditions').calledWith(1, 'value', 'string')).to.equal(item.updateFilterCalled); - }); - }); - }); - describe('#willDestroyElement()', function() { it('controller.isPolling is false', function() { view.willDestroyElement(); @@ -362,7 +179,4 @@ describe('App.MainConfigHistoryView', function() { expect(view.get('controller.resetStartIndex')).to.be.false; }); }); - - App.TestAliases.testAsComputedAlias(view, 'colPropAssoc', 'controller.colPropAssoc', 'array'); - }); http://git-wip-us.apache.org/repos/asf/ambari/blob/479cf86a/ambari-web/test/views/main/host/combo_search_box_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/main/host/combo_search_box_test.js b/ambari-web/test/views/main/host/combo_search_box_test.js index 0775f66..a59d845 100644 --- a/ambari-web/test/views/main/host/combo_search_box_test.js +++ b/ambari-web/test/views/main/host/combo_search_box_test.js @@ -94,11 +94,11 @@ describe('App.MainHostComboSearchBoxView', function () { describe("#search()", function () { beforeEach(function() { - view.set('parentView.parentView', Em.Object.create({ + view.set('parentView', Em.Object.create({ updateComboFilter: Em.K, controller: {name: 'ctrl1'} })); - sinon.stub(view.get('parentView.parentView'), 'updateComboFilter'); + sinon.stub(view.get('parentView'), 'updateComboFilter'); sinon.stub(view, 'createFilterConditions').returns([{}]); sinon.stub(view, 'clearErrMsg'); sinon.stub(view, 'showErrMsg'); @@ -112,7 +112,7 @@ describe('App.MainHostComboSearchBoxView', function () { view.showErrMsg.restore(); this.mockFacet.restore(); view.createFilterConditions.restore(); - view.get('parentView.parentView').updateComboFilter.restore(); + view.get('parentView').updateComboFilter.restore(); }); it("clearErrMsg should be called", function() { @@ -133,7 +133,7 @@ describe('App.MainHostComboSearchBoxView', function () { it("updateComboFilter should be called", function() { view.search('query', {}); - expect(view.get('parentView.parentView').updateComboFilter.calledWith([{}])).to.be.true; + expect(view.get('parentView').updateComboFilter.calledWith([{}])).to.be.true; }); }); @@ -576,64 +576,6 @@ describe('App.MainHostComboSearchBoxView', function () { }); }); - describe("#showHideClearButton()", function () { - var container = { - removeClass: Em.K, - addClass: Em.K - }; - - beforeEach(function() { - sinon.stub(window, '$').returns(container); - sinon.spy(container, 'removeClass'); - sinon.spy(container, 'addClass'); - this.mock = sinon.stub(visualSearch.searchQuery, 'toJSON'); - }); - - afterEach(function() { - window.$.restore(); - container.removeClass.restore(); - container.addClass.restore(); - visualSearch.searchQuery.toJSON.restore(); - }); - - it("class should be added", function() { - this.mock.returns([]); - view.showHideClearButton(); - expect(container.addClass.calledWith('hide')).to.be.true; - }); - - it("class should be removed", function() { - this.mock.returns(['f']); - view.showHideClearButton(); - expect(container.removeClass.calledWith('hide')).to.be.true; - }); - }); - - describe("#restoreComboFilterQuery()", function () { - - beforeEach(function() { - this.mockQuery = sinon.stub(App.db, 'getComboSearchQuery'); - sinon.stub(visualSearch.searchBox, 'setQuery'); - }); - - afterEach(function() { - this.mockQuery.restore(); - visualSearch.searchBox.setQuery.restore(); - }); - - it("query is empty", function() { - this.mockQuery.returns(''); - view.restoreComboFilterQuery(); - expect(visualSearch.searchBox.setQuery.called).to.be.false; - }); - - it("query has value", function() { - this.mockQuery.returns('query'); - view.restoreComboFilterQuery(); - expect(visualSearch.searchBox.setQuery.calledWith('query')).to.be.true; - }); - }); - describe("#getHostComponentList()", function () { var labelValueMap = {};
