You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ma...@apache.org on 2013/02/04 03:24:02 UTC

svn commit: r1442010 [27/29] - in /incubator/ambari/branches/branch-1.2: ./ ambari-agent/ ambari-agent/conf/unix/ ambari-agent/src/examples/ ambari-agent/src/main/puppet/modules/hdp-ganglia/files/ ambari-agent/src/main/puppet/modules/hdp-ganglia/manife...

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/apps_view.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/apps_view.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/apps_view.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/apps_view.js Mon Feb  4 02:23:55 2013
@@ -17,887 +17,306 @@
  */
 
 var App = require('app');
-var date = require('utils/date');
-var validator = require('utils/validator');
-var misc = require('utils/misc');
+var filters = require('views/common/filter_view');
 
 App.MainAppsView = Em.View.extend({
-  templateName:require('templates/main/apps'),
-  /**
-   * List of runs
-   */
-  content:function () {
-    return this.get('controller.content');
-  }.property('controller.content'),
-
-  /**
-   * Choose view type for apps list:
-   * all - show all runs
-   * filtered - show only filtered runs
-   * starred - show only filtered runs with stars selected
-   */
-  viewType : 'all',
-  defaultViewType: 'all',
-  /**
-   * List of users
-   */
-  users: function() {
-    var result = [];
-    this.get('content').forEach(function(item) {
-       result.push(item.get('userName'));
-    });
-    return jQuery.unique(result);
-  }.property('content'),
-  /**
-   * jQuery dataTable object
-   */
-  oTable:null,
-  /**
-   * jQuery collection of stars icons (in dataTables). Saved here for easy "turning off"
-   */
-  smallStarsIcons: null,
-
-  stared: function() {
-    return this.get('controller.staredRunsLength');
-  }.property('controller.staredRunsLength'),
-  /**
-   * Count of filtered runs
-   */
-  filtered: null,
-  /**
-   * Flag for avgData
-   */
-  whatAvgShow: true, // true - for filtered data, false - for starred
-  /**
-   * avg data for display. Can be stared or filtered. Based on whatAvgShow
-   */
-  avgData: function() {
-    if (this.get('whatAvgShow')) {
-      return this.get('filteredData');
-    }
-    else {
-      return this.get('staredData');
-    }
-  }.property('filteredData', 'staredData', 'whatAvgShow'),
-  /**
-   * Avg data of filtered runs
-   */
-  filteredData: function() {
-    return this.getAvgData(this.get('controller.content').filterProperty('isFiltered', true));
-  }.property('controller.filteredRunsLength'),
-  /**
-   * Avg data of stared runs
-   */
-  staredData: function() {
-    return this.getAvgData(this.get('controller.content').filterProperty('isStared', true));
-  }.property('controller.staredRunsLength'),
-  setFilteredRuns: function(data) {
+  templateName: require('templates/main/apps'),
 
-  },
-  /**
-   * Common method for calculation avg data (filtered or stored - based on param content)
-   * @param content data-array
-   * @return {*} array with calculated data
-   */
-  getAvgData: function(content) {
-    var avgJobs = 0.0, minJobs = 0, maxJobs = 0, avgInput = 0, minInput = 0, maxInput = 0, avgOutput = 0, minOutput = 0, maxOutput = 0, avgDuration = 0.0, minDuration = 0, maxDuration = 0, oldest = 0, youngest = 0;
-    if (content.length > 0) {
-      minJobs = content[0].get('numJobsTotal');
-      minInput = content[0].get('input');
-      minOutput = content[0].get('output');
-      oldest = content[0].get('lastUpdateTime');
-      youngest = content[0].get('lastUpdateTime');
-      minDuration = date.dateUnformatInterval(content[0].get('duration'));
-    }
-    content.forEach(function(item) {
-      avgJobs += item.get('numJobsTotal') / content.length;
-      avgInput += item.get('input') / content.length;
-      avgOutput += item.get('output') / content.length;
-      avgDuration += date.dateUnformatInterval(item.get('duration')) / content.length;
-      if (item.get('numJobsTotal') < minJobs) {
-        minJobs = item.get('numJobsTotal');
-      }
-      else {
-        if (item.get('numJobsTotal') > maxJobs) {
-          maxJobs = item.get('numJobsTotal');
-        }
-      }
-      if (item.get('input') < minInput) {
-        minInput = item.get('input');
-      }
-      else {
-        if (item.get('input') > maxInput) {
-          maxInput = item.get('input');
-        }
-      }
-      if (item.get('output') < minOutput) {
-        minOutput = item.get('output');
-      }
-      else {
-        if (item.get('output') > maxOutput) {
-          maxOutput = item.get('output');
-        }
-      }
-      if (date.dateUnformatInterval(item.get('duration')) < minDuration) {
-        minDuration = date.dateUnformatInterval(item.get('duration'));
-      }
-      else {
-        if (date.dateUnformatInterval(item.get('duration')) > maxDuration) {
-          maxDuration = date.dateUnformatInterval(item.get('duration'));
-        }
-      }
-      if (item.get('lastUpdateTime') < oldest) {
-        oldest = item.get('lastUpdateTime');
+  //Pagination left/right buttons css class
+  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");
       }
-      else {
-        if (item.get('lastUpdateTime') > youngest) {
-          youngest = item.get('lastUpdateTime');
-        }
+    }.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);
+        this.set("controller.filterObject.iDisplayStart", startDisplayValue);
       }
-    });
-    if (oldest != 0) {
-      d = new Date(oldest*1);
-      oldest = d.toDateString();
-    }
-    else {
-      oldest = '0000-00-00';
-    }
-    if (youngest != 0) {
-      d = new Date(youngest*1);
-      youngest = d.toDateString();
-    }
-    else {
-      youngest = '0000-00-00';
     }
-    avgInput = misc.formatBandwidth(avgInput);
-    minInput = misc.formatBandwidth(minInput);
-    maxInput = misc.formatBandwidth(maxInput);
-    avgOutput = misc.formatBandwidth(avgOutput);
-    minOutput = misc.formatBandwidth(minOutput);
-    maxOutput = misc.formatBandwidth(maxOutput);
-    ret = {
-      'jobs': {
-        'avg': avgJobs.toFixed(2),
-        'min': minJobs,
-        'max': maxJobs
-      },
-      'input': {
-        'avg': avgInput,
-        'min': minInput,
-        'max': maxInput
-      },
-      'output': {
-        'avg': avgOutput,
-        'min': minOutput,
-        'max': maxOutput
-      },
-      'duration': {
-        'avg': date.timingFormat(Math.round(avgDuration)),
-        'min': date.timingFormat(minDuration),
-        'max': date.timingFormat(maxDuration)
-      },
-      'times': {
-        'oldest': oldest,
-        'youngest': youngest
+  }),
+  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");
       }
-    };
-    return ret;
-  },
-  /**
-   * Click on big star on the avg block
-   */
-  avgStarClick: function() {
-    if (this.get('viewType') === 'starred') return;
-    this.set('whatAvgShow', !this.get('whatAvgShow'));
-    $('a.icon-star.a').toggleClass('active');
-  },
-  /**
-   *
-   */
-  starClicked: function() {
-    var runIndex = this.get('controller.lastStarClicked');
-    if (!this.get('oTable')) return;
-    var rowIndex = -1;
-    // Get real row index
-    var column = this.get('oTable').fnGetColumnData(1);  // 1 - number of column with full runId (hidden)
-    for (var i = 0; i < column.length; i++) {
-      if (runIndex == column[i]) {
-        rowIndex = i;
-        break;
+    }.observes("controller.paginationObject"),
+    click: function (event) {
+      if (this.class == "paginate_next") {
+        var startDisplayValue = parseInt(this.get("controller.paginationObject.endIndex"));
+        this.set("controller.filterObject.iDisplayStart", startDisplayValue);
       }
     }
-    var perPage = this.get('oTable').fnSettings()['_iDisplayLength']; // How many rows show per page
-    var rowIndexVisible = rowIndex; // rowIndexVisible - rowIndex in current visible part of the table
-    if (perPage !== -1) { // If not show All is selected we should recalculate row index according to other visible rows
-      rowIndexVisible = rowIndex % perPage;
-    }
-    // Update inner dataTable value
-    this.get('oTable').fnUpdate( $('#dataTable tbody tr:eq(' + rowIndexVisible + ') td:eq(0)').html(), this.get('oTable').fnSettings()['aiDisplay'][rowIndex], 0);
-    if (perPage !== -1) { // Change page after reDraw (if show All is selected this will not happens)
-      this.get('oTable').fnPageChange(Math.floor(rowIndex / perPage));
-    }
-  }.observes('controller.lastStarClicked'),
+  }),
+
   /**
-   * Flush all starred runs
+   * If there are table rows with runs.
    */
