Author: yusaku
Date: Thu Jan 31 00:26:13 2013
New Revision: 1440747
URL: http://svn.apache.org/viewvc?rev=1440747&view=rev
Log:
AMBARI-1303. Remake clearFilters function in app_view. (Arun Kandregula via
yusaku)
Modified:
incubator/ambari/trunk/CHANGES.txt
incubator/ambari/trunk/ambari-web/app/controllers/main/apps_controller.js
incubator/ambari/trunk/ambari-web/app/styles/apps.less
incubator/ambari/trunk/ambari-web/app/templates/main/apps.hbs
incubator/ambari/trunk/ambari-web/app/templates/main/host/component_filter.hbs
incubator/ambari/trunk/ambari-web/app/views/common/filter_view.js
incubator/ambari/trunk/ambari-web/app/views/main/apps_view.js
incubator/ambari/trunk/ambari-web/app/views/main/host.js
Modified: incubator/ambari/trunk/CHANGES.txt
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/CHANGES.txt?rev=1440747&r1=1440746&r2=1440747&view=diff
==============================================================================
--- incubator/ambari/trunk/CHANGES.txt (original)
+++ incubator/ambari/trunk/CHANGES.txt Thu Jan 31 00:26:13 2013
@@ -36,6 +36,9 @@ Trunk (unreleased changes):
IMPROVEMENTS
+ AMBARI-1303. Remake clearFilters function in app_view. (Arun Kandregula via
+ yusaku)
+
AMBARI-1302. Minor label cleanup on Jobs Charts popup. (Arun Kandregula via
yusaku)
Modified:
incubator/ambari/trunk/ambari-web/app/controllers/main/apps_controller.js
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/main/apps_controller.js?rev=1440747&r1=1440746&r2=1440747&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/main/apps_controller.js
(original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/main/apps_controller.js
Thu Jan 31 00:26:13 2013
@@ -28,6 +28,19 @@ App.MainAppsController = Em.ArrayControl
loaded : false,
loading : false,
+ /**
+ * List of users.
+ * Will be used for filtering in user column.
+ * Go to App.MainAppsView.userFilterView for more information
+ */
+ users: function () {
+ return
this.get('content').mapProperty("userName").uniq().map(function(userName){
+ return {
+ name: userName,
+ checked: false
+ };
+ });
+ }.property('content.length'),
loadRuns:function () {
Modified: incubator/ambari/trunk/ambari-web/app/styles/apps.less
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/styles/apps.less?rev=1440747&r1=1440746&r2=1440747&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/styles/apps.less (original)
+++ incubator/ambari/trunk/ambari-web/app/styles/apps.less Thu Jan 31 00:26:13
2013
@@ -56,29 +56,27 @@
word-wrap: break-word;
}
- .view-wrapper {
- width: 73%;
- }
input, select{
- width: 90%;
+ width: 77%;
+ }
+
+ input.input-super-mini{
+ width: 47px;
+ max-width: 57%;
}
+
label.checkbox input {
width: auto;
}
.col8,
td:first-child + td,
th:first-child + th{
- width: 15%;
- }
- .col0,
- td:first-child + td,
- th:first-child + th{
- width: 15%;
+ width: 11%;
}
.col1,
td:first-child + td + td,
th:first-child + th + th{
- width: 12%;
+ width: 15%;
}
.col2,
td:first-child + td + td + td,
@@ -253,10 +251,6 @@
}
}
- div.view-wrapper {
- float: left;
- }
-
a.ui-icon-circle-close {
float: right;
opacity: 0.2;
Modified: incubator/ambari/trunk/ambari-web/app/templates/main/apps.hbs
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/templates/main/apps.hbs?rev=1440747&r1=1440746&r2=1440747&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/templates/main/apps.hbs (original)
+++ incubator/ambari/trunk/ambari-web/app/templates/main/apps.hbs Thu Jan 31
00:26:13 2013
@@ -66,7 +66,7 @@
</div>
</div>
- <table class="table table-striped runsList" id="dataTable">
+ <table class="table table-striped runsList">
<thead>
{{#view view.wrapSorting}}
{{#each controller.columnsName}}
@@ -76,15 +76,15 @@
{{/each}}
{{/view}}
<tr>
- <th class="notActive"><div class="view-wrapper">{{view
view.appidFilterView valueBinding="controller.filterObject.sSearch_0"
viewName="appidFilterViewInstance"}}</div> <a href="#" {{action
"clearFilterButtonClick" target="view"}} id="view_appidFilterViewInstance"
class="ui-icon ui-icon-circle-close ui-appid"></a></th>
- <th class="notActive"><div class="view-wrapper">{{view
view.nameFilterView valueBinding="controller.filterObject.sSearch_1"
viewName="nameFilterViewInstance"}}</div> <a href="#" {{action
"clearFilterButtonClick" target="view"}} id="view_nameFilterViewInstance"
class="ui-icon ui-icon-circle-close ui-name"></a></th>
- <th class="notActive"><div class="view-wrapper">{{view
view.typeSelectView selectionBinding="controller.filterObject.runType"
viewName="typeSelectViewInstance"}}</div> <a href="#" {{action
"clearFilterButtonClick" target="view"}} id="view_typeSelectViewInstance"
class="ui-icon ui-icon-circle-close ui-type"></a></th>
- <th class="notActive"><div class="view-wrapper">{{view
view.userFilterView viewName="userFilterViewInstance"}}</div> <a href="#"
{{action "clearFilterButtonClick" target="view"}}
id="view_userFilterViewInstance" class="ui-icon ui-icon-circle-close
ui-user"></a><input id="user_filter" type="hidden"></th>
- <th class="notActive"><div class="view-wrapper">{{view
view.jobsFilterView valueBinding="controller.filterObject.jobs"
viewName="jobsFilterViewInstance"}}</div> <a href="#" {{action
"clearFilterButtonClick" target="view"}} id="view_jobsFilterViewInstance"
class="ui-icon ui-icon-circle-close ui-jobs"></a></th>
- <th class="notActive"><div class="view-wrapper">{{view
view.inputFilterView valueBinding="controller.filterObject.input"
viewName="inputFilterViewInstance"}}</div> <a href="#" {{action
"clearFilterButtonClick" target="view"}} id="view_inputFilterViewInstance"
class="ui-icon ui-icon-circle-close ui-input"></a></th>
- <th class="notActive"><div class="view-wrapper">{{view
view.outputFilterView valueBinding="controller.filterObject.output"
viewName="outputFilterViewInstance"}}</div> <a href="#" {{action
"clearFilterButtonClick" target="view"}} id="view_outputFilterViewInstance"
class="ui-icon ui-icon-circle-close ui-output"></a></th>
- <th class="notActive"><div class="view-wrapper">{{view
view.durationFilterView valueBinding="controller.filterObject.duration"
viewName="durationFilterViewInstance"}}</div> <a href="#" {{action
"clearFilterButtonClick" target="view"}} id="view_durationFilterViewInstance"
class="ui-icon ui-icon-circle-close ui-duration"></a></th>
- <th class="notActive"><div class="view-wrapper">{{view
view.rundateSelectView selectionBinding="controller.filterObject.runDate"
viewName="rundateSelectViewInstance"}}</div> <a href="#" {{action
"clearFilterButtonClick" target="view"}} id="view_rundateSelectViewInstance"
class="ui-icon ui-icon-circle-close ui-rundate"></a><input
id="custom_rundate_filter" type="hidden"></th>
+ <th>{{view view.appIdFilterView}}</th>
+ <th>{{view view.nameFilterView}}</th>
+ <th>{{view view.typeFilterView}}</th>
+ <th>{{view view.userFilterView}}</th>
+ <th>{{view view.jobsFilterView}}</th>
+ <th>{{view view.inputFilterView}}</th>
+ <th>{{view view.outputFilterView}}</th>
+ <th>{{view view.durationFilterView}}</th>
+ <th>{{view view.runDateFilterView}}</th>
</tr>
</thead>
<tbody>
Modified:
incubator/ambari/trunk/ambari-web/app/templates/main/host/component_filter.hbs
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/templates/main/host/component_filter.hbs?rev=1440747&r1=1440746&r2=1440747&view=diff
==============================================================================
---
incubator/ambari/trunk/ambari-web/app/templates/main/host/component_filter.hbs
(original)
+++
incubator/ambari/trunk/ambari-web/app/templates/main/host/component_filter.hbs
Thu Jan 31 00:26:13 2013
@@ -16,7 +16,6 @@
* limitations under the License.
}}
-<div {{bindAttr class="view.btnGroupClass"}}>
<button class="btn btn-info single-btn-group" {{action "clickFilterButton"
target="view"}}>
Components <span class="caret"></span>
</button>
@@ -68,8 +67,7 @@
</ul>
</li>
<li>
- <button class="btn" {{action "closeFilters"
target="view"}}>Cancel</button>
+ <button class="btn" {{action "closeFilter"
target="view"}}>Cancel</button>
<button class="btn btn-primary" {{action "applyFilter"
target="view"}}>Apply</button>
</li>
- </ul>
-</div>
\ No newline at end of file
+ </ul>
\ No newline at end of file
Modified: incubator/ambari/trunk/ambari-web/app/views/common/filter_view.js
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/views/common/filter_view.js?rev=1440747&r1=1440746&r2=1440747&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/views/common/filter_view.js (original)
+++ incubator/ambari/trunk/ambari-web/app/views/common/filter_view.js Thu Jan
31 00:26:13 2013
@@ -16,20 +16,42 @@
* limitations under the License.
*/
+/**
+ * Wrapper View for all filter components. Layout template and common actions
are located inside of it.
+ * Logic specific for data component(input, select, or custom multi select,
which fire any changes on interface) are
+ * located in inner view - <code>filterView</code>.
+ *
+ * If we want to have input filter, put <code>textFieldView</code> to it.
+ * All inner views implemented below this view.
+ * @type {*}
+ */
var wrapperView = Ember.View.extend({
classNames: ['view-wrapper'],
- layout: Ember.Handlebars.compile('<a href="#" {{action "clearFilter"
target="view"}} class="ui-icon ui-icon-circle-close ui-name"></a> {{yield}}'),
+ layout: Ember.Handlebars.compile('<a href="#" {{action "clearFilter"
target="view"}} class="ui-icon ui-icon-circle-close"></a> {{yield}}'),
template: Ember.Handlebars.compile('{{#if view.fieldId}}<input type="hidden"
id="{{unbound view.fieldId}}" value="" />{{/if}} {{view view.filterView}}'),
value: null,
+ /**
+ * If this field is exists we dynamically create hidden input element and
set value there.
+ * Used for some cases, where this values will be used outside of component
+ */
+ fieldId: null,
+
clearFilter: function(){
this.set('value', this.get('emptyValue'));
return false;
},
+ /**
+ * Use to determine whether filter is clear or not. Also when we want to set
empty value
+ */
emptyValue: '',
+ /**
+ * Whether our <code>value</code> is empty or not
+ * @return {Boolean}
+ */
isEmpty: function(){
if(this.get('value') === null){
return true;
@@ -37,6 +59,11 @@ var wrapperView = Ember.View.extend({
return this.get('value').toString() === this.get('emptyValue').toString();
},
+ /**
+ * Show/Hide <code>Clear filter</code> button.
+ * Also this method updates computed field related to <code>fieldId</code>
if it exists.
+ * Call <code>onChangeValue</code> callback when everything is done.
+ */
showClearFilter: function(){
if(!this.get('parentNode')){
return;
@@ -62,13 +89,14 @@ var wrapperView = Ember.View.extend({
},
+ /**
+ * Filter components is located here. Should be redefined
+ */
filterView: Em.View,
- init: function(){
- this.set('value', this.get('emptyValue'));
- this._super();
- },
-
+ /**
+ * Update class of parentNode(hide clear filter button) on page load
+ */
didInsertElement: function(){
var parent = this.$().parent();
this.set('parentNode', parent);
@@ -76,62 +104,45 @@ var wrapperView = Ember.View.extend({
}
});
+/**
+ * Simple input control for wrapperView
+ */
var textFieldView = Ember.TextField.extend({
type:'text',
placeholder: 'Any',
valueBinding: "parentView.value"
});
+/**
+ * Simple multiselect control for wrapperView.
+ * Used to render blue button and popup, which opens on button click.
+ * All content related logic should be implemented manually outside of it
+ */
var componentFieldView = Ember.View.extend({
- templateName: require('templates/main/host/component_filter'),
classNames: ['btn-group'],
- classNameBindings: ['open'],
- multiple: true,
+ classNameBindings: ['isFilterOpen:open:'],
+ /**
+ * Whether popup is shown or not
+ */
isFilterOpen: false,
- btnGroupClass:function () {
- return this.get('isFilterOpen') ? 'btn-group open' : 'btn-group';
- }.property('isFilterOpen'),
-
+ /**
+ * We have <code>value</code> property similar to inputs <code>value</code>
property
+ */
valueBinding: 'parentView.value',
- masterComponentsBinding: 'controller.masterComponents',
- slaveComponentsBinding: 'controller.slaveComponents',
- clientComponentsBinding: 'controller.clientComponents',
-
- masterComponentsChecked:false,
- toggleMasterComponents:function () {
- this.get('masterComponents').setEach('checkedForHostFilter',
this.get('masterComponentsChecked'));
- }.observes('masterComponentsChecked'),
-
- slaveComponentsChecked:false,
- toggleSlaveComponents:function () {
- this.get('slaveComponents').setEach('checkedForHostFilter',
this.get('slaveComponentsChecked'));
- }.observes('slaveComponentsChecked'),
-
- clientComponentsChecked: false,
- toggleClientComponents: function() {
- this.get('clientComponents').setEach('checkedForHostFilter',
this.get('clientComponentsChecked'));
- }.observes('clientComponentsChecked'),
/**
* Clear filter to initial state
*/
- clearFilter:function() {
- this.set('masterComponentsChecked', false);
- this.set('slaveComponentsChecked', false);
- this.set('clientComponentsChecked', false);
-
- this.get('masterComponents').setEach('checkedForHostFilter', false);
- this.get('slaveComponents').setEach('checkedForHostFilter', false);
- this.get('clientComponents').setEach('checkedForHostFilter', false);
- this.set('value', []);
+ clearFilter: function(){
+ this.set('value', '');
},
/**
* Onclick handler for <code>cancel filter</code> button
*/
- closeFilters:function () {
+ closeFilter:function () {
$(document).unbind('click');
this.set('isFilterOpen', false);
},
@@ -140,20 +151,7 @@ var componentFieldView = Ember.View.exte
* Onclick handler for <code>apply filter</code> button
*/
applyFilter:function() {
- this.closeFilters();
-
- var chosenComponents = [];
-
- this.get('masterComponents').filterProperty('checkedForHostFilter',
true).forEach(function(item){
- chosenComponents.push(item.get('displayName'));
- });
- this.get('slaveComponents').filterProperty('checkedForHostFilter',
true).forEach(function(item){
- chosenComponents.push(item.get('displayName'));
- });
- this.get('clientComponents').filterProperty('checkedForHostFilter',
true).forEach(function(item){
- chosenComponents.push(item.get('displayName'));
- });
- this.set('value', chosenComponents);
+ this.closeFilter();
},
/**
@@ -175,21 +173,38 @@ var componentFieldView = Ember.View.exte
firstClick = false;
});
}
- },
-
- didInsertElement:function () {
- if (this.get('controller.comeWithFilter')) {
- this.applyFilter();
- this.set('controller.comeWithFilter', false);
- } else {
- this.clearFilter();
- }
}
});
+/**
+ * Simple select control for wrapperView
+ */
+var selectFieldView = Ember.Select.extend({
+ selectionBinding: 'parentView.value',
+ contentBinding: 'parentView.content'
+});
+
+/**
+ * Result object, which will be accessible outside
+ * @type {Object}
+ */
module.exports = {
+ /**
+ * You can access wrapperView outside
+ */
wrapperView : wrapperView,
+ /**
+ * And also controls views if need it
+ */
+ textFieldView : textFieldView,
+ selectFieldView: selectFieldView,
+ componentFieldView: componentFieldView,
+
+ /**
+ * Quick create input filters
+ * @param config parameters of <code>wrapperView</code>
+ */
createTextView : function(config){
config.fieldType = config.fieldType || 'input-medium';
@@ -199,9 +214,12 @@ module.exports = {
return wrapperView.extend(config);
},
+
+ /**
+ * Quick create multiSelect filters
+ * @param config parameters of <code>wrapperView</code>
+ */
createComponentView : function(config){
- config.filterView = componentFieldView;
- config.emptyValue = [];
config.clearFilter = function(){
this.forEachChildView(function(item){
if(item.clearFilter){
@@ -212,5 +230,20 @@ module.exports = {
};
return wrapperView.extend(config);
+ },
+
+ /**
+ * Quick create select filters
+ * @param config parameters of <code>wrapperView</code>
+ */
+ createSelectView: function(config){
+
+ config.fieldType = config.fieldType || 'input-medium';
+ config.filterView = selectFieldView.extend({
+ classNames : [ config.fieldType ]
+ });
+ config.emptyValue = 'Any';
+
+ return wrapperView.extend(config);
}
};
\ No newline at end of file
Modified: incubator/ambari/trunk/ambari-web/app/views/main/apps_view.js
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/views/main/apps_view.js?rev=1440747&r1=1440746&r2=1440747&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/views/main/apps_view.js (original)
+++ incubator/ambari/trunk/ambari-web/app/views/main/apps_view.js Thu Jan 31
00:26:13 2013
@@ -17,323 +17,221 @@
*/
var App = require('app');
+var filters = require('views/common/filter_view');
App.MainAppsView = Em.View.extend({
- templateName:require('templates/main/apps'),
-
- /**
- * List of users
- */
- users:function () {
- return this.get('controller.content').mapProperty("userName").uniq();
- }.property('controller.content.length'),
+ templateName: require('templates/main/apps'),
//Pagination left/right buttons css class
- paginationLeft : Ember.View.extend({
+ paginationLeft: Ember.View.extend({
tagName: 'a',
template: Ember.Handlebars.compile('<i class="icon-arrow-left"></i>'),
classNameBindings: ['class'],
- class:"",
- calculateClass: function(){
- if(parseInt(this.get("controller.paginationObject.startIndex"))>1){
- this.set("class","paginate_previous");
- }else{
- this.set("class","paginate_disabled_previous");
+ class: "",
+ calculateClass: function () {
+ if (parseInt(this.get("controller.paginationObject.startIndex")) > 1) {
+ this.set("class", "paginate_previous");
+ } else {
+ this.set("class", "paginate_disabled_previous");
}
}.observes("controller.paginationObject"),
- click: function(event){
- if(this.class == "paginate_previous"){
- var
startIndex=parseInt(this.get("controller.paginationObject.startIndex"))-1;
- var
showRows=parseInt(this.get("controller.filterObject.iDisplayLength"));
- var startDisplayValue = Math.max(0,startIndex-showRows);
+ click: function (event) {
+ if (this.class == "paginate_previous") {
+ var startIndex =
parseInt(this.get("controller.paginationObject.startIndex")) - 1;
+ var showRows =
parseInt(this.get("controller.filterObject.iDisplayLength"));
+ var startDisplayValue = Math.max(0, startIndex - showRows);
this.set("controller.filterObject.iDisplayStart", startDisplayValue);
}
}
}),
- paginationRight : Ember.View.extend({
+ paginationRight: Ember.View.extend({
tagName: 'a',
template: Ember.Handlebars.compile('<i class="icon-arrow-right"></i>'),
classNameBindings: ['class'],
- class:"",
- calculateClass: function(){
-
if((parseInt(this.get("controller.paginationObject.endIndex"))+1)<parseInt(this.get("controller.paginationObject.iTotalDisplayRecords"))){
- this.set("class","paginate_next");
- }else{
- this.set("class","paginate_disabled_next");
+ class: "",
+ calculateClass: function () {
+ if ((parseInt(this.get("controller.paginationObject.endIndex")) + 1) <
parseInt(this.get("controller.paginationObject.iTotalDisplayRecords"))) {
+ this.set("class", "paginate_next");
+ } else {
+ this.set("class", "paginate_disabled_next");
}
}.observes("controller.paginationObject"),
- click: function(event){
- if(this.class == "paginate_next"){
+ click: function (event) {
+ if (this.class == "paginate_next") {
var startDisplayValue =
parseInt(this.get("controller.paginationObject.endIndex"));
this.set("controller.filterObject.iDisplayStart", startDisplayValue);
}
}
}),
- wrapSorting:Ember.View.extend({
+ /**
+ * View for RunPerPage select component
+ */
+ runPerPageSelectView: Em.Select.extend({
+
+ selected: '10',
+ content: ['10', '25', '50', '100']
+ }),
+
+ wrapSorting: Ember.View.extend({
tagName: 'tr'
}),
sortingColumns: Ember.View.extend({
tagName: 'th',
- classNameBindings: ['class','widthClass'],
- class:"sorting",
- widthClass:"",
+ classNameBindings: ['class', 'widthClass'],
+ class: "sorting",
+ widthClass: "",
content: null,
- didInsertElement:function(){
- this.set("widthClass","col"+this.content.index);
+ didInsertElement: function () {
+ this.set("widthClass", "col" + this.content.index);
},
- click: function(event){
+ click: function (event) {
console.log(this.class);
- if(this.class == "sorting"){
+ if (this.class == "sorting") {
this.resetSortClass();
- this.setControllerObj(this.content.index,"ASC");
+ this.setControllerObj(this.content.index, "ASC");
this.set("class", "sorting_asc");
- }else if(this.class == "sorting_asc"){
- this.setControllerObj(this.content.index,"DESC");
+ } else if (this.class == "sorting_asc") {
+ this.setControllerObj(this.content.index, "DESC");
this.set("class", "sorting_desc");
- }else if(this.class == "sorting_desc"){
- this.setControllerObj("","");
+ } else if (this.class == "sorting_desc") {
+ this.setControllerObj("", "");
this.set("class", "sorting");
}
},
- resetSortClass:function(){
-
this.get("parentView.childViews").map(function(a,e){a.get("childViews")[0].set("class","sorting")});
+ resetSortClass: function () {
+ this.get("parentView.childViews").map(function (a, e) {
+ a.get("childViews")[0].set("class", "sorting")
+ });
},
- setControllerObj:function(col,dir){
+ setControllerObj: function (col, dir) {
this.set("controller.filterObject.iSortCol_0", col);
this.set("controller.filterObject.sSortDir_0", dir);
}
}),
/**
- * Filter-field for AppId
+ * Filter-field for Search
*/
- appidFilterView:Em.TextField.extend({
- classNames:['input-small-app'],
- type:'text',
- placeholder:'Any ID',
- elementId:'appid_filter',
- filtering:function () {
- if (this.get('value') == '') {
- this.$().closest('th').addClass('notActive');
- }
- else {
- this.$().closest('th').removeClass('notActive');
- }
- }.observes('value')
+ appSearchThrough: Em.TextField.extend({
+ classNames: ['input-medium'],
+ type: 'text',
+ placeholder: 'Search'
}),
/**
- * Filter-field for Search
+ * Filter-field for App ID.
+ * Based on <code>filters</code> library
*/
- appSearchThrough:Em.TextField.extend({
- classNames:['input-medium'],
- type:'text',
- placeholder:'Search',
- filtering:function () {
- if (this.get('value') == '') {
- this.$().closest('th').addClass('notActive');
- }
- else {
- this.$().closest('th').removeClass('notActive');
- }
- }.observes('value')
+ appIdFilterView: filters.createTextView({
+ valueBinding: "controller.filterObject.sSearch_0"
}),
/**
- * Filter-field for name
+ * Filter-field for name.
+ * Based on <code>filters</code> library
*/
- nameFilterView:Em.TextField.extend({
- classNames:['input-small'],
- type:'text',
- placeholder:'Any Name',
- filtering:function () {
- if (this.get('value') == '') {
- this.$().closest('th').addClass('notActive');
- }
- else {
- this.$().closest('th').removeClass('notActive');
- }
- }.observes('value')
+ nameFilterView: filters.createTextView({
+ valueBinding: "controller.filterObject.sSearch_1",
+ fieldType: 'input-small'
}),
/**
- * dataTable filter views
+ * Filter-field for type.
+ * Based on <code>filters</code> library
*/
- typeSelectView:Em.Select.extend({
- classNames:['input-small'],
- selected:'Any',
- content:['Any', 'Pig', 'Hive', 'MapReduce'],
- change:function (event) {
- if (this.get('selection') === 'Any') {
- this.$().closest('th').addClass('notActive');
- }
- else {
- this.$().closest('th').removeClass('notActive');
- }
- }
+ typeFilterView: filters.createSelectView({
+ fieldType: 'input-small',
+ valueBinding: "controller.filterObject.runType",
+ content: ['Any', 'Pig', 'Hive', 'MapReduce']
}),
+
/**
- * dataTable filter views
+ * Filter-list for User.
+ * Based on <code>filters</code> library
*/
- runPerPageSelectView:Em.Select.extend({
+ userFilterView: filters.createComponentView({
+ /**
+ * Inner FilterView. Used just to render component. Value bind to
<code>mainview.value</code> property
+ * Base methods was implemented in <code>filters.componentFieldView</code>
+ */
+ filterView: filters.componentFieldView.extend({
+ templateName:require('templates/main/apps/user_filter'),
- selected:'10',
- content:['10', '25', '50', '100']
- }),
- /**
- * Filter-list for User
- */
- userFilterView:Em.View.extend({
- classNames:['btn-group'],
- classNameBindings:['open'],
- multiple:true,
- open:false,
- users:function () {
- var users = [];
- for (var i = 0; i < this.get('parentView').get('users').length; i++)
- users.push(Ember.Object.create({
- name:this.get('parentView').get('users')[i],
- checked:false
- }));
- return users;
- }.property('parentView.users'),
- templateName:require('templates/main/apps/user_filter'),
- allComponentsChecked:false,
- toggleAllComponents:function () {
- var checked = this.get('allComponentsChecked');
- this.get('users').forEach(function (item) {
- item.set('checked', checked);
- });
- }.observes('allComponentsChecked'),
- clickFilterButton:function (event) {
- this.set('open', !this.get('open'));
- },
- clearFilter:function (self) {
- self.set('allComponentsChecked', true);
- self.set('allComponentsChecked', false);
- jQuery('#user_filter').val([]);
-
self.get('parentView').get('controller.filterObject').set("sSearch_3","");
- jQuery('#user_filter').closest('th').addClass('notActive');
- },
- closeFilter:function () {
- this.set('open', false);
- },
- applyFilter:function () {
- var chosenUsers = new Array();
- this.set('open', !this.get('open'));
- this.get('users').forEach(function (item) {
- if (item.get('checked')) chosenUsers.push(item.get('name'));
- });
+ usersBinding: 'controller.users',
- /**
- * Set filterObject
- */
-
this.get('parentView').get('controller.filterObject').set("sSearch_3",chosenUsers)
-
- jQuery('#user_filter').val(chosenUsers);
- if (chosenUsers.length == 0) {
- this.$().closest('th').addClass('notActive');
- }
- else {
- this.$().closest('th').removeClass('notActive');
+ allComponentsChecked:false,
+ toggleAllComponents:function () {
+ var checked = this.get('allComponentsChecked');
+ this.get('users').setEach('checked', checked);
+ }.observes('allComponentsChecked'),
+
+ clearFilter:function() {
+ this.set('allComponentsChecked', false);
+
+ this.get('users').setEach('checked', false);
+
+ this._super();
+ },
+
+ applyFilter:function() {
+ this._super();
+
+ var chosenUsers = this.get('users').filterProperty('checked',
true).mapProperty('name');
+ this.set('value', chosenUsers.toString());
}
- }
+ }),
+
+ valueBinding: 'controller.filterObject.sSearch_3'
}),
/**
- * Filter-field for jobs
+ * Filter-field for jobs.
+ * Based on <code>filters</code> library
*/
- jobsFilterView:Em.TextField.extend({
- classNames:['input-mini'],
- type:'text',
- placeholder:'Any ',
- elementId:'jobs_filter',
- filtering:function () {
- if (this.get('value') == '') {
- this.$().closest('th').addClass('notActive');
- }
- else {
- this.$().closest('th').removeClass('notActive');
- }
- //this.get('parentView').get('applyFilter')(this.get('parentView'), 6);
- }.observes('value')
+ jobsFilterView: filters.createTextView({
+ fieldType: 'input-super-mini',
+ valueBinding: "controller.filterObject.jobs"
}),
-
/**
- * Filter-field for Input
+ * Filter-field for Input.
+ * Based on <code>filters</code> library
*/
- inputFilterView:Em.TextField.extend({
- classNames:['input-mini'],
- type:'text',
- placeholder:'Any ',
- elementId:'input_filter',
- filtering:function () {
- if (this.get('value') == '') {
- this.$().closest('th').addClass('notActive');
- }
- else {
- this.$().closest('th').removeClass('notActive');
- }
- }.observes('value')
+ inputFilterView: filters.createTextView({
+ fieldType: 'input-super-mini',
+ valueBinding: "controller.filterObject.input"
}),
/**
- * Filter-field for Output
+ * Filter-field for Output.
+ * Based on <code>filters</code> library
*/
- outputFilterView:Em.TextField.extend({
- classNames:['input-mini'],
- type:'text',
- placeholder:'Any ',
- elementId:'output_filter',
- filtering:function () {
- if (this.get('value') == '') {
- this.$().closest('th').addClass('notActive');
- }
- else {
- this.$().closest('th').removeClass('notActive');
- }
- }.observes('value')
+ outputFilterView: filters.createTextView({
+ fieldType: 'input-super-mini',
+ valueBinding: "controller.filterObject.output"
}),
/**
- * Filter-field for Duration
+ * Filter-field for Duration.
+ * Based on <code>filters</code> library
*/
- durationFilterView:Em.TextField.extend({
- classNames:['input-mini'],
- type:'text',
- placeholder:'Any ',
- elementId:'duration_filter',
- filtering:function () {
- if (this.get('value') == '') {
- this.$().closest('th').addClass('notActive');
- }
- else {
- this.$().closest('th').removeClass('notActive');
- }
- }.observes('value')
+ durationFilterView: filters.createTextView({
+ fieldType: 'input-super-mini',
+ valueBinding: "controller.filterObject.duration"
}),
/**
- * Filter-field for RunDate
+ * Filter-field for RunDate.
+ * Based on <code>filters</code> library
*/
- rundateSelectView:Em.Select.extend({
- content:['Any', 'Past 1 Day', 'Past 2 Days', 'Past 7 Days', 'Past 14
Days', 'Past 30 Days'],
- selected:'Any',
- classNames:['input-medium'],
- elementId:'rundate_filter',
- change:function (event) {
- if (this.get('selection') == 'Any') {
- this.$().closest('th').addClass('notActive');
- }
- else {
- this.$().closest('th').removeClass('notActive');
- }
- }
+ runDateFilterView: filters.createSelectView({
+ fieldType: 'input-medium',
+ valueBinding: "controller.filterObject.runDate",
+ content: ['Any', 'Past 1 Day', 'Past 2 Days', 'Past 7 Days', 'Past 14
Days', 'Past 30 Days']
}),
/**
* Onclick handler for Show All/Filtered buttons
*/
- clickViewType:function (event) {
+ clickViewType: function (event) {
this.set("controller.filterObject.viewTypeClickEvent", true);
- if($(event.target).hasClass("filtered")){
+ if ($(event.target).hasClass("filtered")) {
this.set("controller.filterObject.viewType", "filtered");
- }else{
+ } else {
this.set("controller.filterObject.allFilterActivated", true);
this.set("controller.filterObject.viewType", "all");
}
@@ -341,7 +239,7 @@ App.MainAppsView = Em.View.extend({
/**
*
*/
- onChangeViewType:function () {
+ onChangeViewType: function () {
var tmpViewType = this.get('controller.filterObject.viewType');
var filterButtons = $("#filter_buttons").children();
filterButtons.each(function (index, element) {
@@ -358,9 +256,9 @@ App.MainAppsView = Em.View.extend({
*
* @param event
*/
- clearFilters:function (event) {
+ clearFilters: function (event) {
this._childViews.forEach(function (item) {
- if(item.get("viewName") === "runPerPageSelectView"){
+ if (item.get("viewName") === "runPerPageSelectView") {
return "";
}
if (item.get('tagName') === 'input') {
@@ -375,70 +273,52 @@ App.MainAppsView = Em.View.extend({
}
});
},
- /**
- * Clear selected filter
- * @param event
- */
- clearFilterButtonClick:function (event) {
- var viewName = event.target.id.replace('view_', '');
- var elementId = this.get(viewName).get('elementId');
- if (this.get(viewName).get('tagName') === 'input') {
- this.get(viewName).set('value', '');
- }
- if (this.get(viewName).get('tagName') === 'select') {
- this.get(viewName).set('value', 'Any');
- this.get(viewName).change();
- }
- if (this.get(viewName).get('multiple')) {
- this.get(viewName).get('clearFilter')(this.get(viewName));
- }
- },
/**
* This Container View is used to render static table row(appTableRow) and
additional dynamic content
*/
- containerRow:Em.ContainerView.extend({
+ containerRow: Em.ContainerView.extend({
/**
* Unique row id
*/
- id:function () {
+ id: function () {
return this.get('run.id');
}.property("run.id"),
/**
* Show/hide additional content appropriated for this row
*/
- expandToggle:function () {
+ expandToggle: function () {
//App.router.get('mainAppsItemController').set('jobsLoaded', false);
App.router.get('mainAppsItemController').set('content', this.get('run'));
App.ModalPopup.show({
- classNames:['big-modal'],
- header:Em.I18n.t('apps.dagCharts.popup'),
- bodyClass:App.MainAppsItemView.extend({
- controllerBinding:'App.router.mainAppsItemController'
+ classNames: ['big-modal'],
+ header: Em.I18n.t('apps.dagCharts.popup'),
+ bodyClass: App.MainAppsItemView.extend({
+ controllerBinding: 'App.router.mainAppsItemController'
}),
- onPrimary:function () {
+ onPrimary: function () {
this.hide();
},
- secondary:null
+ secondary: null
});
}
}),
/**
* Table-row view
*/
- appTableRow:Em.View.extend({
- templateName:require('templates/main/apps/list_row'),
- classNames:['app-table-row'],
- tagName:"tr",
- mouseEnter:function (event, view) {
+ appTableRow: Em.View.extend({
+ templateName: require('templates/main/apps/list_row'),
+ classNames: ['app-table-row'],
+ tagName: "tr",
+ mouseEnter: function (event, view) {
$(event.currentTarget).addClass("hover")
},
- mouseLeave:function (event, view) {
+ mouseLeave: function (event, view) {
$(event.currentTarget).removeClass("hover");
},
- click:function (event, view) {
+ click: function (event, view) {
this.get('parentView').expandToggle();
}
Modified: incubator/ambari/trunk/ambari-web/app/views/main/host.js
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/views/main/host.js?rev=1440747&r1=1440746&r2=1440747&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/views/main/host.js (original)
+++ incubator/ambari/trunk/ambari-web/app/views/main/host.js Thu Jan 31
00:26:13 2013
@@ -130,18 +130,30 @@ App.MainHostView = Em.View.extend({
}),
+ /**
+ * Filter view for name column
+ * Based on <code>filters</code> library
+ */
nameFilterView: filters.createTextView({
onChangeValue: function(){
this.get('parentView').updateFilter(8, this.get('value'));
}
}),
+ /**
+ * Filter view for ip column
+ * Based on <code>filters</code> library
+ */
ipFilterView: filters.createTextView({
onChangeValue: function(){
this.get('parentView').updateFilter(2, this.get('value'));
}
}),
+ /**
+ * Filter view for Cpu column
+ * Based on <code>filters</code> library
+ */
cpuFilterView: filters.createTextView({
fieldType: 'input-mini',
fieldId: 'cpu_filter',
@@ -150,6 +162,10 @@ App.MainHostView = Em.View.extend({
}
}),
+ /**
+ * Filter view for LoadAverage column
+ * Based on <code>filters</code> library
+ */
loadAvgFilterView: filters.createTextView({
fieldType: 'input-mini',
fieldId: 'load_avg_filter',
@@ -158,6 +174,10 @@ App.MainHostView = Em.View.extend({
}
}),
+ /**
+ * Filter view for Ram column
+ * Based on <code>filters</code> library
+ */
ramFilterView: filters.createTextView({
fieldType: 'input-mini',
fieldId: 'ram_filter',
@@ -166,7 +186,95 @@ App.MainHostView = Em.View.extend({
}
}),
+ /**
+ * Filter view for HostComponents column
+ * Based on <code>filters</code> library
+ */
componentsFilterView: filters.createComponentView({
+ /**
+ * Inner FilterView. Used just to render component. Value bind to
<code>mainview.value</code> property
+ * Base methods was implemented in <code>filters.componentFieldView</code>
+ */
+ filterView: filters.componentFieldView.extend({
+ templateName: require('templates/main/host/component_filter'),
+
+ /**
+ * Next three lines bind data to this view
+ */
+ masterComponentsBinding: 'controller.masterComponents',
+ slaveComponentsBinding: 'controller.slaveComponents',
+ clientComponentsBinding: 'controller.clientComponents',
+
+ /**
+ * Checkbox for quick selecting/deselecting of master components
+ */
+ masterComponentsChecked:false,
+ toggleMasterComponents:function () {
+ this.get('masterComponents').setEach('checkedForHostFilter',
this.get('masterComponentsChecked'));
+ }.observes('masterComponentsChecked'),
+
+ /**
+ * Checkbox for quick selecting/deselecting of slave components
+ */
+ slaveComponentsChecked:false,
+ toggleSlaveComponents:function () {
+ this.get('slaveComponents').setEach('checkedForHostFilter',
this.get('slaveComponentsChecked'));
+ }.observes('slaveComponentsChecked'),
+
+ /**
+ * Checkbox for quick selecting/deselecting of client components
+ */
+ clientComponentsChecked: false,
+ toggleClientComponents: function() {
+ this.get('clientComponents').setEach('checkedForHostFilter',
this.get('clientComponentsChecked'));
+ }.observes('clientComponentsChecked'),
+
+ /**
+ * Clear filter.
+ * Called by parent view, when user clicks on <code>x</code>
button(clear button)
+ */
+ clearFilter:function() {
+ this.set('masterComponentsChecked', false);
+ this.set('slaveComponentsChecked', false);
+ this.set('clientComponentsChecked', false);
+
+ this.get('masterComponents').setEach('checkedForHostFilter', false);
+ this.get('slaveComponents').setEach('checkedForHostFilter', false);
+ this.get('clientComponents').setEach('checkedForHostFilter', false);
+
+ this._super();
+ },
+
+ /**
+ * Onclick handler for <code>Apply filter</code> button
+ */
+ applyFilter:function() {
+ this._super();
+
+ var chosenComponents = [];
+
+ this.get('masterComponents').filterProperty('checkedForHostFilter',
true).forEach(function(item){
+ chosenComponents.push(item.get('displayName'));
+ });
+ this.get('slaveComponents').filterProperty('checkedForHostFilter',
true).forEach(function(item){
+ chosenComponents.push(item.get('displayName'));
+ });
+ this.get('clientComponents').filterProperty('checkedForHostFilter',
true).forEach(function(item){
+ chosenComponents.push(item.get('displayName'));
+ });
+ this.set('value', chosenComponents.toString());
+ },
+
+ didInsertElement:function () {
+ if (this.get('controller.comeWithFilter')) {
+ this.applyFilter();
+ this.set('controller.comeWithFilter', false);
+ } else {
+ this.clearFilter();
+ }
+ }
+
+ }),
fieldId: 'components_filter',
onChangeValue: function(){
this.get('parentView').updateFilter(9);