blob: f417cc66296a7b35f98976da930d36f0ee1d38d3 [file] [log] [blame]
/**
* 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.MainHostComboSearchBoxView = Em.View.extend({
templateName: require('templates/main/host/combo_search_box'),
healthStatusCategories: require('data/host/categories'),
errMsg: '',
serviceMap : {},
didInsertElement: function () {
this.initVS();
this.restoreComboFilterQuery();
this.showHideClearButton();
},
initVS: function() {
this.setupLabelMap();
window.visualSearch = VS.init({
container: $('#combo_search_box'),
query: '',
showFacets: true,
delay: 1000,
placeholder: Em.I18n.t('hosts.combo.search.placebolder'),
unquotable: [
'text'
],
callbacks: {
search: this.search.bind(this),
facetMatches: this.facetMatches.bind(this),
valueMatches: this.valueMatches.bind(this)
}
});
},
/**
* 'search' call back for visualsearch.js
* @param query
* @param searchCollection
*/
search: function (query, searchCollection) {
this.clearErrMsg();
var invalidFacet = this.findInvalidFacet(searchCollection);
if (invalidFacet) {
this.showErrMsg(invalidFacet);
}
var tableView = this.get('parentView').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) {
this.showHideClearButton();
var list = [
{label: 'Host Name', category: 'Host'},
{label: 'IP', category: 'Host'},
{label: 'Host Status', category: 'Host'},
{label: 'Cores', category: 'Host'},
{label: 'RAM', category: 'Host'},
{label: 'Stack Version', category: 'Host'},
{label: 'Version State', category: 'Host'},
{label: 'Rack', category: 'Host'},
{label: 'Service', category: 'Service'}
];
var hostComponentList = this.getHostComponentList();
// Add host component facets only when there isn't any component filter
// with value other than ALL yet
var currentComponentFacets = this.getComponentStateFacets(hostComponentList, false);
if (currentComponentFacets.length == 0) {
list = list.concat(hostComponentList);
}
list = this.filterOutOneFacetOnlyOptions(list);
// Append host components
callback(list, {preserveOrder: true});
},
/**
* 'valueMatches' callback for visualsearch.js
* @param facet
* @param searchTerm
* @param callback
*/
valueMatches: function (facet, searchTerm, callback) {
var controller = App.router.get('mainHostComboSearchBoxController');
this.showHideClearButton();
var map = App.router.get('mainHostController.labelValueMap');
var serviceMap = this.get('serviceMap')
var facetValue = map[facet] || facet;
if (controller.isComponentStateFacet(facetValue)) {
facetValue = 'componentState'
}
switch (facetValue) {
case 'hostName':
case 'ip':
controller.getPropertySuggestions(facetValue, searchTerm).done(function() {
callback(controller.get('currentSuggestion').reject(function (item) {
return visualSearch.searchQuery.values(facet).indexOf(item) >= 0; // reject the ones already in search
}), {preserveMatches: true});
});
break;
case 'rack':
callback(App.Host.find().toArray().mapProperty('rack').uniq().reject(function (item) {
return visualSearch.searchQuery.values(facet).indexOf(item) >= 0;
}));
break;
case 'version':
callback(App.HostStackVersion.find().toArray()
.filterProperty('isVisible', true).mapProperty('displayName').uniq().reject(function (item) {
return visualSearch.searchQuery.values(facet).indexOf(item) >= 0;
}));
break;
case 'versionState':
callback(App.HostStackVersion.statusDefinition.map(function (status) {
map[App.HostStackVersion.formatStatus(status)] = status;
return App.HostStackVersion.formatStatus(status);
}).reject(function (item) {
return visualSearch.searchQuery.values(facet).indexOf(item) >= 0;
}));
break;
case 'healthClass':
var category_mocks = this.healthStatusCategories;
callback(category_mocks.slice(1).map(function (category) {
map[category.value] = category.healthStatus;
return category.value;
}).reject(function (item) {
return visualSearch.searchQuery.values(facet).indexOf(item) >= 0;
}), {preserveOrder: true});
break;
case 'services':
callback(App.Service.find().toArray().map(function (service) {
serviceMap[App.format.role(service.get('serviceName'), true)] = service.get('serviceName');
return App.format.role(service.get('serviceName'), true);
}).reject(function (item) {
return visualSearch.searchQuery.values(facet).indexOf(item) >= 0;
}), {preserveOrder: true});
break;
case 'componentState':
var list = [ "All" ];
// client only have "ALL" state
if (facet.toLowerCase().indexOf("client") == -1)
{
var currentComponentFacets = this.getComponentStateFacets(null, true);
if (currentComponentFacets.length == 0) {
list = list.concat(App.HostComponentStatus.getStatusesList()
.reject(function(status){return status == "UPGRADE_FAILED"}) // take out 'UPGRADE_FAILED'
.map(function (status) {
map[App.HostComponentStatus.getTextStatus(status)] = status;
return App.HostComponentStatus.getTextStatus(status);
}))
.concat([
"Inservice",
"Decommissioned",
"Decommissioning",
"RS Decommissioned",
"Maintenance Mode On",
"Maintenance Mode Off"
]);
}
}
callback(list, {preserveOrder: true});
break;
}
},
findInvalidFacet: function(searchCollection) {
var result = null;
var map = App.router.get('mainHostController.labelValueMap');
for (var i = 0; i < searchCollection.models.length; i++) {
var facet = searchCollection.models[i];
if (!map[facet.attributes.category]) {
result = facet;
break;
}
}
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()
.concat(App.SlaveComponent.find().rejectProperty('totalCount', 0).toArray()
.concat(App.ClientComponent.find().rejectProperty('totalCount', 0).toArray()))
.forEach(function(component) {
var displayName = component.get('displayName');
if (displayName) {
hostComponentList.push({label: displayName, category: 'Component'});
App.router.get('mainHostController.labelValueMap')[displayName] = component.get('componentName');
}
});
return hostComponentList;
},
getComponentStateFacets: function(hostComponentList, includeAllValue) {
if (!hostComponentList) {
hostComponentList = this.getHostComponentList();
}
var currentComponentFacets = visualSearch.searchQuery.toJSON().filter(function (facet) {
var result = !!(hostComponentList.findProperty('label', facet.category) && facet.value);
if (!includeAllValue) {
result &= (facet.value != 'All');
}
return result;
});
return currentComponentFacets;
},
getFacetsByName: function(name) {
var facets = visualSearch.searchQuery.toJSON().filter(function(facet) {
return facet.category === name;
});
return facets;
},
filterOutOneFacetOnlyOptions: function(options) {
var self = this;
var oneFacetOnlyLables = ['Cores', 'RAM'];
oneFacetOnlyLables.forEach(function(label) {
var facets = self.getFacetsByName(label);
if (facets.length > 0) {
options = options.rejectProperty('label', label);
}
});
return options;
},
setupLabelMap: function() {
var map = App.router.get('mainHostController.labelValueMap');
map['All'] = 'ALL';
map['Host Name'] = 'hostName';
map['IP'] = 'ip';
map['Host Status'] = 'healthClass';
map['Cores'] = 'cpu';
map['RAM'] = 'memoryFormatted';
map['Stack Version'] = 'version';
map['Version State'] = 'versionState';
map['Rack'] = 'rack';
map['Service'] = 'services';
map['Inservice'] = 'INSERVICE';
map['Decommissioned'] = 'DECOMMISSIONED';
map['Decommissioning'] = 'DECOMMISSIONING';
map['RS Decommissioned'] = 'RS_DECOMMISSIONED';
map['Maintenance Mode On'] = 'ON';
map['Maintenance Mode Off'] = 'OFF';
},
createFilterConditions: function(searchCollection) {
var self = this;
var mainHostController = App.router.get('mainHostController');
var map = mainHostController.get('labelValueMap');
var serviceMap = this.get('serviceMap');
var filterConditions = Em.A();
searchCollection.models.forEach(function (model) {
var tag = model.attributes;
var category = map[tag.category] || tag.category;
var value = (category == 'services')? (serviceMap[tag.value] || tag.value) : (map[tag.value] || tag.value);
var iColumn = self.getFilterColumn(category, value);
var filterValue = self.getFilterValue(category, value);
var condition = filterConditions.findProperty('iColumn', iColumn);
if (condition) {
// handle multiple facets with same category
if (typeof condition.value == 'string') {
condition.value = [condition.value, filterValue];
} else if (Em.isArray(condition.value) && condition.value.indexOf(filterValue) == -1) {
condition.value.push(filterValue);
}
} else {
var type = 'string';
if (category === 'cpu') {
type = 'number';
}
if (category === 'memoryFormatted') {
type = 'ambari-bandwidth';
}
condition = {
skipFilter: false,
iColumn: iColumn,
value: filterValue,
type: type
};
filterConditions.push(condition);
}
});
return filterConditions;
},
getFilterColumn: function(category, value) {
var iColumn = -1;
if (this.get('controller').isComponentStateFacet(category)) {
iColumn = App.router.get('mainHostController').get('colPropAssoc').indexOf('componentState');
} else if (this.get('controller').isComplexHealthStatusFacet(value)) {
iColumn = this.get('healthStatusCategories').findProperty('healthStatus', value).column;
} else {
iColumn = App.router.get('mainHostController').get('colPropAssoc').indexOf(category);
}
return iColumn;
},
getFilterValue: function(category, value) {
var filterValue = value;
if (this.get('controller').isComponentStateFacet(category)) {
filterValue = category + ':' + value;
} else if (this.get('controller').isComplexHealthStatusFacet(value)) {
filterValue = this.get('healthStatusCategories').findProperty('healthStatus', value).filterValue;
}
return filterValue;
}
});