-  clearStars: function() {
-    this.get('controller').get('content').setEach('isStared', false);
-    this.get('controller').set('staredRunsLength', 0);
-    this.set('viewType', this.get('defaultViewType'));
-    this.set('whatAvgShow', true);
-    this.get('smallStarsIcons').removeClass('stared');
-    $('#dataTable .icon-star').removeClass('stared');
-    $('a.icon-star.a').removeClass('active');
-  },
-  /**
-   * "turn off" stars in the table
+  emptyData:true,
+
+  /*
+   If no runs to display set emptyData to true and reset Avg table data, else to set emptyData to false.
    */
-  resetStars: function() {
-    /*var self = this;
-    if (this.get('controller.staredRunsLength') != 0 && this.get('smallStarsIcons') != null) {
-      this.get('smallStarsIcons').removeClass('stared');
-      $('#dataTable .icon-star').removeClass('stared');
-      $('a.icon-star.a').removeClass('active');
-      this.get('starFilterViewInstance').set('value', '');
-      this.updateStars();
-    }*/
-  }.observes('controller.staredRunsLength'),
-  /**
-   * Update stars data in dataTable. data taken from page
-   * Experimental. Need to be tested.
-   */
-  updateStars: function() {
-    var self = this;
-    if (this.get('oTable').fnSettings().fnRecordsDisplay()) {
-      $('#dataTable tbody tr').each(function(index) {
-        self.get('oTable').fnUpdate( $('#dataTable tbody tr:eq(' + index + ') td:eq(0)').html(), self.get('oTable').fnSettings()['aiDisplay'][index], 0);
-      });
+  emptyDataObserver:function(){
+    //debugger;
+    if(this.get("controller.paginationObject.iTotalRecords") != null && this.get("controller.paginationObject.iTotalDisplayRecords")>0){
+      this.set("emptyData",false);
+    }else{
+      this.set("emptyData",true);
+      this.set("controller.serverData",null);
     }
-  },
-  /**
-   * Reset filters and "turn off" stars
-   */
-  showAll: function() {
-    this.clearFilters();
-    this.clearStars();
-  },
-  /**
-   * Display only stared rows
-   */
-  showStared: function() {
-    this.updateStars();
-    this.get('starFilterViewInstance').set('value', 'stared');
-    this.set('whatAvgShow', false);
-    $('a.icon-star.a').addClass('active');
-  },
-  /**
-   * Onclick handler for <code>Show All/Filtered/Starred</code> links
-   */
-  clickViewType: function(event) {
-    this.set('viewType', $(event.target).data('view-type'));
-  },
+  }.observes("controller.paginationObject.iTotalDisplayRecords","controller.paginationObject.iTotalRecords"),
+
+
   /**
-   *
+   * View for RunPerPage select component
    */
-  onChangeViewType: function(){
-    var viewType = this.get('viewType');
-    var table = this.get('oTable');
-    var filterButtons = $("#filter_buttons").children();
-    filterButtons.each(function(index, element){
-      $(element).removeClass('selected');
-      if(viewType == $(element).data('view-type')){
-        $(element).addClass('selected');
-      }
-    });
-    switch(viewType) {
-      case 'all':
-        table.fnSettings().oFeatures.bFilter = false;
-        table.fnDraw();
-        table.fnSettings().oFeatures.bFilter = true;
-        break;
-      case 'starred':
-        this.showStared();
-        break;
-      case 'filtered':
-        table.fnSettings().oFeatures.bFilter = true;
-        table.fnDraw();
-        break;
-      };
-
-
-  }.observes('viewType'),
-
-  /**
-   * jQuery dataTable init
-   */
-  createDataTable: function () {
-    var smallStars = $('#dataTable .icon-star');
-    var self = this;
-    this.set('smallStarsIcons', smallStars);
-    var d = new Date();
-    var oTable = this.$('#dataTable').dataTable({
-      "sDom": '<"search-bar"f><"clear">rt<"page-bar"lip><"clear">',
-      "fnDrawCallback": function( oSettings ) {
-        if(!self.get('oTable')){return}
-        if(self.get('viewType') !== 'all') {
-          if (self.get('viewType') !== 'starred') {
-            self.set('filtered', this.fnSettings().fnRecordsDisplay());
-          }
-        }
-        if(self.get('viewType') === 'all' && self.get('oTable').fnSettings().oFeatures.bFilter){
-          self.set('viewType', 'filtered');
-          self.set('filtered', this.fnSettings().fnRecordsDisplay());
-        }
-      },
-      "aaSorting": [],
-      "oLanguage": {
-        "sSearch": "Search:",
-        "sLengthMenu": "Show: _MENU_",
-        "sInfo": "_START_ - _END_ of _TOTAL_",
-        "sInfoEmpty": "0 - _END_ of _TOTAL_",
-        "sInfoFiltered": "",
-        "oPaginate":{
-          "sPrevious": "<i class='icon-arrow-left'></i>",
-          "sNext": "<i class='icon-arrow-right'></i>"
-        }
-      },
-      "bSortCellsTop": true,
-      "iDisplayLength": -1,
-      "aLengthMenu": [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]],
-      "aoColumns":[
-        { "bSortable": false  },
-        { "bVisible": false },
-        null,
-        null,
-        null,
-        null,
-        null,
-        { "sType":"ambari-bandwidth" },
-        { "sType":"ambari-bandwidth" },
-        null,
-        { "sType":"ambari-datetime" }
-      ],
-      "aaSorting": [[ 10, "desc" ]]
-    }).css('visibility', 'visible');
-    this.set('oTable', oTable);
-    this.set('filtered', oTable.fnSettings().fnRecordsDisplay());
-
-    // If we have some starred runs, mark them again
-    var staredRuns = [];
-    this.get('controller.').get('content').filterProperty('isStared', true).forEach(function(run) {
-      staredRuns.push(run.get('id'));
-    });
-    this.clearStars();
-    var tr = $('#dataTable').find('tr');
-    staredRuns.forEach(function(item) {
-      tr.each(function() {
-        if ($(this).find('td.appId:eq(0)').attr('title') == item) {
-          return $(this).find('td a:eq(0) span').trigger('click');
-        }
-      });
-    });
-    this.get('oTable').fnSettings()._iDisplayLength = 10;
-    $('#dataTable_length select option:eq(0)').attr('selected', 'selected');
-    this.get('oTable').fnDraw(false);
-
-    console.log('Rendering Apps Table:');
-    console.log('Start - ', d.toLocaleTimeString());
-    console.log('End   - ', (new Date()).toLocaleTimeString());
-  },
+  runPerPageSelectView: Em.Select.extend({
+    selected: '10',
+    content: ['10', '25', '50', '100']
+  }),
 
-  loaded: false,
-  inserted: false,
+  wrapSorting: Ember.View.extend({
+    tagName: 'tr'
+  }),
 
-  onLoad: function(){
-    if(this.get('loaded')){
-      return;
-    }
-    if(!App.router.get('clusterController.postLoadList.runs')){
-      return;
-    }
-    if(!this.get('inserted')){
-      return;
-    }
+  sortingColumns: Ember.View.extend({
+    tagName: 'th',
+    classNameBindings: ['class', 'widthClass'],
+    class: "sorting",
+    widthClass: "",
+    content: null,
+    defaultColumn: 8,
 
-    this.set('loaded', true);
-    var self = this;
-    Ember.run.next(function(){
-      self.createDataTable();
-    });
-  }.observes('App.router.clusterController.postLoadList.runs'),
+    didInsertElement: function () {
+      this.set("widthClass", "col" + this.content.index);
+      if (this.content.index == this.defaultColumn) {
+        this.setControllerObj(this.content.index, "DESC");
+        this.set("class", "sorting_desc");
+      }
+    },
+    click: function (event) {
+      console.log(this.class);
+      if (this.class == "sorting") {
+        this.resetSortClass();
+        this.setControllerObj(this.content.index, "ASC");
+        this.set("class", "sorting_asc");
+      } 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("", "");
+        this.set("class", "sorting");
+      }
+    },
+    resetSortClass: function () {
+      this.get("parentView.childViews").map(function (a, e) {
+        a.get("childViews")[0].set("class", "sorting")
+      });
+    },
+    setControllerObj: function (col, dir) {
+      this.set("controller.filterObject.iSortCol_0", col);
+      this.set("controller.filterObject.sSortDir_0", dir);
+    }
+  }),
 
-  didInsertElement: function () {
-    $('#dataTable').css('visibility', 'hidden'); // hide table before dataTables id initialized
-    this.set('inserted', true);
-    this.onLoad();
-  },
   /**
-   * reset all filters in dataTable
-   *
-   * @param event
+   * Filter-field for Search
    */
-  clearFilters:function(event) {
-    this._childViews.forEach(function(item) {
-    if(item.get('tagName') === 'input') {
-      item.set('value','');
-    }
-    if(item.get('tagName') === 'select') {
-      item.set('value','Any');
-    }
-    if(item.get('multiple')) {
-      item.get('clearFilter')(item);
-    }
-    });
-    this.get('oTable').fnFilterClear();
-    //this.get('controller').clearFilteredRuns();
-    this.set('viewType', this.get('defaultViewType'));
-    this.set('filtered',this.get('oTable').fnSettings().fnRecordsDisplay());
-    this.setFilteredRuns(this.get('oTable')._('tr', {"filter":"applied"}));
-  },
+  appSearchThrough: Em.TextField.extend({
+    classNames: ['input-medium'],
+    type: 'text',
+    placeholder: 'Search'
+  }),
   /**
-   * Clear selected filter
-   * @param event
+   * Filter-field for App ID.
+   * Based on <code>filters</code> library
    */
-  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));
-    }
-  },
-
-  /**
-   * apply each filter to dataTable
-   *
-   * @param {parentView}
-   * @param {iColumn} number of column by which filter
-   * @param {value}
-   */
-  applyFilter:function(parentView, iColumn, value) {
-      value = (value) ? value : '';
-      parentView.get('oTable').fnFilter(value, iColumn);
-  },
-
+  appIdFilterView: filters.createTextView({
+    valueBinding: "controller.filterObject.sSearch_0"
+  }),
   /**
-   * refresh average info in top block when filtered changes
+   * Filter-field for name.
+   * Based on <code>filters</code> library
    */
-  averageRefresh:function() {
-    var rows = this.get('oTable')._('tr', {"filter":"applied"});
-    this.get('controller').clearFilteredRuns();
-    var ids = [];
-    for(var i = 0; i < rows.length; i++) {
-      ids.push(rows[i][1]);
-    }
-    this.get('controller').filterFilteredRuns(ids);
-  }.observes('filtered'),
+  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');
-        this.get('parentView').get('oTable').fnFilter('', 4);
-      }
-      else {
-        this.$().closest('th').removeClass('notActive');
-        this.get('parentView').get('oTable').fnFilter(this.get('selection'), 4);
-      }
-      this.get('parentView').set('filtered',this.get('parentView').get('oTable').fnSettings().fnRecordsDisplay());
-    }
+  typeFilterView: filters.createSelectView({
+    fieldType: 'input-small',
+    valueBinding: "controller.filterObject.runType",
+    content: ['Any', 'Pig', 'Hive', 'MapReduce']
   }),
+
   /**
-   * Filter-field for RunDate
+   * Filter-list for User.
+   * Based on <code>filters</code> library
    */
-  rundateSelectView: Em.Select.extend({
-    content: ['Any', 'Running Now', 'Past 1 Day', 'Past 2 Days', 'Past 7 Days', 'Past 14 Days', 'Past 30 Days', 'Custom'],
-    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');
-      }
-
-      if (this.get('selection') == 'Custom') {
-        this.customFilter();
-      } else {
-        this.get('parentView').get('applyFilter')(this.get('parentView'), 10);
-      }
-    },
-
+  userFilterView: filters.createComponentView({
     /**
-     * Custom filter view for RunDate
+     * Inner FilterView. Used just to render component. Value bind to <code>mainview.value</code> property
+     * Base methods was implemented in <code>filters.componentFieldView</code>
      */
-    customFilter: function() {
-      var rundateSelect = this;
+    filterView: filters.componentFieldView.extend({
+      templateName:require('templates/main/apps/user_filter'),
 
-      /**
-       * Show popup with custom filters
-       */
-      App.ModalPopup.show({
-        lowerBound: null,
-        upperBound: null,
-        equal: null,
-        header: Em.I18n.t('apps.filters.customRunDate'),
-        bodyClass: Ember.View.extend({
-          templateName: require('templates/main/apps/custom_rundate_popup'),
-
-          /**
-           * Lower bound view for date-time range on custom filter popup.
-           */
-          lowerBoundView: Ember.TextField.extend({
-            elementId: 'lowerBound',
-            classNames: 'lowerBound',
-            attributeBindings:['readonly'],
-            readonly: true,
-            didInsertElement: function() {
-              var textField = this;
-              var popupBody = this.get('parentView');
-              this.$().datetimepicker({
-                dateFormat: 'D, M dd, yy',
-                timeFormat: 'hh:mm',
-                maxDate: new Date(),
-                onClose:function (dateText, inst) {
-                  var endDateTextBox = $('#upperBound');
-                  if (endDateTextBox.val() != '') {
-                    var testStartDate = new Date(dateText);
-                    var testEndDate = new Date(endDateTextBox.val());
-                    if (testStartDate > testEndDate)
-                      endDateTextBox.val(dateText);
-                  } else {
-                    endDateTextBox.val(dateText);
-                  }
-                },
-                onSelect:function (selectedDateTime) {
-                  var start = $(this).datetimepicker('getDate');
-                  $('#upperBound').datetimepicker('option', 'minDate', new Date(start.getTime()));
-                  popupBody.get('parentView').set('lowerBound', selectedDateTime);
-                }
-              });
-            }
-          }),
-
-          /**
-           * Upper bound view for date-time range on custom filter popup.
-           */
-          upperBoundView: Ember.TextField.extend({
-            elementId: 'upperBound',
-            classNames: 'upperBound',
-            attributeBindings:['readonly'],
-            readonly: true,
-            didInsertElement: function() {
-              var textField = this;
-              var popupBody = this.get('parentView');
-              this.$().datetimepicker({
-                dateFormat: 'D, M dd, yy',
-                timeFormat: 'hh:mm',
-                maxDate: new Date(),
-                onClose:function (dateText, inst) {
-                  var startDateTextBox = $('#lowerBound');
-                  if (startDateTextBox.val() != '') {
-                    var testStartDate = new Date(startDateTextBox.val());
-                    var testEndDate = new Date(dateText);
-                    if (testStartDate > testEndDate)
-                      startDateTextBox.val(dateText);
-                  } else {
-                    startDateTextBox.val(dateText);
-                  }
-                },
-                onSelect:function (selectedDateTime) {
-                  var end = $(this).datetimepicker('getDate');
-                  $('#lowerBound').datetimepicker('option', 'maxDate', new Date(end.getTime()));
-                  popupBody.get('parentView').set('upperBound', selectedDateTime);
-                }
-              });
-            }
-          }),
-
-          /**
-           * Equal view for custom filter popup.
-           */
-          equalView: Ember.TextField.extend({
-            attributeBindings:['readonly'],
-            readonly: true,
-            didInsertElement: function() {
-              var textField = this;
-              var popupBody = this.get('parentView');
-              this.$().datetimepicker({
-                dateFormat: 'D, M dd, yy',
-                timeFormat: 'hh:mm',
-                maxDate: new Date(),
-                onSelect:function (selectedDateTime) {
-                  popupBody.get('parentView').set('equal', selectedDateTime);
-                }
-              });
-            }
-          })
-        }),
+      usersBinding: 'controller.users',
 
-        /**
-         * apply each filter to dataTable
-         * @param lowerBound date-time
-         * @param upperBound date-time
-         * @param equal date-time
-         */
-        applyFilter:function(lowerBound, upperBound, equal) {
-          if (arguments.length == 1) {
-            //do if filtered by equal value
-            equal = new Date(arguments[0]).getTime();
-            jQuery('#custom_rundate_filter').val(equal);
-          } else if (arguments.length == 2) {
-            //do if filtered by date-time range
-            lowerBound = new Date(arguments[0]).getTime();
-            upperBound = new Date(arguments[1]).getTime();
-            var range = [lowerBound, upperBound];
-            jQuery('#custom_rundate_filter').val(range);
-          }
-          rundateSelect.get('parentView').get('applyFilter')(rundateSelect.get('parentView'), 10);
-          if (arguments.length == 0) {
-            rundateSelect.$().closest('th').addClass('notActive');
-          }
-          else {
-            rundateSelect.$().closest('th').removeClass('notActive');
-          }
-        },
-        onPrimary: function() {
-          if (this.get('lowerBound') && this.get('upperBound')) {
-            if (this.get('lowerBound') === this.get('upperBound')) {
-              alert('Range points must be different!');
-            } else {
-              this.applyFilter(this.get('lowerBound'), this.get('upperBound'));
-              this.hide();
-            }
-          } else if (this.get('equal')) {
-            this.applyFilter(this.get('equal'));
-            this.hide();
-          } else {
-            alert('Please specify date and time range or exact date and time!');
-          }
-        },
-        secondary : null
-      });
-    }
+      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 Stars. hidden
+   * Filter-field for jobs.
+   * Based on <code>filters</code> library
    */
-  starFilterView: Em.TextField.extend({
-    classNames:['input-small'],
-    type:'hidden',
-    placeholder: '',
-    elementId:'star_filter',
-    filtering:function() {
-      this.get('parentView').get('applyFilter')(this.get('parentView'), 0);
-    }.observes('value')
-  }),
-  /**
-   * Filter-field for AppId
-   */
-  appidFilterView: Em.TextField.extend({
-    classNames:['input-medium'],
-    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');
-      }
-      this.get('parentView').get('applyFilter')(this.get('parentView'), 1, this.get('value'));
-    }.observes('value')
+  jobsFilterView: filters.createTextView({
+    fieldType: 'input-super-mini',
+    valueBinding: "controller.filterObject.jobs"
   }),
   /**
-   * Filter-field for name
+   * Filter-field for Input.
+   * 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');
-      }
-      this.get('parentView').get('applyFilter')(this.get('parentView'), 3, this.get('value'));
-    }.observes('value')
+  inputFilterView: filters.createTextView({
+    fieldType: 'input-super-mini',
+    valueBinding: "controller.filterObject.input"
   }),
   /**
-   * Filter-field for jobs
+   * Filter-field for Output.
+   * 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')
+  outputFilterView: filters.createTextView({
+    fieldType: 'input-super-mini',
+    valueBinding: "controller.filterObject.output"
   }),
   /**
-   * Filter-field for Input
+   * Filter-field for Duration.
+   * 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');
-      }
-      this.get('parentView').get('applyFilter')(this.get('parentView'), 7);
-    }.observes('value')
+  durationFilterView: filters.createTextView({
+    fieldType: 'input-super-mini',
+    valueBinding: "controller.filterObject.duration"
   }),
   /**
-   * Filter-field for Output
+   * Filter-field for RunDate.
+   * 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');
-      }
-      this.get('parentView').get('applyFilter')(this.get('parentView'), 8);
-    }.observes('value')
+  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']
   }),
+
   /**
-   * Filter-field for Duration
+   * Onclick handler for Show All/Filtered buttons
    */
-  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');
-      }
-      this.get('parentView').get('applyFilter')(this.get('parentView'), 9);
-    }.observes('value')
-  }),
+  clickViewType: function (event) {
+    this.set("controller.filterObject.viewTypeClickEvent", true);
+    if ($(event.target).hasClass("filtered")) {
+      this.set("controller.filterObject.viewType", "filtered");
+    } else {
+      this.set("controller.filterObject.allFilterActivated", true);
+      this.set("controller.filterObject.viewType", "all");
+    }
+  },
   /**
-   * Filter-list for User
+   * Clears up last job ID when coming in fresh to page.
+   * Not doing this will result in failure to load job
+   * data, and subsequently the popup dialog.
    */
-  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'),
-    template: Ember.Handlebars.compile(
-      '<button class="btn btn-info single-btn-group"'+
-      '{{action "clickFilterButton" target="view"}}>'+
-      'User&nbsp;<span class="caret"></span></button>'+
-      '<ul class="dropdown-menu filter-components">'+
-      '<li><label class="checkbox">' +
-      '{{view Ember.Checkbox checkedBinding="view.allComponentsChecked"}} All</label></li>'+
-      '{{#each user in view.users}}<li><label class="checkbox">' +
-      '{{view Ember.Checkbox checkedBinding="user.checked"}} {{user.name}}'+
-      '</label></li>{{/each}}'+
-      '<li>' +
-      '<button class="btn" {{action "closeFilter" target="view"}}>' +
-      'Cancel</button>' +
-      '<button class="btn btn-primary" {{action "applyFilter" target="view"}}>'+
-      'Apply</button>'+
-      '</li></ul>'
-    ),
-    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('oTable').fnFilter('', 5);
-      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'));
-      });
-      jQuery('#user_filter').val(chosenUsers);
-      this.get('parentView').get('applyFilter')(this.get('parentView'), 5);
-      if (chosenUsers.length == 0) {
-        this.$().closest('th').addClass('notActive');
-      }
-      else {
-        this.$().closest('th').removeClass('notActive');
+  didInsertElement: function(){
+    App.router.get('mainAppsItemController').set('lastJobId', null);
+  },
+  /**
+   *
+   */
+  onChangeViewType: function () {
+    var tmpViewType = this.get('controller.filterObject.viewType');
+    var filterButtons = $("#filter_buttons").children();
+    filterButtons.each(function (index, element) {
+      $(element).removeClass('selected');
+      if (tmpViewType == $(element).data('view-type')) {
+        $(element).addClass('selected');
       }
-    }
-  }),
+    });
+    this.set("controller.filterObject.viewTypeClickEvent", false);
+  }.observes("controller.filterObject.viewType"),
+
+  /**
+   * reset all filters in table
+   *
+   */
+  clearFilters: function (event) {
+    this.set("controller.filterObject.sSearch_0","");
+    this.set("controller.filterObject.sSearch_1","");
+    this.set("controller.filterObject.sSearch_2","");
+    this.set("controller.filterObject.sSearch_3","");
+    this.set("controller.filterObject.runType","Any");
+    this.set("controller.filterObject.jobs","");
+    this.set("controller.filterObject.input","");
+    this.set("controller.filterObject.output","");
+    this.set("controller.filterObject.duration","");
+    this.set("controller.filterObject.runDate","Any");
+  },
 
   /**
    * 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'],
@@ -905,10 +324,10 @@ App.MainAppsView = Em.View.extend({
         bodyClass: App.MainAppsItemView.extend({
           controllerBinding: 'App.router.mainAppsItemController'
         }),
-        onPrimary: function() {
+        onPrimary: function () {
           this.hide();
         },
-        secondary : null
+        secondary: null
       });
     }
   }),
@@ -916,16 +335,16 @@ App.MainAppsView = Em.View.extend({
    * Table-row view
    */
   appTableRow: Em.View.extend({
-    templateName : require('templates/main/apps/list_row'),
-    classNames:['app-table-row'],
+    templateName: require('templates/main/apps/list_row'),
+    classNames: ['app-table-row'],
     tagName: "tr",
-    mouseEnter: function(event, view){
+    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/branches/branch-1.2/ambari-web/app/views/main/charts/heatmap/heatmap_host.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/charts/heatmap/heatmap_host.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/charts/heatmap/heatmap_host.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/charts/heatmap/heatmap_host.js Mon Feb  4 02:23:55 2013
@@ -54,6 +54,12 @@ App.MainChartsHeatmapHostView = Em.View.
         } else {
           val = val.toFixed(1);
         }
+      } else if (i == 'hostComponents') {
+        if (val == undefined) {
+          val = null;
+        } else {
+          val = val.filterProperty('isMaster').concat(val.filterProperty('isSlave')).mapProperty('displayName').join(', ');
+        }
       }
       view.set('details.' + i, val);
     });

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/charts/heatmap/heatmap_host_detail.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/charts/heatmap/heatmap_host_detail.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/charts/heatmap/heatmap_host_detail.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/charts/heatmap/heatmap_host_detail.js Mon Feb  4 02:23:55 2013
@@ -31,6 +31,7 @@ App.MainChartsHeatmapHostDetailView = Em
     metricValue: 'metric-value',
     diskUsage: '10',
     cpuUsage: '10',
-    memoryUsage: '10'
+    memoryUsage: '10',
+    hostComponents: 'host components'
   }
 });
\ No newline at end of file

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/cluster_metrics/cpu.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/cluster_metrics/cpu.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/cluster_metrics/cpu.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/cluster_metrics/cpu.js Mon Feb  4 02:23:55 2013
@@ -29,10 +29,12 @@ var App = require('app');
 App.ChartClusterMetricsCPU = App.ChartLinearTimeView.extend({
   id: "cluster-metrics-cpu",
   url: function () {
-    return App.formatUrl(App.apiPrefix + "/clusters/{clusterName}?fields=metrics/cpu[{fromSeconds},{toSeconds},{stepSeconds}]", {
-      clusterName: App.router.get('clusterController.clusterName')
-    }, "/data/cluster_metrics/cpu_1hr.json");
-  }.property('App.router.clusterController.clusterName').volatile(),
+    return App.formatUrl(
+      this.get('urlPrefix') + "?fields=metrics/cpu[{fromSeconds},{toSeconds},{stepSeconds}]",
+      {},
+      "/data/cluster_metrics/cpu_1hr.json"
+    );
+  }.property('clusterName').volatile(),
 
   title: "CPU Usage",
   yAxisFormatter: App.ChartLinearTimeView.PercentageFormatter,
@@ -45,25 +47,12 @@ App.ChartClusterMetricsCPU = App.ChartLi
         var displayName = name;
         var seriesData = jsonData.metrics.cpu[name];
         if (seriesData) {
-          // Is it a string?
-          if ("string" == typeof seriesData) {
-            seriesData = JSON.parse(seriesData);
-          }
-          // We have valid data
-          var series = {};
-          series.name = displayName;
-          series.data = [];
-          for ( var index = 0; index < seriesData.length; index++) {
-            series.data.push({
-              x: seriesData[index][1],
-              y: seriesData[index][0]
-            });
-          }
-          if (name != 'Idle') {
-            seriesArray.push(series);
+          var s = this.transformData(seriesData, displayName);
+          if ('Idle' == s.name) {
+            cpu_idle = s;
           }
           else {
-            cpu_idle = series;
+            seriesArray.push(s);
           }
         }
       }

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/cluster_metrics/load.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/cluster_metrics/load.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/cluster_metrics/load.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/cluster_metrics/load.js Mon Feb  4 02:23:55 2013
@@ -29,12 +29,14 @@ var App = require('app');
  */
 App.ChartClusterMetricsLoad = App.ChartLinearTimeView.extend({
   id: "cluster-metrics-load",
-  url: "/data/cluster_metrics/load_1hr.json",
   url: function () {
-    return App.formatUrl(App.apiPrefix + "/clusters/{clusterName}?fields=metrics/load[{fromSeconds},{toSeconds},{stepSeconds}]", {
-      clusterName: App.router.get('clusterController.clusterName')
-    }, "/data/cluster_metrics/load_1hr.json");
-  }.property('App.router.clusterController.clusterName').volatile(),
+    return App.formatUrl(
+      this.get('urlPrefix') + "?fields=metrics/load[{fromSeconds},{toSeconds},{stepSeconds}]",
+      {},
+      "/data/cluster_metrics/load_1hr.json"
+    );
+  }.property('clusterName').volatile(),
+
   renderer: 'line',
   title: "Cluster Load",
   
@@ -45,21 +47,7 @@ App.ChartClusterMetricsLoad = App.ChartL
         var displayName = name;
         var seriesData = jsonData.metrics.load[name];
         if (seriesData) {
-          // Is it a string?
-          if ("string" == typeof seriesData) {
-            seriesData = JSON.parse(seriesData);
-          }
-          // We have valid data
-          var series = {};
-          series.name = displayName;
-          series.data = [];
-          for ( var index = 0; index < seriesData.length; index++) {
-            series.data.push({
-              x: seriesData[index][1],
-              y: seriesData[index][0]
-            });
-          }
-          seriesArray.push(series);
+          seriesArray.push(this.transformData(seriesData, displayName));
         }
       }
     }

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/cluster_metrics/memory.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/cluster_metrics/memory.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/cluster_metrics/memory.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/cluster_metrics/memory.js Mon Feb  4 02:23:55 2013
@@ -29,10 +29,13 @@ var App = require('app');
 App.ChartClusterMetricsMemory = App.ChartLinearTimeView.extend({
   id: "cluster-metrics-memory",
   url: function () {
-    return App.formatUrl(App.apiPrefix + "/clusters/{clusterName}?fields=metrics/memory[{fromSeconds},{toSeconds},{stepSeconds}]", {
-      clusterName: App.router.get('clusterController.clusterName')
-    }, "/data/cluster_metrics/memory_1hr.json");
-  }.property('App.router.clusterController.clusterName').volatile(),
+    return App.formatUrl(
+      this.get('urlPrefix') + "?fields=metrics/memory[{fromSeconds},{toSeconds},{stepSeconds}]",
+      {},
+      "/data/cluster_metrics/memory_1hr.json"
+    );
+  }.property('clusterName').volatile(),
+
   title: "Memory Usage",
   yAxisFormatter: App.ChartLinearTimeView.BytesFormatter,
   renderer: 'line',
@@ -43,21 +46,7 @@ App.ChartClusterMetricsMemory = App.Char
         var displayName = name;
         var seriesData = jsonData.metrics.memory[name];
         if (seriesData) {
-          // Is it a string?
-          if ("string" == typeof seriesData) {
-            seriesData = JSON.parse(seriesData);
-          }
-          // We have valid data
-          var series = {};
-          series.name = displayName;
-          series.data = [];
-          for ( var index = 0; index < seriesData.length; index++) {
-            series.data.push({
-              x: seriesData[index][1],
-              y: seriesData[index][0]
-            });
-          }
-          seriesArray.push(series);
+          seriesArray.push(this.transformData(seriesData, displayName));
         }
       }
     }

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/cluster_metrics/network.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/cluster_metrics/network.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/cluster_metrics/network.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/cluster_metrics/network.js Mon Feb  4 02:23:55 2013
@@ -30,10 +30,13 @@ var App = require('app');
 App.ChartClusterMetricsNetwork = App.ChartLinearTimeView.extend({
   id: "cluster-metrics-network",
   url: function () {
-    return App.formatUrl(App.apiPrefix + "/clusters/{clusterName}?fields=metrics/network[{fromSeconds},{toSeconds},{stepSeconds}]", {
-      clusterName: App.router.get('clusterController.clusterName')
-    }, "/data/cluster_metrics/network_1hr.json");
-  }.property('App.router.clusterController.clusterName').volatile(),
+    return App.formatUrl(
+      this.get('urlPrefix') + "?fields=metrics/network[{fromSeconds},{toSeconds},{stepSeconds}]",
+      {},
+      "/data/cluster_metrics/network_1hr.json"
+    );
+  }.property('clusterName').volatile(),
+
   title: "Network Usage",
   yAxisFormatter: App.ChartLinearTimeView.BytesFormatter,
   renderer: 'line',
@@ -45,22 +48,7 @@ App.ChartClusterMetricsNetwork = App.Cha
         var displayName = name;
         var seriesData = jsonData.metrics.network[name];
         if (seriesData) {
-          // Is it a string?
-          if ("string" == typeof seriesData) {
-            seriesData = JSON.parse(seriesData);
-          }
-          // We have valid data
-          var series = {};
-          series.name = displayName;
-          series.data = [];
-          for ( var index = 0; index < seriesData.length; index++) {
-            series.data.push({
-              x: seriesData[index][1],
-              y: seriesData[index][0]
-            });
-          }
-
-          seriesArray.push(series);
+          seriesArray.push(this.transformData(seriesData, displayName));
         }
       }
     }

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service.js Mon Feb  4 02:23:55 2013
@@ -22,7 +22,7 @@ require('models/alert');
 
 App.MainDashboardServiceHealthView = Em.View.extend({
   classNameBindings: ["healthStatus"],
-  template: Em.Handlebars.compile(""),
+  //template: Em.Handlebars.compile(""),
   blink: false,
   tagName: 'span',
   
@@ -71,7 +71,7 @@ App.MainDashboardServiceHealthView = Em.
         break;
     }
 
-    return 'health-status-' + status + " span";
+    return 'health-status-' + status;
   }.property('service.healthStatus'),
 
   didInsertElement: function () {
@@ -86,9 +86,38 @@ App.MainDashboardServiceView = Em.View.e
     return this.get('controller.data.' + this.get('serviceName'));
   }.property('controller.data'),
 
+  formatUnavailable: function(value){
+    return (value || value == 0) ? value : this.t('services.service.summary.notAvailable');
+  },
+
   criticalAlertsCount: function () {
     var alerts = App.router.get('clusterController.alerts');
     return alerts.filterProperty('serviceType', this.get('service.id')).filterProperty('isOk', false).length;
-  }.property('App.router.clusterController.alerts')
+  }.property('App.router.clusterController.alerts'),
+
+  isCollapsed: false,
+
+  toggleInfoView: function () {
+    this.$('.service-body').toggle('blind', 200);
+    this.set('isCollapsed', !this.isCollapsed);
+  },
+
+  masters: function(){
+    return this.get('service.hostComponents').filterProperty('isMaster', true);
+  }.property('service'),
+
+  clients: function(){
+    var clients = this.get('service.hostComponents').filterProperty('isClient', true);
+    var len = clients.length;
+    var template = 'dashboard.services.{0}.client'.format(this.get('serviceName').toLowerCase());
+    if(len > 1){
+      template += 's';
+    }
+
+    return {
+      title: this.t(template).format(len),
+      component: clients.objectAt(0)
+    };
+  }.property('service')
 
 });
\ No newline at end of file

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/hbase.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/hbase.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/hbase.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/hbase.js Mon Feb  4 02:23:55 2013
@@ -31,6 +31,10 @@ App.MainDashboardServiceHbaseView = App.
     return this.t('dashboard.services.hbase.masterServerHeap.summary').format(heapString, heapMaxString, percent.toFixed(1));
   }.property('service.heapMemoryUsed', 'service.heapMemoryMax'),
 
+  version: function(){
+    return this.formatUnavailable(this.get('service.version'));
+  }.property('service.version'),
+
   summaryHeader: function () {
     var avgLoad = this.get('service.averageLoad');
     if (avgLoad == null) {
@@ -46,7 +50,7 @@ App.MainDashboardServiceHbaseView = App.
   averageLoad: function () {
     var avgLoad = this.get('service.averageLoad');
     if (avgLoad == null) {
-      avgLoad = this.t('services.service.summary.unknown');
+      avgLoad = this.t('services.service.summary.notAvailable');
     }
     return this.t('dashboard.services.hbase.averageLoadPerServer').format(avgLoad);
   }.property("service.averageLoad"),
@@ -61,7 +65,7 @@ App.MainDashboardServiceHbaseView = App.
       var formatted = date.timingFormat(diff);
       return this.t('dashboard.services.uptime').format(formatted);
     }
-    return this.t('services.service.summary.unknown');
+    return this.t('services.service.summary.notRunning');
   }.property("service.masterStartTime"),
 
   masterActivatedTime: function () {
@@ -74,17 +78,11 @@ App.MainDashboardServiceHbaseView = App.
       var formatted = date.timingFormat(diff);
       return this.t('dashboard.services.uptime').format(formatted);
     }
-    return this.t('services.service.summary.unknown');
+    return this.t('services.service.summary.notRunning');
   }.property("service.masterActiveTime"),
 
   regionServerComponent: function () {
-    return App.Component.find().findProperty('componentName', 'HBASE_REGIONSERVER');
-  }.property('components'),
-
-  isCollapsed: false,
+    return App.HostComponent.find().findProperty('componentName', 'HBASE_REGIONSERVER');
+  }.property()
 
-  toggleInfoView: function () {
-    $('#hbase-info').toggle('blind', 200);
-    this.set('isCollapsed', !this.isCollapsed);
-  }
 });
\ No newline at end of file

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/hdfs.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/hdfs.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/hdfs.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/hdfs.js Mon Feb  4 02:23:55 2013
@@ -23,6 +23,11 @@ App.MainDashboardServiceHdfsView = App.M
   serviceName: 'HDFS',
   Chart: App.ChartPieView.extend({
     service: null,
+    color: '#0066B3',
+    stroke: '#0066B3',
+    palette: new Rickshaw.Color.Palette({
+      scheme: [ 'rgba(0,102,179,0)', 'rgba(0,102,179,1)'].reverse()
+    }),
     data: function () {
       var total = this.get('service.capacityTotal') + 0;
       var remaining = (this.get('service.capacityRemaining') + 0);
@@ -31,14 +36,36 @@ App.MainDashboardServiceHdfsView = App.M
     }.property('service.capacityUsed', 'service.capacityTotal')
   }),
 
+  version: function(){
+    return this.formatUnavailable(this.get('service.version'));
+  }.property('service.version'),
+  dfsTotalBlocks: function(){
+    return this.formatUnavailable(this.get('service.dfsTotalBlocks'));
+  }.property('service.dfsTotalBlocks'),
+  dfsTotalFiles: function(){
+    return this.formatUnavailable(this.get('service.dfsTotalFiles'));
+  }.property('service.dfsTotalFiles'),
+  dfsCorruptBlocks: function(){
+    return this.formatUnavailable(this.get('service.dfsCorruptBlocks'));
+  }.property('service.dfsCorruptBlocks'),
+  dfsMissingBlocks: function(){
+    return this.formatUnavailable(this.get('service.dfsMissingBlocks'));
+  }.property('service.dfsMissingBlocks'),
+  dfsUnderReplicatedBlocks: function(){
+    return this.formatUnavailable(this.get('service.dfsUnderReplicatedBlocks'));
+  }.property('service.dfsUnderReplicatedBlocks'),
+
   nodeUptime: function () {
     var uptime = this.get('service').get('nameNodeStartTime');
-    var diff = (new Date()).getTime() - uptime;
-    if (diff < 0) {
-      diff = 0;
+    if (uptime && uptime > 0){
+      var diff = (new Date()).getTime() - uptime;
+      if (diff < 0) {
+        diff = 0;
+      }
+      var formatted = date.timingFormat(diff);
+      return this.t('dashboard.services.uptime').format(formatted);
     }
-    var formatted = date.timingFormat(diff);
-    return this.t('dashboard.services.uptime').format(formatted);
+    return this.t('services.service.summary.notRunning');
   }.property("service.nameNodeStartTime"),
 
   nodeWebUrl: function () {
@@ -87,16 +114,9 @@ App.MainDashboardServiceHdfsView = App.M
   }.property('service.capacityUsed', 'service.capacityTotal'),
 
   dataNodeComponent: function () {
-    return App.Component.find().findProperty('componentName', 'DATANODE');
+    return App.HostComponent.find().findProperty('componentName', 'DATANODE');
   }.property('+'),
 
-  isCollapsed: false,
-
-  toggleInfoView: function () {
-    $('#hdfs-info').toggle('blind', 200);
-    this.set('isCollapsed', !this.isCollapsed);
-  },
-
   isSafeMode: function () {
     var safeMode = this.get('service.safeModeStatus');
     return safeMode != null && safeMode.length > 0;

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/hive.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/hive.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/hive.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/hive.js Mon Feb  4 02:23:55 2013
@@ -20,5 +20,10 @@ var App = require('app');
 
 App.MainDashboardServiceHiveView = App.MainDashboardServiceView.extend({
   templateName: require('templates/main/dashboard/service/hive'),
-  serviceName: 'hive'
+  serviceName: 'hive',
+
+  titleMasters: function(){
+    var masters = this.get('masters');
+    return [masters.findProperty('componentName', 'HIVE_SERVER'), masters.findProperty('componentName', 'HIVE_METASTORE')];
+  }.property('service')
 });
\ No newline at end of file

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/mapreduce.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/mapreduce.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/mapreduce.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/mapreduce.js Mon Feb  4 02:23:55 2013
@@ -31,14 +31,22 @@ App.MainDashboardServiceMapreduceView = 
     }.property('_parentView.data.chart')
   }),
 
+  version: function(){
+    return this.formatUnavailable(this.get('service.version'));
+  }.property('service.version'),
+
   jobTrackerUptime: function () {
     var uptime = this.get('service').get('jobTrackerStartTime');
-    var diff = (new Date()).getTime() - uptime;
-    if (diff < 0) {
-      diff = 0;
+    if (uptime && uptime > 0){
+      var diff = (new Date()).getTime() - uptime;
+      if (diff < 0) {
+        diff = 0;
+      }
+      var formatted = date.timingFormat(diff);
+      return this.t('dashboard.services.uptime').format(formatted);
+
     }
-    var formatted = date.timingFormat(diff);
-    return this.t('dashboard.services.uptime').format(formatted);
+    return this.t('services.service.summary.notRunning');
   }.property("service.jobTrackerStartTime"),
 
   summaryHeader: function () {
@@ -60,8 +68,8 @@ App.MainDashboardServiceMapreduceView = 
   }.property('service.aliveTrackers', 'service.taskTrackers'),
 
   trackersHeapSummary: function () {
-    var heapUsed = this.get('service').get('jobTrackerHeapUsed') || 90;
-    var heapMax = this.get('service').get('jobTrackerHeapMax') || 90;
+    var heapUsed = this.get('service').get('jobTrackerHeapUsed') || 0;
+    var heapMax = this.get('service').get('jobTrackerHeapMax') || 0;
     var percent = heapMax > 0 ? 100 * heapUsed / heapMax : 0;
     return this.t('dashboard.services.mapreduce.jobTrackerHeapSummary').format(heapUsed.bytesToSize(1, "parseFloat"), heapMax.bytesToSize(1, "parseFloat"), percent.toFixed(1));
   }.property('service.jobTrackerHeapUsed', 'service.jobTrackerHeapMax'),
@@ -69,31 +77,31 @@ App.MainDashboardServiceMapreduceView = 
   jobsSummary: function () {
     var svc = this.get('service');
     var template = this.t('dashboard.services.mapreduce.jobsSummary');
-    return template.format(svc.get('jobsSubmitted'), svc.get('jobsCompleted'));
+    return template.format(this.formatUnavailable(svc.get('jobsSubmitted')), this.formatUnavailable(svc.get('jobsCompleted')));
   }.property('service.jobsSubmitted', 'service.jobsCompleted'),
 
   mapSlotsSummary: function () {
     var svc = this.get('service');
     var template = this.t('dashboard.services.mapreduce.mapSlotsSummary');
-    return template.format(svc.get('mapSlotsOccupied'), svc.get('mapSlotsReserved'));
+    return template.format(this.formatUnavailable(svc.get('mapSlotsOccupied')), this.formatUnavailable(svc.get('mapSlotsReserved')));
   }.property('service.mapSlotsOccupied', 'service.mapSlotsReserved'),
 
   reduceSlotsSummary: function () {
     var svc = this.get('service');
     var template = this.t('dashboard.services.mapreduce.reduceSlotsSummary');
-    return template.format(svc.get('reduceSlotsOccupied'), svc.get('reduceSlotsReserved'));
+    return template.format(this.formatUnavailable(svc.get('reduceSlotsOccupied')), this.formatUnavailable(svc.get('reduceSlotsReserved')));
   }.property('service.reduceSlotsOccupied', 'service.reduceSlotsReserved'),
 
   mapTasksSummary: function () {
     var svc = this.get('service');
     var template = this.t('dashboard.services.mapreduce.tasksSummary');
-    return template.format(svc.get('mapsRunning'), svc.get('mapsWaiting'));
+    return template.format(this.formatUnavailable(svc.get('mapsRunning')), this.formatUnavailable(svc.get('mapsWaiting')));
   }.property('service.mapsRunning', 'service.mapsWaiting'),
 
   reduceTasksSummary: function () {
     var svc = this.get('service');
     var template = this.t('dashboard.services.mapreduce.tasksSummary');
-    return template.format(svc.get('reducesRunning'), svc.get('reducesWaiting'));
+    return template.format(this.formatUnavailable(svc.get('reducesRunning')), this.formatUnavailable(svc.get('reducesWaiting')));
   }.property('service.reducesRunning', 'service.reducesWaiting'),
 
   slotsCapacitySummary: function () {
@@ -109,13 +117,6 @@ App.MainDashboardServiceMapreduceView = 
   }.property('service.mapSlots', 'service.reduceSlots', 'service.aliveTrackers'),
 
   taskTrackerComponent: function () {
-    return App.Component.find().findProperty('componentName', 'TASKTRACKER');
-  }.property('components'),
-
-  isCollapsed: false,
-
-  toggleInfoView: function() {
-    $('#mapreduce-info').toggle('blind', 200);
-    this.set('isCollapsed', !this.isCollapsed);
-  }
+    return App.HostComponent.find().findProperty('componentName', 'TASKTRACKER');
+  }.property()
 });
\ No newline at end of file

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/oozie.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/oozie.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/oozie.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/oozie.js Mon Feb  4 02:23:55 2013
@@ -19,7 +19,11 @@
 var App = require('app');
 
 App.MainDashboardServiceOozieView = App.MainDashboardServiceView.extend({
-  classNames: ['no-borders'],
   serviceName: 'oozie',
-  templateName: require('templates/main/dashboard/service/oozie')
+  templateName: require('templates/main/dashboard/service/oozie'),
+
+  webUi: function () {
+    var hostName = this.get('service.hostComponents').findProperty('componentName', 'OOZIE_SERVER').get('host.publicHostName');
+    return "http://{0}:11000/oozie".format(hostName);
+  }.property('service')
 });
\ No newline at end of file

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/zookeeper.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/zookeeper.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/zookeeper.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/dashboard/service/zookeeper.js Mon Feb  4 02:23:55 2013
@@ -20,5 +20,21 @@ var App = require('app');
 
 App.MainDashboardServiceZookeperView = App.MainDashboardServiceView.extend({
   templateName: require('templates/main/dashboard/service/zookeeper'),
-  serviceName: 'zookeeper'
+  serviceName: 'zookeeper',
+
+  titleInfo: function(){
+    var components = this.get('service.hostComponents').filterProperty('componentName', 'ZOOKEEPER_SERVER');
+    var running = 0;
+    components.forEach(function(item){
+      if(item.get('workStatus') === App.HostComponentStatus.started){
+        running += 1;
+      }
+    });
+
+    return {
+      pre: this.t('dashboard.services.zookeeper.prefix').format(running),
+      title: this.t('dashboard.services.zookeeper.title').format(components.length),
+      component: components.objectAt(0)
+    };
+  }.property('service')
 });
\ No newline at end of file

Modified: incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/host.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/host.js?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/host.js (original)
+++ incubator/ambari/branches/branch-1.2/ambari-web/app/views/main/host.js Mon Feb  4 02:23:55 2013
@@ -18,6 +18,8 @@
 
 var App = require('app');
 require('utils/data_table');
+var filters = require('views/common/filter_view');
+var date = require('utils/date');
 
 App.MainHostView = Em.View.extend({
   templateName:require('templates/main/host'),
@@ -46,6 +48,8 @@ App.MainHostView = Em.View.extend({
       "bSortCellsTop": true,
       "iDisplayLength": 10,
       "aLengthMenu": [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]],
+      "oSearch": {"bSmart":false},
+      "bAutoWidth": false,
       "aoColumns":[
         { "bSortable": false },
         { "sType":"html" },
@@ -57,7 +61,8 @@ App.MainHostView = Em.View.extend({
         { "sType":"html", "bSortable": false  },
         { "bVisible": false }, // hidden column for raw public host name value
         { "bVisible": false } // hidden column for raw components list
-      ]
+      ],
+      "aaSorting": [[ 1, "asc" ]]
     });
     this.set('oTable', oTable);
     this.set('allComponentsChecked', true); // select all components (checkboxes) on start.
@@ -66,9 +71,37 @@ App.MainHostView = Em.View.extend({
   HostView:Em.View.extend({
     content:null,
 
+    healthToolTip: function(){
+      var hostComponents = this.get('content.hostComponents').filter(function(item){
+        if(item.get('workStatus') !== App.HostComponentStatus.started){
+          return true;
+        }
+      });
+      var output = '';
+      switch (this.get('content.healthClass')){
+        case 'health-status-DEAD':
+          hostComponents = hostComponents.filterProperty('isMaster', true);
+          output = Em.I18n.t('hosts.host.healthStatus.mastersDown');
+          hostComponents.forEach(function(hc, index){
+            output += (index == (hostComponents.length-1)) ? hc.get('displayName') : (hc.get('displayName')+", ");
+          }, this);
+          break;
+        case 'health-status-DEAD-YELLOW':
+          output = Em.I18n.t('hosts.host.healthStatus.heartBeatNotReceived');
+          break;
+        case 'health-status-DEAD-ORANGE':
+          hostComponents = hostComponents.filterProperty('isSlave', true);
+          output = Em.I18n.t('hosts.host.healthStatus.slavesDown');
+          hostComponents.forEach(function(hc, index){
+            output += (index == (hostComponents.length-1)) ? hc.get('displayName') : (hc.get('displayName')+", ");
+          }, this);
+          break;
+      }
+      return output;
+    }.property('content.healthClass'),
+
     shortLabels: function() {
-      var components = this.get('labels');
-      var labels = this.get('content.components').getEach('displayName');
+      var labels = this.get('content.hostComponents').getEach('displayName');
       var shortLabels = '';
       var c = 0;
       labels.forEach(function(label) {
@@ -87,8 +120,8 @@ App.MainHostView = Em.View.extend({
     }.property('labels'),
 
     labels: function(){
-      return this.get('content.components').getEach('displayName').join('\n');
-    }.property('content.components.@each'),
+      return this.get('content.hostComponents').getEach('displayName').join('\n');
+    }.property('content.hostComponents.@each'),
 
     usageStyle:function () {
       return "width:" + this.get('content.diskUsage') + "%";
@@ -97,320 +130,169 @@ App.MainHostView = Em.View.extend({
 
   }),
 
-  nameFilterView: Em.TextField.extend({
-    classNames:['input-medium'],
-    type:'text',
-    placeholder: 'Any Name',
-    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'), 8, this.get('value'));
-    }.observes('value')
+  /**
+   * Filter view for name column
+   * Based on <code>filters</code> library
+   */
+  nameFilterView: filters.createTextView({
+    onChangeValue: function(){
+      this.get('parentView').updateFilter(8, this.get('value'));
+    }
   }),
 
-  rackFilterView: Em.TextField.extend({
-    classNames:['input-medium'],
-    type:'text',
-    placeholder: 'Any Name',
-    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'), 2, this.get('value'));
-    }.observes('value')
-  }),
   /**
-   * Filter-field for cpu
+   * Filter view for ip column
+   * Based on <code>filters</code> library
    */
-  cpuFilterView: Em.TextField.extend({
-    classNames:['input-mini'],
-    type:'text',
-    placeholder: 'Any ',
-    elementId:'cpu_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'), 3);
-    }.observes('value')
+  ipFilterView: filters.createTextView({
+    onChangeValue: function(){
+      this.get('parentView').updateFilter(2, this.get('value'));
+    }
   }),
+
   /**
-   * Filter-field for load avg
+   * Filter view for Cpu column
+   * Based on <code>filters</code> library
    */
-  loadAvgFilterView: Em.TextField.extend({
-    classNames:['input-mini'],
-    type:'text',
-    placeholder: 'Any ',
-    elementId:'load_avg_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'), 5);
-    }.observes('value')
+  cpuFilterView: filters.createTextView({
+    fieldType: 'input-mini',
+    fieldId: 'cpu_filter',
+    onChangeValue: function(){
+      this.get('parentView').updateFilter(3);
+    }
   }),
+
   /**
-   * Filter-field for RAM
+   * Filter view for LoadAverage column
+   * Based on <code>filters</code> library
    */
-  ramFilterView: Em.TextField.extend({
-    classNames:['input-mini'],
-    type:'text',
-    placeholder: 'Any ',
-    elementId: 'ram_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'), 4);
-    }.observes('value')
+  loadAvgFilterView: filters.createTextView({
+    fieldType: 'input-mini',
+    fieldId: 'load_avg_filter',
+    onChangeValue: function(){
+      this.get('parentView').updateFilter(5);
+    }
   }),
+
   /**
-   * Filter-list for Components
+   * Filter view for Ram column
+   * Based on <code>filters</code> library
    */
-  componentsFilterView: Em.View.extend({
-    classNames:['btn-group'],
-    classNameBindings: ['open'],
-    multiple:true,
-    open: false,
-
-    isFilterOpen:false,
-
-    btnGroupClass:function () {
-      return this.get('isFilterOpen') ? 'btn-group open' : 'btn-group';
-    }.property('isFilterOpen'),
-
-    allComponentsChecked:false,
-    toggleAllComponents:function () {
-      this.set('masterComponentsChecked', this.get('allComponentsChecked'));
-      this.set('slaveComponentsChecked', this.get('allComponentsChecked'));
-      this.set('clientComponentsChecked', this.get('allComponentsChecked'));
-    }.observes('allComponentsChecked'),
-
-    masterComponentsChecked:false,
-    toggleMasterComponents:function () {
-      var checked = this.get('masterComponentsChecked');
-      this.get('masterComponents').forEach(function (comp) {
-        comp.set('checkedForHostFilter', checked);
-      });
-    }.observes('masterComponentsChecked'),
-
-    slaveComponentsChecked:false,
-    toggleSlaveComponents:function () {
-      var checked = this.get('slaveComponentsChecked');
-      this.get('slaveComponents').forEach(function (comp) {
-        comp.set('checkedForHostFilter', checked);
-      });
-    }.observes('slaveComponentsChecked'),
+  ramFilterView: filters.createTextView({
+    fieldType: 'input-mini',
+    fieldId: 'ram_filter',
+    onChangeValue: function(){
+      this.get('parentView').updateFilter(4);
+    }
+  }),
 
-    clientComponentsChecked: false,
-    toggleClientComponents: function() {
-      var checked = this.get('clientComponentsChecked');
-      this.get('clientComponents').forEach(function(comp) {
-        comp.set('checkedForHostFilter', checked);
-      });
-    }.observes('clientComponentsChecked'),
+  /**
+   * 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);
 
-    masterComponents:function(){
-      var masterComponents = [];
-      for(var i = 0; i < this.get('parentView').get('controller.masterComponents').length; i++) {
-        masterComponents.push(this.get('parentView').get('controller.masterComponents')[i]);
-      }
-      return masterComponents;
-    }.property('parentView.controller.masterComponents'),
+        this._super();
+      },
 
-    slaveComponents:function(){
-      var slaveComponents = [];
-      for(var i = 0; i < this.get('parentView').get('controller.slaveComponents').length; i++) {
-        slaveComponents.push(this.get('parentView').get('controller.slaveComponents')[i]);
-      }
-      return slaveComponents;
-    }.property('parentView.controller.slaveComponents'),
+      /**
+       * Onclick handler for <code>Apply filter</code> button
+       */
+      applyFilter:function() {
+        this._super();
 
-    clientComponents: function() {
-      var clientComponents = [];
-      for (var i = 0; i < this.get('parentView').get('controller.clientComponents').length; i++) {
-        clientComponents.push(this.get('parentView').get('controller.clientComponents')[i]);
-      }
-      return clientComponents;
-    }.property('parentView.controller.clientComponents'),
+        var chosenComponents = [];
 
-    template: Ember.Handlebars.compile('<div {{bindAttr class="view.btnGroupClass"}} >'+
-      '<button class="btn btn-info single-btn-group" {{action "clickFilterButton" target="view"}}>' +
-        'Components ' +
-        '<span class="caret"></span>' +
-       '</button>' +
-        '<ul class="dropdown-menu filter-components" id="filter-dropdown">' +
-          '<li>' +
-            '<ul>' +
-              '<li>' +
-                  '<label class="checkbox">' +
-                    '{{view Ember.Checkbox checkedBinding="view.allComponentsChecked"}} All' +
-                  '</label>' +
-                '</li>' +
-                '<li>' +
-                  '<label class="checkbox">' +
-                    '{{view Ember.Checkbox checkedBinding="view.masterComponentsChecked"}} Master Components:' +
-                  '</label>' +
-                  '<ul>' +
-                    '{{#each component in masterComponents}}' +
-                      '<li>' +
-                        '<label class="checkbox">' +
-                          '{{view Ember.Checkbox checkedBinding="component.checkedForHostFilter" }} {{unbound component.displayName}}' +
-                        '</label>' +
-                      ' </li>' +
-                    '{{/each}}' +
-                  '</ul>' +
-                '</li>' +
-                '<li>' +
-                  '<label class="checkbox">' +
-                    '{{view Ember.Checkbox checkedBinding="view.slaveComponentsChecked"}} Slave Components:' +
-                  '</label>' +
-                  '<ul>' +
-                    '{{#each component in slaveComponents}}' +
-                      '<li>' +
-                        '<label class="checkbox">' +
-                          '{{view Ember.Checkbox checkedBinding="component.checkedForHostFilter" }} {{unbound component.displayName}}' +
-                        '</label>' +
-                      '</li>' +
-                    '{{/each}}' +
-                  '</ul>' +
-                '</li>' +
-                '<li>' +
-                  '<label class="checkbox">' +
-                    '{{view Ember.Checkbox checkedBinding="view.clientComponentsChecked"}} Client Components:' +
-                  '</label>' +
-                  '<ul>' +
-                    '{{#each component in clientComponents}}' +
-                      '<li>' +
-                        '<label class="checkbox">' +
-                          '{{view Ember.Checkbox checkedBinding="component.checkedForHostFilter" }} {{unbound component.displayName}}' +
-                        '</label>' +
-                      '</li>' +
-                    '{{/each}}' +
-                  '</ul>' +
-                '</li>' +
-            '</ul>' +
-          '</li>' +
-          '<li>' +
-            '<button class="btn" {{action "closeFilters" target="view"}}>' +
-              'Cancel' +
-            '</button> ' +
-            '<button class="btn btn-primary" {{action "applyFilter" target="view"}}>' +
-              'Apply' +
-            '</button>' +
-          '</li>' +
-        '</ul>' +
-      '</div>'),
-
-    clearFilter:function(self) {
-      self.set('allComponentsChecked', true);
-      self.set('allComponentsChecked', false);
-      jQuery('#components_filter').val([]);
-      self.get('parentView').get('oTable').fnFilter('', 6);
-      jQuery('#components_filter').closest('th').addClass('notActive');
-    },
-    closeFilters:function () {
-      $(document).unbind('click');
-      this.clickFilterButton();
-    },
-
-    clickFilterButton:function () {
-      var self = this;
-      this.set('isFilterOpen', !this.get('isFilterOpen'));
-      if (this.get('isFilterOpen')) {
-        var filters = App.router.get('mainHostController.filters.components');
-        $('.filter-component').each(function() {
-          var componentId = parseInt($(this).attr('id').replace('component-', ''));
-          var index = filters.indexOf(componentId);
-          $(this).attr('checked', index == -1);
+        this.get('masterComponents').filterProperty('checkedForHostFilter', true).forEach(function(item){
+          chosenComponents.push(item.get('displayName'));
         });
-
-        var dropDown = $('#filter-dropdown');
-        var firstClick = true;
-        $(document).bind('click', function (e) {
-          if (!firstClick && $(e.target).closest(dropDown).length == 0) {
-            self.set('isFilterOpen', false);
-            $(document).unbind('click');
-          }
-          firstClick = false;
+        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.closeFilters();
+      didInsertElement:function () {
+        if (this.get('controller.comeWithFilter')) {
+          this.applyFilter();
+          this.set('controller.comeWithFilter', false);
+        } else {
+          this.clearFilter();
+        }
       }
-    },
-
-    applyFilter:function() {
-      var chosenComponents = new Array();
 
-      this.set('isFilterOpen', !this.get('isFilterOpen'));
-      this.get('masterComponents').forEach(function(item){
-        if(item.get('checkedForHostFilter')) chosenComponents.push(item.get('displayName'));
-      });
-      this.get('slaveComponents').forEach(function(item){
-        if(item.get('checkedForHostFilter')) chosenComponents.push(item.get('displayName'));
-      });
-      this.get('clientComponents').forEach(function(item){
-        if(item.get('checkedForHostFilter')) chosenComponents.push(item.get('displayName'));
-      });
-      jQuery('#components_filter').val(chosenComponents);
-      this.get('parentView').get('applyFilter')(this.get('parentView'), 9);
-      if (chosenComponents.length == 0) {
-        this.$().closest('th').addClass('notActive');
-      }
-      else {
-        this.$().closest('th').removeClass('notActive');
-      }
+    }),
+    fieldId: 'components_filter',
+    onChangeValue: function(){
+      this.get('parentView').updateFilter(9);
     }
   }),
+
+  startIndex : function(){
+    return Math.random();
+  }.property(),
+
   /**
-   * 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));
-    }
-  },
-  /**
-   * apply each filter to dataTable
+   * Apply each filter to dataTable
    *
-   * @param {parentView}
-   * @param {iColumn} number of column by which filter
-   * @param {value}
+   * @param iColumn number of column by which filter
+   * @param value
    */
-  applyFilter:function(parentView, iColumn, value) {
-    value = (value) ? value : '';
-    parentView.get('oTable').fnFilter(value, iColumn);
+  updateFilter: function(iColumn, value){
+    this.get('oTable').fnFilter(value || '', iColumn);
   }
 
-});
\ No newline at end of file
+});