http://git-wip-us.apache.org/repos/asf/ambari/blob/529ef7f7/contrib/views/storm/src/main/resources/scripts/modules/Table/Pagination.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/modules/Table/Pagination.jsx 
b/contrib/views/storm/src/main/resources/scripts/modules/Table/Pagination.jsx
new file mode 100644
index 0000000..41a763c
--- /dev/null
+++ 
b/contrib/views/storm/src/main/resources/scripts/modules/Table/Pagination.jsx
@@ -0,0 +1,158 @@
+/**
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+*
+     http://www.apache.org/licenses/LICENSE-2.0
+*
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+define(['react', 'utils/Globals'], function(React, Globals){
+  'use strict';
+  return React.createClass({
+    displayName: 'Pagination',
+    
+    getInitialState: function(){
+      this.props.collection.on('reset', function(data){
+        this.setState({'collection': data});
+      }.bind(this));
+      return {
+        collection: this.props.collection
+      };
+    },
+    /**
+     * Next page button being clicked
+     */
+    nextPage: function(e) {
+      e.preventDefault();
+      
this.props.collection.getNextPage(this.props.collection.state.currentPage);
+    },
+    /**
+     * Previous page button being clicked
+     */
+    previousPage: function(e) {
+      e.preventDefault();
+      
this.props.collection.getPreviousPage(this.props.collection.state.currentPage);
+    },
+    /**
+     * Change page being clicked
+     * @param {Event} e Event of the page number being clicked
+     */
+    changePage: function(e) {
+      e.preventDefault();
+      var pageNumber = +e.currentTarget.getAttribute('data-page');
+      this.props.collection.getParticularPage(pageNumber);
+    },
+    /**
+     * Render function for the next page button.
+     * If the current page is the last then it shouldn't render a clickable 
next page
+     */
+    renderNext: function() {
+      if(this.props.collection.state.currentPage < 
this.props.collection.state.totalPages){
+        return (<li><a href="javascript: void(0);" ref="nextPage" 
onClick={this.nextPage}>&raquo;</a></li>);
+      } else {
+        return (<li className="disabled"><a href="javascript: void 
0;">&raquo;</a></li>);
+      }
+    },
+    /**
+     * Render functon for the pages
+     * If the number of maximumPages is exceeded by the number of pages then 
that must be handled with an ellipsis
+     * If the page is active then it should have the active class
+     *
+     */
+    renderPages: function(){
+      var pages = [];
+      var starterPage = 1;
+      if(this.props.collection.state.currentPage >= 4) {
+        starterPage = this.props.collection.state.currentPage - 1;
+      }
+      var page = 1;
+      if(!this.props.maximumPages || this.props.maximumPages > 
this.props.collection.state.totalPages) {
+        for(page = 1; page <= this.props.collection.state.totalPages; page++){
+          if(page !== this.props.collection.state.currentPage) {
+            pages.push(<li key={page}><a href="javascript: void 0;" 
onClick={this.changePage} data-page={page}>{page}</a></li>);
+          } else {
+            pages.push(<li key={page} className="active"><a href="javascript: 
void 0;" >{page}</a></li>);
+
+          }
+        }
+      } else {
+        if(this.props.collection.state.currentPage >= 4) {
+          pages.push(<li key={1}><a href="javascript: void 0;" 
onClick={this.changePage} data-page={1} >{1}</a></li>);
+          pages.push(<li  key="leftellips" className="disabled"><a 
href="javascript: void 0;">&hellip;</a></li>);
+
+        }
+        for(page = starterPage; page <= 
this.props.collection.state.totalPages; ++page) {
+          if((starterPage + this.props.maximumPages) < page && (page + 
this.props.maximumPages) < this.props.collection.state.totalPages) {
+            pages.push(<li key={'ellips'} className="disabled"><a 
href="javascript: void 0;">&hellip;</a></li>);
+            pages.push(<li key={'collection.state.totalPages'}><a 
href="javascript: void 0;" onClick={this.changePage} 
data-page={this.props.collection.state.totalPages} 
className="">{this.props.collection.state.totalPages}</a></li>);
+            break;
+          } else if (page !== this.props.collection.state.currentPage){
+            pages.push(<li key={page}><a href="javascript: void 0;" 
onClick={this.changePage} data-page={page} className="">{page}</a></li>);
+          } else {
+            pages.push(<li key={page} className="active"><a href="javascript: 
void 0;" >{page}</a></li>);
+
+          }
+        }
+      }
+      return pages;
+
+    },
+    /**
+     * Render function for the previous page button.
+     * If the current page is the first then it shouldn't render a clickable 
previous page
+     */
+    renderPrevious : function() {
+      if(this.props.collection.state.currentPage > 1){
+        return (<li className=""><a href="javascript: void 0;"  ref="prevPage" 
onClick={this.previousPage}>&laquo;</a></li>);
+      }else {
+        return (<li className="disabled"><a href="javascript: void 0;" 
>&laquo;</a></li>);
+      }
+    },
+    renderNumber: function(){
+      var startNumber, endNumber;
+      if(this.props.collection.state.currentPage > 1){
+        startNumber = ((this.props.collection.state.currentPage - 1) * 
Globals.settings.PAGE_SIZE) + 1;
+        endNumber = startNumber + Globals.settings.PAGE_SIZE - 1;
+        if(endNumber > this.props.collection.state.totalRecords){
+          endNumber = this.props.collection.state.totalRecords;
+        }
+      } else {
+        startNumber = 1;
+        if(this.props.collection.state.totalRecords){
+          endNumber = (this.props.collection.state.totalRecords > 
Globals.settings.PAGE_SIZE ? Globals.settings.PAGE_SIZE : 
this.props.collection.state.totalRecords);
+        } else {
+          startNumber = 0;
+          endNumber = 0;
+        }
+      }
+      return (
+        <span className="pull-left">Showing {startNumber} to {endNumber} of 
{this.props.collection.state.totalRecords || 0} entries.</span>
+      );
+    },
+
+    render: function () {
+      var next = this.renderNext();
+      var pages = this.renderPages();
+      var previous = this.renderPrevious();
+      var number = this.renderNumber();
+      return(<div className="clearfix">
+        {number}
+        <ul className="pagination pagination-sm pull-right no-margin">
+          {previous}
+          {pages}
+          {next}
+        </ul>
+      </div>);
+    }
+  });
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/529ef7f7/contrib/views/storm/src/main/resources/scripts/modules/Vent.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/modules/Vent.js 
b/contrib/views/storm/src/main/resources/scripts/modules/Vent.js
deleted file mode 100644
index eebd6d7..0000000
--- a/contrib/views/storm/src/main/resources/scripts/modules/Vent.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements.  See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership.  The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-define(['backbone.wreqr'], function (Wreqr) {
-  "use strict";
-  return new Wreqr.EventAggregator();
-});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/529ef7f7/contrib/views/storm/src/main/resources/scripts/router/Router.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/router/Router.js 
b/contrib/views/storm/src/main/resources/scripts/router/Router.js
index 98007e7..24fc1e0 100644
--- a/contrib/views/storm/src/main/resources/scripts/router/Router.js
+++ b/contrib/views/storm/src/main/resources/scripts/router/Router.js
@@ -1,97 +1,99 @@
 /**
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements.  See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership.  The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License.  You may obtain a copy of the License at
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
 *
-*     http://www.apache.org/licenses/LICENSE-2.0
+     http://www.apache.org/licenses/LICENSE-2.0
 *
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
 */
 
 define([
-       'jquery',
-       'underscore',
+       'require',
        'backbone',
-       'utils/Utils',
-       'App'
-], function($, _, Backbone, Utils, App) {
+       'react',
+       'react-dom',
+       'utils/Utils'
+], function(require, Backbone, React, ReactDOM, Utils) {       
+       'use strict';
+       var rRender;
        var AppRouter = Backbone.Router.extend({
                routes: {
-                       // Define some URL routes
-                       "": 'topologySummaryAction',
-                       "!/topology": 'topologySummaryAction',
-                       "!/topology/:id": 'topologyDetailAction',
-
-                       // Default
-                       '*actions': 'defaultAction'
+                       ''                                                      
                                                : 'dashboardAction',
+                       '!/dashboard'                                           
                                : 'dashboardAction',
+                       '!/topology'                                            
                                : 'topologyAction',
+                       '!/topology/:id'                                        
                                : 'topologyDetailsAction',
+                       '!/topology/:id/component/:name'                        
                : 'componentDetailsAction',
+                       '!/nimbus'                                              
                                        : 'nimbusAction',
+                       '!/supervisor'                                          
                                : 'supervisorAction',
+                       '*actions'                                              
                                        : 'defaultAction'
                },
-
                initialize: function() {
+                       App.baseURL = Utils.getStormHostDetails();
+                       // App.baseURL = 'http://c6502:8744';
                        this.showRegions();
-                       this.bindRegions();
-                       this.listenTo(this, "route", this.postRouteExecute, 
this);
                },
-
-               showRegions: function () {
-                       require(['views/site/Header'], function (HeaderView) {
-                               App.rHeader.show(new HeaderView());
-                       });
+               showRegions: function() {
+                       this.renderFooter();
                },
-
-               bindRegions: function () {
-                       var that = this;
-                       require(['modules/Vent'], function(vent){
-                               vent.on('Region:showTopologySection', 
function(){
-                                       
App.rCluster.$el.removeClass('active').hide();
-                                       
App.rTopology.$el.addClass('active').show();
-                                       
if(App.rTopology.$el.children().hasClass('topologyDetailView')){
-                                               
that.topologyDetailAction(App.rTopology.currentView.model.get('id'));
-                                       } else {
-                                               that.topologySummaryAction();
-                                       }
-                               });
-
-                               vent.on('Region:showClusterSection', function(){
-                                       
require(['views/Cluster/ClusterSummary'], function(ClusterSummaryView){
-                                               App.rCluster.show(new 
ClusterSummaryView());
-                                       });
-                                       
App.rTopology.$el.removeClass('active').hide();
-                                       
App.rCluster.$el.addClass('active').show();
-                                       vent.trigger('Breadcrumb:Hide');
-                               });
-
+               renderFooter: function(){
+                       require(['jsx!views/Footer'], function(Footer){
+                               ReactDOM.render(React.createElement(Footer), 
App.Footer);
                        });
                },
+               execute: function(callback, args) {
+                       this.preRouteExecute();
+                       if (callback) callback.apply(this, args);
+                       this.postRouteExecute();
+               },
+               preRouteExecute: function() {},
+               postRouteExecute: function(name, args) {},
 
                /**
                 * Define route handlers here
                 */
-               topologySummaryAction: function() {
-                       
require(['views/Topology/TopologySummary'],function(TopologySummaryView){
-        App.rTopology.show(new TopologySummaryView());
-      });
+               
+               dashboardAction: function(){
+                       require(['jsx!views/Dashboard'], 
function(DashboardView){
+                               
ReactDOM.render(React.createElement(DashboardView), App.Container);
+                       });
                },
-
-               topologyDetailAction: function(id) {
-                       require(['views/Topology/TopologyDetail'], 
function(TopologyDetailView){
-                               App.rTopology.show(new TopologyDetailView({
-                                       id: id
-                               }));
+               topologyAction: function(){
+                       require(['jsx!views/TopologyListingView'], 
function(TopologyListingView){
+                               
ReactDOM.render(React.createElement(TopologyListingView), App.Container);
+                       });
+               },
+               topologyDetailsAction: function(id){
+                       require(['jsx!views/TopologyDetailView'], 
function(TopologyDetailView){
+                               
ReactDOM.render(React.createElement(TopologyDetailView, Object.assign({}, 
this.props, {id: id})), App.Container);
+                       }.bind(this));
+               },
+               componentDetailsAction: function(id, name){
+                       require(['jsx!views/ComponentDetailView'], 
function(ComponentDetailView){
+                               
ReactDOM.render(React.createElement(ComponentDetailView, Object.assign({}, 
this.props, {id: id, name: name})), App.Container);
+                       }.bind(this));
+               },
+               nimbusAction: function(){
+                       require(['jsx!views/NimbusSummaryView'], 
function(NimbusSummaryView){
+                               
ReactDOM.render(React.createElement(NimbusSummaryView), App.Container);
+                       });
+               },
+               supervisorAction: function(){
+                       require(['jsx!views/SupervisorSummaryView'], 
function(SupervisorSummaryView){
+                               
ReactDOM.render(React.createElement(SupervisorSummaryView), App.Container);
                        });
                },
-
                defaultAction: function(actions) {
-                       // We have no matching route, lets just log what the 
URL was
-                       console.log('No route:', actions);
-               }
+                       throw new Error("No such route found in the 
application: "+actions);
+               },
        });
 
        return AppRouter;

http://git-wip-us.apache.org/repos/asf/ambari/blob/529ef7f7/contrib/views/storm/src/main/resources/scripts/utils/Globals.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/utils/Globals.js 
b/contrib/views/storm/src/main/resources/scripts/utils/Globals.js
index bfbb873..c28d45f 100644
--- a/contrib/views/storm/src/main/resources/scripts/utils/Globals.js
+++ b/contrib/views/storm/src/main/resources/scripts/utils/Globals.js
@@ -1,30 +1,30 @@
 /**
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements.  See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership.  The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License.  You may obtain a copy of the License at
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
 *
-*     http://www.apache.org/licenses/LICENSE-2.0
+     http://www.apache.org/licenses/LICENSE-2.0
 *
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
 */
 
-define(['require', 'App'], function (require, App) {
+define(['require'], function (require) {
   'use strict';
+       var Globals = {};
 
-  var Globals = {};
+       Globals.baseURL = App.baseURL;
 
-  Globals.baseURL = App.baseUrl;
+       Globals.settings = {
+               PAGE_SIZE: 25
+       };
 
-  Globals.settings = {};
-  Globals.settings.refreshInterval = 60000;
-
-  return Globals;
+       return Globals;
 });
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/529ef7f7/contrib/views/storm/src/main/resources/scripts/utils/LangSupport.js
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/utils/LangSupport.js 
b/contrib/views/storm/src/main/resources/scripts/utils/LangSupport.js
deleted file mode 100644
index 79822c7..0000000
--- a/contrib/views/storm/src/main/resources/scripts/utils/LangSupport.js
+++ /dev/null
@@ -1,116 +0,0 @@
-/**
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements.  See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership.  The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-define(['require', 'modules/Vent', 'globalize', 'gblMessages/message/en'], 
function(require, vent, Globalize) {
-  'use strict';
-
-  var localization = {};
-
-  //This is just to suppress validation Engine Error when app starts
-  $.fn.validationEngine = function() {};
-
-  function setCulture(culture) {
-    if (typeof culture !== 'undefined') {
-      localization.culture = culture;
-    } else {
-      localization.culture = "en";
-    }
-    Globalize.culture(localization.culture);
-  };
-
-  localization.setDefaultCulture = function() {
-    setCulture();
-  };
-
-  localization.tt = function(label) {
-    var ret = label;
-
-    var str = localization.localize(label, localization.culture);
-    if (typeof str !== 'undefined') {
-      return str;
-    }
-
-    if (localization.culture !== 'en') {
-      if (typeof localization.culture !== 'undefined')
-        ret = (typeof localization.localize(label, "en") === 'undefined') ? 
label : localization.localize(label, "en");
-      else {
-        ret = localization.localize(label, "en");
-      }
-    }
-    return ret;
-  };
-
-  localization.localize = function(key, culture) {
-    return 
localization.byString(Globalize.findClosestCulture(culture).messages, key) || 
Globalize.cultures["default"].messages[key];
-  };
-
-  localization.byString = function(o, s) {
-    s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
-    s = s.replace(/^\./, ''); // strip a leading dot
-    var a = s.split('.');
-    while (a.length) {
-      var n = a.shift();
-      if (n in o) {
-        o = o[n];
-      } else {
-        return;
-      }
-    }
-    return o;
-  };
-
-  localization.formatCurrency = function(label) {
-    var str = Globalize.format(parseFloat(label), 'c');
-    if (typeof str !== 'undefined') {
-      return str;
-    }
-  };
-
-  localization.getMonthsAbbr = function() {
-    return Globalize.culture().calendars.standard.months.namesAbbr;
-  };
-
-  localization.getDaysOfWeek = function(label) {
-    return Globalize.culture().calendars.standard.days.namesAbbr;
-  };
-
-  localization.chooseCulture = function(culture) {
-    var dfd = $.Deferred();
-    dfd.done(function(validationMessages) {
-      setCulture(culture);
-      vent.trigger('Layouts:rerender');
-    });
-    switch (culture) {
-      default: require(['gblMessages/message/en'], function() {
-        dfd.resolve('');
-        console.log('Language Changed to en');
-      });
-      break;
-    }
-  };
-
-  localization.formatDate = function(val, format) {
-    if (!val) return "";
-    require(['utils/Utils'], function(Utils) {
-      var valDate = Util.DBToDateObj(val);
-      return Globalize.format(valDate, format, localization.culture);
-    });
-  };
-
-  return localization;
-});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/529ef7f7/contrib/views/storm/src/main/resources/scripts/utils/Overrides.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/utils/Overrides.js 
b/contrib/views/storm/src/main/resources/scripts/utils/Overrides.js
index 251e2d4..7bb6b3f 100644
--- a/contrib/views/storm/src/main/resources/scripts/utils/Overrides.js
+++ b/contrib/views/storm/src/main/resources/scripts/utils/Overrides.js
@@ -1,299 +1,33 @@
 /**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-define(['require',
-  'utils/Globals',
-  'utils/Utils',
-  'backgrid',
-  'bootstrap.filestyle',
-  'backbone.forms'
-], function(require, Globals, Utils) {
-  'use strict';
-
-  /**********************************************************************
-   *                      Backgrid related                              *
-   **********************************************************************/
-
-  /*
-   * HtmlCell renders any html code
-   * @class Backgrid.HtmlCell
-   * @extends Backgrid.Cell
-   */
-  var HtmlCell = Backgrid.HtmlCell = Backgrid.Cell.extend({
-
-    /** @property */
-    className: "html-cell",
-
-    render: function() {
-      this.$el.empty();
-      var rawValue = this.model.get(this.column.get("name"));
-      var formattedValue = this.formatter.fromRaw(rawValue, this.model);
-      this.$el.append(formattedValue);
-      this.delegateEvents();
-      return this;
-    }
-  });
-
-  var UriCell = Backgrid.UriCell = Backgrid.Cell.extend({
-    className: "uri-cell",
-    title: null,
-    target: "_blank",
-
-    initialize: function(options) {
-      UriCell.__super__.initialize.apply(this, arguments);
-      this.title = options.title || this.title;
-      this.target = options.target || this.target;
-    },
-
-    render: function() {
-      this.$el.empty();
-      var rawValue = this.model.get(this.column.get("name"));
-      var href = _.isFunction(this.column.get("href")) ? 
this.column.get('href')(this.model) : this.column.get('href');
-      var klass = this.column.get("klass");
-      var formattedValue = this.formatter.fromRaw(rawValue, this.model);
-      this.$el.append($("<a>", {
-        tabIndex: -1,
-        href: href,
-        title: this.title || formattedValue,
-        'class': klass
-      }).text(formattedValue));
-
-      if (this.column.has("iconKlass")) {
-        var iconKlass = this.column.get("iconKlass");
-        var iconTitle = this.column.get("iconTitle");
-        this.$el.find('a').append('<i class="' + iconKlass + '" title="' + 
iconTitle + '"></i>');
-      }
-      this.delegateEvents();
-      return this;
-    }
-
-  });
-
-
-  /**
-     Renders a checkbox for Provision Table Cell.
-     @class Backgrid.CheckboxCell
-     @extends Backgrid.Cell
-  */
-  Backgrid.CheckboxCell = Backgrid.Cell.extend({
-
-    /** @property */
-    className: "select-cell",
-
-    /** @property */
-    tagName: "td",
-
-    /** @property */
-    events: {
-      "change input[type=checkbox]": "onChange",
-      "click input[type=checkbox]": "enterEditMode"
-    },
-
-    /**
-       Initializer. If the underlying model triggers a `select` event, this 
cell
-       will change its checked value according to the event's `selected` value.
-
-       @param {Object} options
-       @param {Backgrid.Column} options.column
-       @param {Backbone.Model} options.model
-    */
-    initialize: function(options) {
-
-      this.column = options.column;
-      if (!(this.column instanceof Backgrid.Column)) {
-        this.column = new Backgrid.Column(this.column);
-      }
-
-      if (!this.column.has("checkedVal")) {
-        this.column.set("checkedVal", "true"); // it is not a boolean value 
for EPM
-        this.column.set("uncheckedVal", "false");
-      }
-
-      var column = this.column,
-        model = this.model,
-        $el = this.$el;
-      this.listenTo(column, "change:renderable", function(column, renderable) {
-        $el.toggleClass("renderable", renderable);
-      });
-
-      if (Backgrid.callByNeed(column.renderable(), column, model)) {
-        $el.addClass("renderable");
-      }
-
-      this.listenTo(model, "change:" + column.get("name"), function() {
-        if (!$el.hasClass("editor")) {
-          this.render();
-        }
-      });
-
-      this.listenTo(model, "backgrid:select", function(model, selected) {
-        this.$el.find("input[type=checkbox]").prop("checked", 
selected).change();
-      });
-
-
-    },
-
-    /**
-       Focuses the checkbox.
-    */
-    enterEditMode: function() {
-      this.$el.find("input[type=checkbox]").focus();
-    },
-
-    /**
-       Unfocuses the checkbox.
-    */
-    exitEditMode: function() {
-      this.$el.find("input[type=checkbox]").blur();
-    },
-
-    /**
-       When the checkbox's value changes, this method will trigger a Backbone
-       `backgrid:selected` event with a reference of the model and the
-       checkbox's `checked` value.
-    */
-    onChange: function() {
-      var checked = this.$el.find("input[type=checkbox]").prop("checked");
-      this.model.set(this.column.get("name"), checked);
-      this.model.trigger("backgrid:selected", this.model, checked);
-    },
-
-    /**
-       Renders a checkbox in a table cell.
-    */
-    render: function() {
-      var model = this.model,
-        column = this.column;
-      var val = (model.get(column.get("name")) === column.get("checkedVal") || 
model.get(column.get("name")) === true) ? true : false;
-      var editable = Backgrid.callByNeed(column.editable(), column, model);
-
-      this.$el.empty();
-
-      this.$el.append($("<input>", {
-        tabIndex: -1,
-        type: "checkbox",
-        checked: val,
-        disabled: !editable
-      }));
-      this.delegateEvents();
-      return this;
-    }
-
-  });
-
-  Backbone.Form.editors.Fileupload = Backbone.Form.editors.Base.extend({
-    initialize: function(options) {
-      Backbone.Form.editors.Base.prototype.initialize.call(this, options);
-      this.template = _.template('<input type="file" name="fileInput" 
class="filestyle">');
-    },
-    render: function() {
-      this.$el.html(this.template);
-      this.$(":file").filestyle();
-      return this;
-    },
-    getValue: function() {
-      return $('input[name="fileInput"]')[0].files[0];
-    }
-  });
-
-  Backbone.ajax = function() {
-    var urlPart = arguments[0].url.split('url=')[0];
-    var stormUrlPart = arguments[0].url.split('url=')[1];
-    urlPart += 'url=' + encodeURIComponent(stormUrlPart);
-    arguments[0].url = urlPart;
-    return Backbone.$.ajax.apply(Backbone.$, arguments);
-  };
-
-  Backbone.Form.editors.RangeSlider = Backbone.Form.editors.Base.extend({
-    ui: {
-
-    },
-    events: {
-      'change #from': 'evChange',
-    },
-
-    initialize: function(options) {
-      this.options = options;
-      Backbone.Form.editors.Base.prototype.initialize.call(this, options);
-      this.template = _.template('<div id="scoreSlider" style="width: 50%; 
float: left; margin-top: 5px;" class="ui-slider ui-slider-horizontal ui-widget 
ui-widget-content ui-corner-all" aria-disabled="false"><div 
class="ui-slider-range ui-widget-header ui-corner-all" style="left: 0%; width: 
100%; "></div><a class="ui-slider-handle ui-state-default ui-corner-all" 
href="#" style="left: 0%; "></a></div><input type="number" id="from" 
class="input-mini" style="float:left; width: 60px; margin-left: 15px;" 
placeholder="0"/><div id="sliderLegend" style="width: 50%"><label 
id="startLabel" style="float: left;">0</label><label id="endLabel" 
style="float: right;">0</label></div>');
-    },
-
-    evChange: function(e) {
-      var val = e.currentTarget.value;
-      if (val == '') {
-        val = '0';
-      }
-
-      var sanitized = val.replace(/[^0-9]/g, '');
-
-      if (_.isNumber(parseInt(sanitized, 10))) {
-        if (sanitized < this.options.schema.options.max) {
-          $(e.currentTarget).val(sanitized);
-          this.$('#scoreSlider').slider('value', sanitized);
-        } else {
-          $(e.currentTarget).val(this.options.schema.options.max);
-          this.$('#scoreSlider').slider('value', 
this.options.schema.options.max);
-        }
-      }
-
-    },
-
-    /**
-     * Adds the editor to the DOM
-     */
-    render: function() {
-      this.$el.html(this.template);
-      this.setupSlider(this.options.schema.options);
-      if (this.value)
-        this.setValue(this.value);
-      return this;
-    },
-
-    getValue: function() {
-      return {
-        min: this.$("#from").val(),
-      };
-    },
-
-    setValue: function(value) {
-      this.$("#from").val(value);
-      return this.$('#scoreSlider').slider('value');
-    },
-    setupSlider: function(options) {
-      var that = this;
-      var minVal = options && options.min ? options.min : 0,
-        maxVal = options && options.max ? options.max : 0;
-      this.$('#scoreSlider').slider({
-        range: "max",
-        min: minVal,
-        max: maxVal,
-        value: this.value,
-        slide: function(event, ui) {
-          that.$("#from").val(ui.value);
-        }
-      });
-      this.$('#startLabel').text(minVal);
-      this.$('#endLabel').text(maxVal);
-      this.$('#from').attr("min", minVal);
-      this.$('#from').attr("max", maxVal);
-      if (this.options.schema.minEditorClass)
-        this.$('#from').addClass(this.options.schema.minEditorClass);
-    }
-  });
-
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+*
+     http://www.apache.org/licenses/LICENSE-2.0
+*
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+define(['backbone'], function(Backbone){
+       'use strict';
+       
+       // $('.loader').hide();
+       
+       Backbone.ajax = function() {
+               if(!arguments[0].data){
+                       var urlPart = arguments[0].url.split('url=')[0];
+                   var stormUrlPart = arguments[0].url.split('url=')[1];
+                   urlPart += 'url=' + encodeURIComponent(stormUrlPart);
+                   arguments[0].url = urlPart;
+               }
+           return Backbone.$.ajax.apply(Backbone.$, arguments);
+       };
 });
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/529ef7f7/contrib/views/storm/src/main/resources/scripts/utils/TableLayout.js
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/utils/TableLayout.js 
b/contrib/views/storm/src/main/resources/scripts/utils/TableLayout.js
deleted file mode 100644
index d827601..0000000
--- a/contrib/views/storm/src/main/resources/scripts/utils/TableLayout.js
+++ /dev/null
@@ -1,106 +0,0 @@
-/**
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements.  See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership.  The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-/**************************************************************************
--- Purpose: @file This is the common View file for displaying Table/Grid to be 
used overall in the application.
-**************************************************************************/
-
-define([
-  'require',
-  'utils/LangSupport'
-], function (require, Localize) {
-  'use strict';
-
-
-  var TablelayoutTmpl = '<div>'+
-                        '<div class="position-relative col-md-12">'+
-                          '<div data-id="r_tableList" class="table-responsive 
tableBorder"> </div>'+
-                          '<div data-id="r_tableSpinner"></div>'+
-                        '</div>'+
-                        '</div>';
-
-  var TableLayout = Marionette.LayoutView.extend(
-    /** @lends TableLayout */
-    {
-      _viewName: 'TableLayout',
-
-      template: TablelayoutTmpl,
-
-      /** Layout sub regions */
-      regions: {
-        'rTableList': 'div[data-id="r_tableList"]',
-        'rTableSpinner': 'div[data-id="r_tableSpinner"]'
-      },
-
-      /** ui selector cache */
-      ui: {},
-
-      defaultGrid: {
-        className: 'table table-bordered table-hover table-condensed backgrid',
-        emptyText: 'No Records found!'
-      },
-
-      /** ui events hash */
-      events: function () {},
-
-      /**
-       * intialize a new HDTableLayout Layout
-       * @constructs
-       */
-      initialize: function (options) {
-        _.extend(this, _.pick(options, 'collection', 'columns'));
-        this.gridOpts = _.clone(this.defaultGrid,{});
-        _.extend(this.gridOpts, options.gridOpts, {
-          collection: this.collection,
-          columns: this.columns
-        });
-
-        this.bindEvents();
-      },
-
-      /** all events binding here */
-      bindEvents: function () {
-        this.listenTo(this.collection, 'request', function () {
-          this.$('div[data-id="r_tableSpinner"]').addClass('loading');
-        }, this);
-        this.listenTo(this.collection, 'sync', function () {
-          this.$('div[data-id="r_tableSpinner"]').removeClass('loading');
-        }, this);
-        this.listenTo(this.collection, 'error', function () {
-          this.$('div[data-id="r_tableSpinner"]').removeClass('loading');
-        }, this);
-      },
-
-      /** on render callback */
-      onRender: function () {
-        this.renderTable();
-      },
-
-      /**
-       * show table
-       */
-      renderTable: function () {
-        this.rTableList.show(new Backgrid.Grid(this.gridOpts));
-      },
-
-      /** on close */
-      onClose: function () {},
-    });
-
-  return TableLayout;
-});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/529ef7f7/contrib/views/storm/src/main/resources/scripts/utils/Utils.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/utils/Utils.js 
b/contrib/views/storm/src/main/resources/scripts/utils/Utils.js
index 72080d5..56a42a6 100644
--- a/contrib/views/storm/src/main/resources/scripts/utils/Utils.js
+++ b/contrib/views/storm/src/main/resources/scripts/utils/Utils.js
@@ -1,133 +1,172 @@
 /**
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements.  See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership.  The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License.  You may obtain a copy of the License at
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
 *
-*     http://www.apache.org/licenses/LICENSE-2.0
+     http://www.apache.org/licenses/LICENSE-2.0
 *
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
 */
 
-define(['require', 'utils/LangSupport', 'bootstrap.notify'], function(require, 
localization) {
-  'use strict';
+define(['require',
+    'react',
+    'react-dom',
+    'bootbox',
+    'bootstrap',
+    'bootstrap-notify'], function(require, React, ReactDOM, bootbox) {
+    'use strict';
+    var Utils = {};
 
-  var Utils = {};
-
-  Utils.defaultErrorHandler = function(model, error) {
-    if (error.status == 401) {
-      console.log("ERROR 401 occured.");
-    }
-  };
+    Utils.getStormHostDetails = function() {
+        var url = location.pathname + 'proxy?url=';
+        $.ajax({
+            url: '/api/v1/clusters/',
+            cache: false,
+            type: 'GET',
+            async: false,
+            success: function(response) {
+                var result = JSON.parse(response);
+                if (_.isArray(result.items) && result.items.length) {
+                    var flag = false;
+                    _.each(result.items, function(object) {
+                        if (!flag) {
+                            $.ajax({
+                                url: object.href,
+                                type: 'GET',
+                                async: false,
+                                success: function(res) {
+                                    var config = JSON.parse(res);
+                                    var hostname;
+                                    _.each(config.alerts, function(obj) {
+                                        if (obj.Alert.service_name === "STORM" 
&& obj.Alert.definition_name === "storm_webui") {
+                                            hostname = obj.Alert.host_name;
+                                        }
+                                    });
+                                    if (_.isUndefined(hostname) || hostname == 
"") {
+                                        console.log("Error detected while 
fetching storm hostname and port number");
+                                    } else {
+                                        var obj = 
_.findWhere(config.service_config_versions, { "service_name": "STORM" });
+                                        if (!_.isUndefined(obj)) {
+                                            var stormConfig = 
_.findWhere(obj.configurations, { "type": "storm-site" });
+                                            if (!_.isUndefined(stormConfig)) {
+                                                flag = true;
+                                                url += 'http://' + hostname + 
':' + stormConfig.properties['ui.port'];
+                                            } else {
+                                                console.log("Error detected 
while fetching storm hostname and port number");
+                                            }
+                                        } else {
+                                            console.log("Error detected while 
fetching storm hostname and port number");
+                                        }
+                                    }
+                                },
+                                error: function(res) {
+                                    console.log("Error detected while fetching 
storm hostname and port number");
+                                }
+                            });
+                        }
+                    });
+                } else {
+                    console.log("Currently, no service is configured in 
ambari");
+                }
+            },
+            error: function(error) {
+                console.log("Error detected while fetching storm hostname and 
port number");
+            }
+        });
+        return url;
+    };
 
-  Utils.uploadFile = function(restURL, data, successCallback, errorCallback){
-    $.ajax({
-        url: restURL,
-        data: data,
-        cache: false,
-        contentType: false,
-        processData: false,
-        type: 'POST',
-        success: successCallback,
-        error: errorCallback
-      });
-  };
+    Utils.ArrayToCollection = function(array, collection){
+        if(array.length){
+            array.map(function(obj){
+                collection.add(new Backbone.Model(obj));
+            });
+        }
+        return collection;
+    };
 
-  Utils.notifyError = function(message){
-    $('.top-right').notify({
-      message: { html: "<i class='fa fa-warning'></i> " + message},
-      type: 'danger',
-      closable: true,
-      transition: 'fade',
-      fadeOut: { enabled: true, delay: 3000 }
-    }).show();
-  };
+    Utils.ConfirmDialog = function(message, title, successCallback, 
cancelCallback) {
+        bootbox.dialog({
+            message: message,
+            title: title,
+            className: 'confirmation-dialog',
+            buttons: {
+                cancel: {
+                    label: 'No',
+                    className: 'btn-default btn-small',
+                    callback: cancelCallback ? cancelCallback : function(){}
+                },
+                success: {
+                    label: 'Yes',
+                    className: 'btn-success btn-small',
+                    callback: successCallback
+                }
+            }
+        });
+    };
 
-  Utils.notifySuccess = function(message){
-    $('.top-right').notify({
-      message: { html: "<i class='fa fa-check'></i> " + message},
-      type: 'success',
-      closable: true,
-      transition: 'fade',
-      fadeOut: { enabled: true, delay: 3000 }
-    }).show();
-  };
+    Utils.notifyError = function(message) {
+        $.notify({
+            icon: 'fa fa-warning',
+            message: message
+        },{
+            type: 'danger',
+            allow_dismiss: true,
+            animate: {
+                enter: 'animated fadeInDown',
+                exit: 'animated fadeOutUp'
+            }
+        });
+    };
+    Utils.notifySuccess = function(message) {
+        $.notify({
+            icon: 'fa fa-check',
+            message: message
+        },{
+            type: 'success',
+            allow_dismiss: true,
+            animate: {
+                enter: 'animated fadeInDown',
+                exit: 'animated fadeOutUp'
+            }
+        });
+    };
 
-  Utils.notifyInfo = function(message){
-    $('.top-right').notify({
-      message: { html: "<i class='fa fa-info'></i> " + message},
-      type: 'warning',
-      closable: true,
-      transition: 'fade',
-      fadeOut: { enabled: true, delay: 3000 }
-    }).show();
-  };
+    Utils.notifyInfo = function(message) {
+        $.notify({
+            icon: 'fa fa-info',
+            message: message
+        },{
+            type: 'info',
+            allow_dismiss: true,
+            animate: {
+                enter: 'animated fadeInDown',
+                exit: 'animated fadeOutUp'
+            }
+        });
+    };
 
-  Utils.getStormHostDetails = function(){
-    var url = location.pathname+'proxy?url=';
-    $.ajax({
-      url: '/api/v1/clusters/',
-      cache: false,
-      type: 'GET',
-      async: false,
-      success: function(response){
-        var result = JSON.parse(response);
-        if(_.isArray(result.items) && result.items.length){
-          var flag = false;
-          _.each(result.items, function(object){
-            if(!flag){
-              $.ajax({
-                url: object.href,
-                type: 'GET',
-                async: false,
-                success: function(res){
-                  var config = JSON.parse(res);
-                  var hostname;
-                  _.each(config.alerts, function(obj){
-                    if(obj.Alert.service_name === "STORM" && 
obj.Alert.definition_name === "storm_webui"){
-                      hostname = obj.Alert.host_name;
-                    }
-                  });
-                  if(_.isUndefined(hostname) || hostname == ""){
-                    Utils.notifyError(localization.tt('msg.stormNotRunning'));
-                  } else {
-                    var obj = _.findWhere(config.service_config_versions, 
{"service_name": "STORM"});
-                    if(!_.isUndefined(obj)){
-                      var stormConfig = _.findWhere(obj.configurations, 
{"type": "storm-site"});
-                      if(! _.isUndefined(stormConfig)){
-                        flag = true;
-                        url += 
'http://'+hostname+':'+stormConfig.properties['ui.port'];
-                      } else {
-                        
Utils.notifyError(localization.tt('msg.stormNotRunning'));
-                      }
-                    } else {
-                      
Utils.notifyError(localization.tt('msg.stormNotRunning'));
-                    }
-                  }
-                },
-                error: function(res){
-                  Utils.notifyError(localization.tt('msg.stormNotRunning'));
-                }
-              });
+    Utils.notifyWarning = function(message) {
+        $.notify({
+            icon: 'fa fa-warning',
+            message: message
+        },{
+            type: 'warning',
+            allow_dismiss: true,
+            animate: {
+                enter: 'animated fadeInDown',
+                exit: 'animated fadeOutUp'
             }
-          });
-        } else {
-          Utils.notifyError(localization.tt('msg.stormNotConfigured'));
-        }
-      },
-      error: function(error){
-        Utils.notifyError(localization.tt('msg.stormNotRunning'));
-      }
-    });
-    return url;
-  };
+        });
+    };
 
-  return Utils;
-});
\ No newline at end of file
+    return Utils;
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/529ef7f7/contrib/views/storm/src/main/resources/scripts/views/Cluster/ClusterSummary.js
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/views/Cluster/ClusterSummary.js
 
b/contrib/views/storm/src/main/resources/scripts/views/Cluster/ClusterSummary.js
deleted file mode 100644
index 540f2f6..0000000
--- 
a/contrib/views/storm/src/main/resources/scripts/views/Cluster/ClusterSummary.js
+++ /dev/null
@@ -1,353 +0,0 @@
-/**
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements.  See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership.  The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-define(['require',
-  'modules/Vent',
-  'models/Cluster',
-  'models/VNimbus',
-  'models/VSupervisor',
-  'models/VNimbusConfig',
-  'utils/TableLayout',
-  'utils/LangSupport',
-  'utils/Globals',
-  'utils/Utils',
-  'hbs!tmpl/cluster/clusterSummary',
-  'backgrid'
-], function(require, vent, vCluster, vNimbus, vSupervisor, vNimbusConfig, 
TableLayout, localization, Globals, Utils, tmpl) {
-  'use strict';
-
-  var ClusterSummaryTableLayout = Marionette.LayoutView.extend({
-
-    template: tmpl,
-
-    templateHelpers: function() {},
-
-    ui: {
-
-      clusterSummaryDetails: '[data-id="clusterSummary"]',
-      nbsSummaryDetails: '[data-id="nbsSummary"]',
-      sprsSummaryDetails: '[data-id="sprSummary"]',
-      nbsConfigDetails: '[data-id="nbsConfig"]'
-    },
-
-    regions: {
-      'rCluster': '#clusterSummaryTable',
-      'rNbsList': '#nbsSummaryTable',
-      'rSprList': '#sprSummaryTable',
-      'rnbsConfigList': '#nbsConfigTable'
-    },
-
-    initialize: function() {
-      this.clusterModel = new vCluster();
-      this.supervisorModel = new vSupervisor();
-      this.nimbusSummaryModel = new vNimbus();
-      this.nimbusConfigModel = new vNimbusConfig();
-
-      this.clusterCollection = new Backbone.Collection();
-      this.sprCollection = new Backbone.Collection();
-      this.nimbusConfigCollection = new Backbone.Collection();
-      this.nbsCollection = new Backbone.Collection();
-
-    },
-
-    onRender: function() {
-      this.showCtrSummary(this.clusterCollection);
-      this.showNbsSummary(this.nbsCollection);
-      this.showSprSummary(this.sprCollection);
-      this.showNbsConSummary(this.nimbusConfigCollection);
-      this.fetchData();
-
-      this.$('.collapse').on('shown.bs.collapse', function() {
-        
$(this).parent().find(".fa-plus-square").removeClass("fa-plus-square").addClass("fa-minus-square");
-      }).on('hidden.bs.collapse', function() {
-        
$(this).parent().find(".fa-minus-square").removeClass("fa-minus-square").addClass("fa-plus-square");
-      });
-
-    },
-    fetchData: function() {
-      this.getClusterSummary(this.clusterModel);
-      this.getSupervisorSummary(this.supervisorModel);
-      this.getNimbusConfig(this.nimbusConfigModel);
-      this.getNimbusSummary(this.nimbusSummaryModel);
-    },
-
-    getClusterSummary: function(model) {
-      var that = this;
-      this.clusterCollection.trigger('request', this.clusterCollection);
-      model.fetch({
-        success: function(model, response, options) {
-          vent.trigger('LastUpdateRefresh');
-          that.clusterCollection.trigger('sync', that.clusterCollection);
-          if (model) {
-            that.clusterCollection.reset(model);
-          }
-        },
-        error: function(model, response, options) {
-          vent.trigger('LastUpdateRefresh');
-          that.clusterCollection.trigger('error', that.clusterCollection);
-          Utils.notifyError(response.statusText);
-          return null;
-        }
-      });
-    },
-
-    getSupervisorSummary: function(model) {
-      var that = this;
-      this.sprCollection.trigger('request', this.sprCollection);
-      model.fetch({
-        success: function(model, response, options) {
-          vent.trigger('LastUpdateRefresh');
-          that.sprCollection.trigger('sync', that.sprCollection);
-          if (model.has('supervisors') && model.get('supervisors').length) {
-            var arr = [];
-            _.each(model.get('supervisors'), function(object) {
-              arr.push(new vSupervisor(object))
-            });
-            that.sprCollection.reset(arr);
-          }
-        },
-        error: function(model, response, options) {
-          vent.trigger('LastUpdateRefresh');
-          that.sprCollection.trigger('error', that.sprCollection);
-          Utils.notifyError(response.statusText);
-        }
-      });
-    },
-
-    getNimbusConfig: function(model) {
-      var that = this;
-      this.nimbusConfigCollection.trigger('request', 
this.nimbusConfigCollection);
-      model.fetch({
-        success: function(model, response, options) {
-          vent.trigger('LastUpdateRefresh');
-          that.nimbusConfigCollection.trigger('sync', 
that.nimbusConfigCollection);
-          if (model) {
-            var arr = [];
-            for(var key in model.attributes){
-              var obj = {};
-              obj.key = key;
-              obj.value = model.get(key);
-              arr.push(new vNimbusConfig(obj));
-            }
-            that.nimbusConfigCollection.reset(arr);
-          }
-        },
-        error: function(model, response, options) {
-          vent.trigger('LastUpdateRefresh');
-          that.nimbusConfigCollection.trigger('error', 
that.nimbusConfigCollection);
-          Utils.notifyError(response.statusText);
-        }
-      });
-    },
-
-    getNimbusSummary: function(model){
-      var that = this;
-      this.nbsCollection.trigger('request', this.nbsCollection);
-      model.fetch({
-        success: function(model, response, options) {
-          vent.trigger('LastUpdateRefresh');
-          that.nbsCollection.trigger('sync', that.nbsCollection);
-          if (model.has('nimbuses') && model.get('nimbuses').length) {
-            var arr = [];
-            _.each(model.get('nimbuses'), function(object) {
-              arr.push(new vNimbus(object))
-            });
-            that.nbsCollection.reset(arr);
-          }
-        },
-        error: function(model, response, options) {
-          vent.trigger('LastUpdateRefresh');
-          that.nbsCollection.trigger('error', that.nbsCollection);
-          Utils.notifyError(response.statusText);
-        }
-      });
-    },
-
-    showCtrSummary: function(collection) {
-      this.rCluster.show(new TableLayout({
-        columns: this.getCtrColumns(),
-        collection: collection,
-        gridOpts: {
-          emptyText: localization.tt('msg.noClusterFound'),
-          className: 'table table-borderless table-striped cluster-table'
-        }
-      }));
-    },
-
-    showNbsSummary: function(collection) {
-      this.rNbsList.show(new TableLayout({
-        columns: this.getNbsColumns(),
-        collection: this.nbsCollection,
-        gridOpts: {
-          emptyText: localization.tt('msg.noNimbusFound'),
-          className: 'table table-borderless table-striped cluster-table'
-        }
-      }));
-    },
-
-    showSprSummary: function(collection) {
-      this.rSprList.show(new TableLayout({
-        columns: this.getSprColumns(),
-        collection: collection,
-        gridOpts: {
-          emptyText: localization.tt('msg.noSupervisorFound'),
-          className: 'table table-borderless table-striped cluster-table'
-        }
-      }));
-    },
-
-    showNbsConSummary: function(collection) {
-      this.rnbsConfigList.show(new TableLayout({
-        columns: this.getNbsConColumns(),
-        collection: collection,
-        gridOpts: {
-          emptyText: localization.tt('msg.noNimbusConfigFound'),
-          className: 'table table-borderless table-striped cluster-table'
-        }
-      }));
-    },
-
-    getCtrColumns: function() {
-      return [{
-        name: "supervisors",
-        cell: "string",
-        label: localization.tt("lbl.supervisors"),
-        hasTooltip: true,
-        tooltipText: localization.tt('msg.clusterSummarySupervisors')
-
-      }, {
-        name: "slotsUsed",
-        cell: "string",
-        label: localization.tt("lbl.usedSlots"),
-        hasTooltip: true,
-        tooltipText: localization.tt('msg.clusterSummarySlots')
-      }, {
-        name: "slotsFree",
-        cell: "string",
-        label: localization.tt("lbl.freeSlots"),
-        hasTooltip: true,
-        tooltipText: localization.tt('msg.clusterSummarySlots')
-
-      }, {
-        name: "slotsTotal",
-        cell: "string",
-        label: localization.tt("lbl.totalSlots"),
-        hasTooltip: true,
-        tooltipText: localization.tt('msg.clusterSummarySlots')
-      }, {
-        name: "executorsTotal",
-        cell: "string",
-        label: localization.tt("lbl.executors"),
-        hasTooltip: true,
-        tooltipText: localization.tt('msg.clusterSummaryExecutors')
-      }, {
-        name: "tasksTotal",
-        cell: "string",
-        label: localization.tt("lbl.tasks"),
-        hasTooltip: true,
-        tooltipText: localization.tt('msg.clusterSummaryTasks')
-      }];
-    },
-
-    getNbsColumns: function() {
-      return [{
-          name: "host",
-          cell: "string",
-          label: localization.tt("lbl.host")
-        }, {
-          name: "port",
-          cell: "string",
-          label: localization.tt("lbl.port")
-        }, {
-          name: "status",
-          cell: "string",
-          label: localization.tt("lbl.status")
-        }, {
-          name: "version",
-          cell: "string",
-          label: localization.tt("lbl.version")
-        }, {
-          name: "nimbusUpTime",
-          cell: "string",
-          label: localization.tt("lbl.uptimeSeconds")
-        }, {
-          name: "logs",
-          cell: "Html",
-          label: '',
-          formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
-            fromRaw: function(rawValue, model) {
-              if (model) {
-                return "<a href="+model.get('nimbusLogLink')+" target='_blank' 
class='btn btn-success btn-xs 
center-block'>"+localization.tt('lbl.viewLogs')+"</a>";
-              }
-            }
-          })
-        }
-      ];
-    },
-
-    getSprColumns: function() {
-      return [{
-          name: "id",
-          cell: "string",
-          label: localization.tt("lbl.id"),
-          hasTooltip: true,
-          tooltipText: localization.tt('msg.supervisorId')
-        }, {
-          name: "host",
-          cell: "string",
-          label: localization.tt("lbl.host"),
-          hasTooltip: true,
-          tooltipText: localization.tt('msg.supervisorHost')
-        }, {
-          name: "uptime",
-          cell: "string",
-          label: localization.tt("lbl.uptime"),
-          hasTooltip: true,
-          tooltipText: localization.tt('msg.supervisorUptime')
-        }, {
-          name: "slotsTotal",
-          cell: "string",
-          label: localization.tt("lbl.slots"),
-          hasTooltip: true,
-          tooltipText: localization.tt('msg.clusterSummarySlots')
-        }, {
-          name: "slotsUsed",
-          cell: "string",
-          label: localization.tt("lbl.usedSlots"),
-          hasTooltip: true,
-          tooltipText: localization.tt('msg.clusterSummarySlots')
-        }
-      ];
-    },
-
-    getNbsConColumns: function() {
-      var cols = [{
-        name: "key",
-        cell: "string",
-        label: localization.tt("lbl.key"),
-      }, {
-        name: "value",
-        cell: "string",
-        label: localization.tt("lbl.value")
-      }];
-      return cols;
-    }
-
-  });
-  return ClusterSummaryTableLayout;
-});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/529ef7f7/contrib/views/storm/src/main/resources/scripts/views/ComponentDetailView.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/views/ComponentDetailView.jsx 
b/contrib/views/storm/src/main/resources/scripts/views/ComponentDetailView.jsx
new file mode 100644
index 0000000..14f7527
--- /dev/null
+++ 
b/contrib/views/storm/src/main/resources/scripts/views/ComponentDetailView.jsx
@@ -0,0 +1,507 @@
+/**
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+*
+     http://www.apache.org/licenses/LICENSE-2.0
+*
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+define([
+       'jsx!components/Table',
+       'jsx!modules/Table/Pagination',
+       'react',
+       'react-dom',
+       'collections/BaseCollection',
+       'models/VTopology',
+       'jsx!components/Breadcrumbs',
+       'jsx!views/ProfilingView',
+       'utils/Utils',
+       'bootbox',
+       'bootstrap',
+       'bootstrap-switch'
+       ],function(Table, Pagination, React, ReactDOM, BaseCollection, 
VTopology, Breadcrumbs, ProfilingView, Utils, bootbox){
+       'use strict';
+
+       return React.createClass({
+               displayName: 'ComponentDetailView',
+               getInitialState: function(){
+                       this.model = new VTopology({'id': this.props.id});
+                       this.systemFlag = (this.props.name.startsWith('__')) ? 
true : false;
+                       this.windowSize = ':all-time';
+                       this.initializeData();
+                       return {
+                               componentObj: {},
+                               profilingModalOpen: false
+                       };
+               },
+               componentWillMount: function(){
+                       $('.loader').show();
+               },
+               componentWillUpdate: function(){
+                       $('.loader').show();
+                       
$('#collapse-input').off('hidden.bs.collapse').off('shown.bs.collapse');
+                       
$('#collapse-output').off('hidden.bs.collapse').off('shown.bs.collapse');
+                       
$('#collapse-executor').off('hidden.bs.collapse').off('shown.bs.collapse');
+                       
$('#collapse-error').off('hidden.bs.collapse').off('shown.bs.collapse');
+               },
+               componentDidMount: function(){
+                       $(".boot-switch.systemSum").bootstrapSwitch({
+                               size: 'small',
+                               onSwitchChange: function(event, state){
+                                       this.systemFlag = state;
+                                       this.initializeData();
+                               }.bind(this)
+                       });
+
+                       $(".boot-switch.debug").bootstrapSwitch({
+                               size: 'small',
+                               onSwitchChange: function(event, state){
+                                       this.debugAction(state);
+                               }.bind(this)
+                       });
+                       $('.loader').hide();
+               },
+               componentDidUpdate: function(){
+                       $('#collapse-input').on('hidden.bs.collapse', function 
() {
+                               $("#input-box").toggleClass("fa-compress 
fa-expand");
+                       }).on('shown.bs.collapse', function() {
+                               $("#input-box").toggleClass("fa-compress 
fa-expand");
+                       });
+
+                       $('#collapse-output').on('hidden.bs.collapse', function 
() {
+                               $("#output-box").toggleClass("fa-compress 
fa-expand");
+                       }).on('shown.bs.collapse', function() {
+                               $("#output-box").toggleClass("fa-compress 
fa-expand");
+                       });
+
+                       $('#collapse-executor').on('hidden.bs.collapse', 
function () {
+                               $("#executor-box").toggleClass("fa-compress 
fa-expand");
+                       }).on('shown.bs.collapse', function() {
+                               $("#executor-box").toggleClass("fa-compress 
fa-expand");
+                       });
+
+                       $('#collapse-error').on('hidden.bs.collapse', function 
() {
+                               $("#error-box").toggleClass("fa-compress 
fa-expand");
+                       }).on('shown.bs.collapse', function() {
+                               $("#error-box").toggleClass("fa-compress 
fa-expand");
+                       });
+                       $('#modal-profiling').on('hidden.bs.modal', function 
(e) {
+                         this.initializeData();
+                         this.setState({"profilingModalOpen":false});
+                       }.bind(this));
+                       if(this.state.profilingModalOpen){
+                               $('#modal-profiling').modal("show");
+                       }
+                       $('.loader').hide();
+               },
+               initializeData: function(){
+                       this.model.getComponent({
+                               id: this.props.id,
+                               name: this.props.name,
+                               window: this.windowSize,
+                               sys: this.systemFlag,
+                               success: function(model, response){
+                                       if(response.error){
+                                               
Utils.notifyError(response.error);
+                                       } else {
+                                               this.setState({"componentObj": 
model});
+                                       }
+                               }.bind(this),
+                               error: function(model, response, options){
+                                       Utils.notifyError("Error occured in 
fetching topology component data.");
+                               }
+                       });
+               },
+               renderWindowOptions: function(){
+                       var arr = this.state.componentObj.spoutSummary || 
this.state.componentObj.boltStats;
+                       if(arr){
+                               return arr.map(function(object, i){
+                                       return ( <option key={i} 
value={object.window}>{object.windowPretty}</option> );
+                               });
+                       } else {
+                               return null;
+                       }
+               },
+               handleWindowChange: function(e){
+                       this.windowSize = e.currentTarget.value;
+                       this.initializeData();
+               },
+               getLinks: function() {
+                       var links = [
+                               {link: '#!/dashboard', title: 'Dashboard'},
+                               {link: '#!/topology', title: 'Topology 
Listing'},
+                               {link: 
'#!/topology/'+this.state.componentObj.topologyId, title: 
this.state.componentObj.name || ""},
+                               {link: 'javascript:void(0);', title: 
this.state.componentObj.id || ""}
+                               ];
+                       return links;
+               },
+               renderStatsRow: function(){
+                       var spoutFlag = (this.state.componentObj.componentType 
=== 'spout' ? true: false);
+                       var statsArr = this.state.componentObj.spoutSummary || 
this.state.componentObj.boltStats;
+                       if(statsArr){
+                               return statsArr.map(function(stats, i){
+                                       return (
+                                               <tr key={i}>
+                                                       
<td>{stats.windowPretty}</td>
+                                                       <td>{stats.emitted}</td>
+                                                       
<td>{stats.transferred}</td>
+                                                       {spoutFlag ? 
<td>{stats.completeLatency}</td> : null}
+                                                       {!spoutFlag ? 
<td>{stats.executeLatency}</td> : null}
+                                                       {!spoutFlag ? 
<td>{stats.executed}</td> : null}
+                                                       {!spoutFlag ? 
<td>{stats.processLatency}</td> : null}
+                                                       <td>{stats.acked}</td>
+                                                       <td>{stats.failed}</td>
+                                               </tr>
+                                       );
+                               });
+                       }
+               },
+               renderAccordion: function(type, header, searchField, searchCb, 
collection, emptyText, columns, toggleCb){
+                       return ( 
+                               <div className="box">
+                                       <div className="box-header" 
data-toggle="collapse" data-target={"#collapse-"+type} aria-expanded="false" 
aria-controls={"collapse-"+type}>
+                                               <h4>{header} ( 
{this.state.componentObj.windowHint} )</h4>
+                                               <h4 className="box-control">
+                                                       <a 
href="javascript:void(0);" className="primary">
+                                                               <i 
className="fa fa-compress" id={type+"-box"} onClick={toggleCb}></i>
+                                                       </a>
+                                               </h4>
+                                       </div>
+                                       <div className="box-body collapse in" 
id={"collapse-"+type}>
+                               <div className="input-group col-sm-4">
+                                                       <input type="text"  
onKeyUp={searchCb} className="form-control" placeholder={"Search by 
"+searchField} />
+                                                       <span 
className="input-group-btn">
+                                                       <button className="btn 
btn-primary" type="button"><i className="fa fa-search"></i></button>
+                                                       </span>
+                                               </div>
+                               <Table className="table table-striped" 
collection={collection} emptyText={emptyText} columns={columns()} />
+                                               {type === 'error' ? <Pagination 
collection={collection} /> : null}
+                           </div>
+                               </div>
+                       );
+               },
+               renderInputStats: function(){
+                       var inputCollection = 
Utils.ArrayToCollection(this.state.componentObj.inputStats, new 
BaseCollection());
+                       inputCollection.searchFields = ['component'];
+                       var searchCb = function(e){
+                               var value = e.currentTarget.value;
+                               inputCollection.search(value);
+                       };
+                       var toggleCb = function(e){
+                               $("#collapse-input").collapse('toggle');
+                       }
+                       return this.renderAccordion('input', 'Input Stats', 
'component', searchCb, inputCollection, 'No input stats found !', 
this.getInputColumns, toggleCb);
+               },
+               getInputColumns: function(){
+                       return [
+                               {name: 'component', title: 'Component', 
tooltip: 'The ID assigned to a the Component by the Topology.'},
+                               {name: 'stream', title: 'Stream', tooltip: 'The 
name of the Tuple stream given in the Topolgy, or "default" if none was 
given.'},
+                               {name: 'executeLatency', title: 'Execute 
Latency (ms)', tooltip: 'The average time a Tuple spends in the execute method. 
The execute method may complete without sending an Ack for the tuple.'},
+                               {name: 'executed', title: 'Executed', tooltip: 
'The number of incoming Tuples processed.'},
+                               {name: 'processLatency', title: 'Process 
Latency (ms)', tooltip: 'The average time it takes to Ack a Tuple after it is 
first received.  Bolts that join, aggregate or batch may not Ack a tuple until 
a number of other Tuples have been received.'},
+                               {name: 'acked', title: 'Acked', tooltip: 'The 
number of Tuples acknowledged by this Bolt.'},
+                               {name: 'failed', title: 'Failed', tooltip: 'The 
number of tuples Failed by this Bolt.'}
+                       ];
+               },
+               renderOutputStats: function(){
+                       var outputCollection = 
Utils.ArrayToCollection(this.state.componentObj.outputStats, new 
BaseCollection());
+                       outputCollection.searchFields = ['stream'];
+                       var searchCb = function(e){
+                               var value = e.currentTarget.value;
+                               outputCollection.search(value);
+                       };
+                       var toggleCb = function(e){
+                               $("#collapse-output").collapse('toggle');
+                       }
+                       return this.renderAccordion('output', 'Output Stats', 
'stream', searchCb, outputCollection, 'No output stats found !', 
this.getOutputColumns, toggleCb);
+               },
+               getOutputColumns: function(){
+                       if(this.state.componentObj.componentType === 'spout'){
+                               return [
+                                       {name: 'stream', title: 'Stream', 
tooltip: 'The name of the Tuple stream given in the Topolgy, or "default" if 
none was given.'},
+                                       {name: 'emitted', title: 'Emitted', 
tooltip: 'The number of Tuples emitted.'},
+                                       {name: 'transferred', title: 
'Transferred', tooltip: 'The number of Tuples emitted that sent to one or more 
bolts.'},
+                                       {name: 'completeLatency', title: 
'Complete Latency (ms)', tooltip: 'The average time a Tuple "tree" takes to be 
completely processed by the Topology. A value of 0 is expected if no acking is 
done.'},
+                                       {name: 'acked', title: 'Acked', 
tooltip: 'The number of Tuple "trees" successfully processed. A value of 0 is 
expected if no acking is done.'},
+                                       {name: 'failed', title: 'Failed', 
tooltip: 'The number of Tuple "trees" that were explicitly failed or timed out 
before acking was completed. A value of 0 is expected if no acking is done.'}
+                               ];
+                       } else {
+                               return [
+                                       {name: 'stream', title: 'Stream', 
tooltip: 'The name of the Tuple stream given in the Topolgy, or "default" if 
none was given.'},
+                                       {name: 'emitted', title: 'Emitted', 
tooltip: 'The number of Tuples emitted.'},
+                                       {name: 'transferred', title: 
'Transferred', tooltip: 'The number of Tuples emitted that sent to one or more 
bolts.'}
+                               ];
+                       }
+               },
+               renderExecutorStats: function(){
+                       var executorCollection = 
Utils.ArrayToCollection(this.state.componentObj.executorStats, new 
BaseCollection());
+                       executorCollection.searchFields = ['id'];
+                       var searchCb = function(e){
+                               var value = e.currentTarget.value;
+                               executorCollection.search(value);
+                       };
+                       var toggleCb = function(e){
+                               $("#collapse-executor").collapse('toggle');
+                       }
+                       return this.renderAccordion('executor', 'Executor 
Stats', 'id', searchCb, executorCollection, 'No executor stats found !', 
this.getExecutorColumns, toggleCb);
+               },
+               getExecutorColumns: function(){
+                       var self = this;
+                       if(this.state.componentObj.componentType === 'spout'){
+                               return [
+                                       {name: 'id', title: 'Id', tooltip: 'The 
unique executor ID.'},
+                                       {name: 'uptime', title: 'Uptime', 
tooltip: 'The length of time an Executor (thread) has been alive.'},
+                                       {name: 'port', title: 'Host:Port', 
tooltip: 'The hostname reported by the remote host. (Note that this hostname is 
not the result of a reverse lookup at the Nimbus node.) Click on it to open the 
logviewer page for this Worker.', component: React.createClass({
+                                               render: function(){
+                                                       return ( <a 
href={this.props.model.get('workerLogLink')} target="_blank"> 
{this.props.model.get('host')}:{this.props.model.get('port')} </a>);
+                                               }
+                                       })},
+                                       {name: 'emitted', title: 'Emitted', 
tooltip: 'The number of Tuples emitted.'},
+                                       {name: 'transferred', title: 
'Transferred', tooltip: 'The number of Tuples emitted that sent to one or more 
bolts.'},
+                                       {name: 'completeLatency', title: 
'Complete Latency (ms)', tooltip: 'The average time a Tuple "tree" takes to be 
completely processed by the Topology. A value of 0 is expected if no acking is 
done.'},
+                                       {name: 'acked', title: 'Acked', 
tooltip: 'The number of Tuple "trees" successfully processed. A value of 0 is 
expected if no acking is done.'},
+                                       {name: 'failed', title: 'Failed', 
tooltip: 'The number of Tuple "trees" that were explicitly failed or timed out 
before acking was completed. A value of 0 is expected if no acking is done.'},
+                                       {name: 'workerLogLink', title: 'Dumps', 
component: React.createClass({
+                                               render: function(){
+                                                       var link = 
this.props.model.get('workerLogLink');
+                                                       link = 
""+link.split('/log')[0]+"/dumps/"+self.props.id+"/"+this.props.model.get('host')+":"+this.props.model.get('port');
+                                                       return (<a href={link} 
className="btn btn-primary btn-xs" target="_blank"><i className="fa 
fa-file-text"></i></a>);
+                                               }
+                                       })}
+                               ];
+                       } else {
+                               return [
+                                       {name: 'id', title: 'Id', tooltip: 'The 
unique executor ID.'},
+                                       {name: 'uptime', title: 'Uptime', 
tooltip: 'The length of time an Executor (thread) has been alive.'},
+                                       {name: 'port', title: 'Host:Port', 
tooltip: 'The hostname reported by the remote host. (Note that this hostname is 
not the result of a reverse lookup at the Nimbus node.) Click on it to open the 
logviewer page for this Worker.', component: React.createClass({
+                                               render: function(){
+                                                       return ( <a 
href={this.props.model.get('workerLogLink')} target="_blank"> 
{this.props.model.get('host')}:{this.props.model.get('port')} </a>);
+                                               }
+                                       })},
+                                       {name: 'emitted', title: 'Emitted', 
tooltip: 'The number of Tuples emitted.'},
+                                       {name: 'transferred', title: 
'Transferred', tooltip: 'The number of Tuples emitted that sent to one or more 
bolts.'},
+                                       {name: 'capacity', title: 'Capacity 
(last 10m)', tooltip: "If this is around 1.0, the corresponding Bolt is running 
as fast as it can, so you may want to increase the Bolt's parallelism. This is 
(number executed * average execute latency) / measurement time."},
+                                       {name: 'executeLatency', title: 
'Execute Latency (ms)', tooltip: 'The average time a Tuple spends in the 
execute method. The execute method may complete without sending an Ack for the 
tuple.'},
+                                       {name: 'executed', title: 'Executed', 
tooltip: 'The number of incoming Tuples processed.'},
+                                       {name: 'processLatency', title: 
'Process Latency (ms)', tooltip: 'The average time it takes to Ack a Tuple 
after it is first received.  Bolts that join, aggregate or batch may not Ack a 
tuple until a number of other Tuples have been received.'},
+                                       {name: 'acked', title: 'Acked', 
tooltip: 'The number of Tuples acknowledged by this Bolt.'},
+                                       {name: 'failed', title: 'Failed', 
tooltip: 'The number of tuples Failed by this Bolt.'},
+                                       {name: 'workerLogLink', title: 'Dumps', 
component: React.createClass({
+                                               render: function(){
+                                                       var link = 
this.props.model.get('workerLogLink');
+                                                       link = 
""+link.split('/log')[0]+"/dumps/"+self.props.id+"/"+this.props.model.get('host')+":"+this.props.model.get('port');
+                                                       return (<a href={link} 
className="btn btn-primary btn-xs" target="_blank"><i className="fa 
fa-file-text"></i></a>);
+                                               }
+                                       })}
+                               ];
+                       }
+               },
+               renderErrorStats: function(){
+                       var errorCollection = 
Utils.ArrayToCollection(this.state.componentObj.componentErrors, new 
BaseCollection());
+                       errorCollection.searchFields = ['error'];
+                       var searchCb = function(e){
+                               var value = e.currentTarget.value;
+                               errorCollection.search(value);
+                       };
+                       var toggleCb = function(e){
+                               $("#collapse-error").collapse('toggle');
+                       }
+                       return this.renderAccordion('error', 'Error Stats', 
'error', searchCb, errorCollection, 'No errors found !', this.getErrorColumns, 
toggleCb);
+               },
+               getErrorColumns: function(){
+                       return [
+                               {name: 'errorTime', title: 'Time', component: 
React.createClass({
+                                       render: function(){
+                                               
if(this.props.model.get('errorTime') != 0) {
+                                                       var d = new 
Date(this.props.model.get('errorTime')),
+                                                       date = 
d.toLocaleDateString() + ' ' + d.toLocaleTimeString();
+                                                       return 
(<span>{date}</span>);
+                                               } else return (<span></span>);
+                                       }
+                               })},
+                               {name: 'errorPort', title: 'Host:Port', 
component: React.createClass({
+                                       render: function(){
+                                               return ( <a 
href={this.props.model.get('errorWorkerLogLink')} target="_blank"> 
{this.props.model.get('errorHost')}:{this.props.model.get('errorPort')} </a>);
+                                       }
+                               })},
+                               {name: 'error', title: 'Error'}
+                       ];
+               },
+               render: function() {
+                       if(this.state.componentObj.debug){
+                               
$(".boot-switch.debug").bootstrapSwitch('state', true, true);
+                       } else {
+                               
$(".boot-switch.debug").bootstrapSwitch('state', false, true);
+                       }
+                       if(this.systemFlag){
+                               
$(".boot-switch.systemSum").bootstrapSwitch('state', true, true);
+                       } else {
+                               
$(".boot-switch.systemSum").bootstrapSwitch('state', false, true);
+                       }
+                       var spoutFlag = (this.state.componentObj.componentType 
=== 'spout' ? true: false);
+                       return (
+                               <div>                                   
+                                       <Breadcrumbs links={this.getLinks()} />
+                                       <div className="row">
+                                               <div className="col-sm-12">
+                                                       <div className="box 
filter">
+                                                               <div 
className="box-body form-horizontal">
+                                                                       <div 
className="form-group no-margin">
+                                                                               
<label className="col-sm-1 control-label">Window</label>
+                                                                               
<div className="col-sm-2">
+                                                                               
        <select className="form-control" onChange={this.handleWindowChange} 
value={this.windowSize}>
+                                                                               
                {this.renderWindowOptions()}
+                                                                               
        </select>
+                                                                               
</div>
+                                                                               
<label className="col-sm-2 control-label">System Summary</label>
+                                                                               
<div className="col-sm-2">
+                                                                               
        <input className="boot-switch systemSum" type="checkbox" />
+                                                                               
</div>
+                                                                               
<label className="col-sm-1 control-label">Debug</label>
+                                                                               
<div className="col-sm-1">
+                                                                               
        <input className="boot-switch debug" type="checkbox"/>
+                                                                               
</div>
+                                                                               
<div className="col-sm-3 text-right">
+                                                                               
        <div className="btn-group" role="group">
+                                                                               
                <button type="button" className="btn btn-primary" 
onClick={this.handleProfiling} title="Profiling & Debugging" data-rel="tooltip">
+                                                                               
                        <i className="fa fa-cogs"></i>
+                                                                               
                </button>
+                                                                               
        </div>
+                                                                               
</div>
+                                                                       </div>
+                                                               </div>
+                                                       </div>
+                                               </div>
+                                       </div>
+                                       <div className="row">
+                                               <div className="col-sm-4">
+                                                       <div 
className="summary-tile">
+                                                               <div 
className="summary-title">Component Summary</div>
+                                                               <div 
className="summary-body">
+                                                                       
<p><strong>ID: </strong>{this.state.componentObj.id}</p>
+                                                                       
<p><strong>Topology: </strong>{this.state.componentObj.name}</p>
+                                                                       
<p><strong>Executors: </strong>{this.state.componentObj.executors}</p>
+                                                                       
<p><strong>Tasks: </strong>{this.state.componentObj.tasks}</p>
+                                                                       
<p><strong>Debug: </strong><a href={this.state.componentObj.eventLogLink} 
target="_blank">events</a></p>
+                                                               </div>
+                                                       </div>
+                                               </div>
+                                               <div className="col-sm-8">
+                                                       <div 
className="stats-tile">
+                                                               <div 
className="stats-title">{spoutFlag ? "Spout Stats" : "Bolt Stats"}</div>
+                                                               <div 
className="stats-body">
+                                                                       <table 
className="table table-condensed no-margin">
+                                                                               
<thead>
+                                                                               
        <tr>
+                                                                               
                <th><span data-rel="tooltip" title="The past period of time for 
which the statistics apply.">Window</span></th>
+                                                                               
                <th><span data-rel="tooltip" title="The number of Tuples 
emitted.">Emitted</span></th>
+                                                                               
                <th><span data-rel="tooltip" title="The number of Tuples 
emitted that sent to one or more bolts.">Transferred</span></th>
+                                                                               
                {spoutFlag ? <th><span data-rel="tooltip" title='The average 
time a Tuple "tree" takes to be completely processed by the Topology. A value 
of 0 is expected if no acking is done.'>Complete Latency (ms)</span></th> : 
null}
+                                                                               
                {!spoutFlag ? <th><span data-rel="tooltip" title="The average 
time a Tuple spends in the execute method. The execute method may complete 
without sending an Ack for the tuple.">Execute Latency (ms)</span></th> : null}
+                                                                               
                {!spoutFlag ? <th><span data-rel="tooltip" title="The number of 
incoming Tuples processed.">Executed</span></th> : null}
+                                                                               
                {!spoutFlag ? <th><span data-rel="tooltip" title="The average 
time it takes to Ack a Tuple after it is first received.  Bolts that join, 
aggregate or batch may not Ack a tuple until a number of other Tuples have been 
received.">Process Latency (ms)</span></th> : null}
+                                                                               
                <th><span data-rel="tooltip" title={spoutFlag ? 'The number of 
Tuple "trees" successfully processed. A value of 0 is expected if no acking is 
done.' : "The number of Tuples acknowledged by this Bolt."}>Acked</span></th>
+                                                                               
                <th><span data-rel="tooltip" title={spoutFlag ? 'The number of 
Tuple "trees" that were explicitly failed or timed out before acking was 
completed. A value of 0 is expected if no acking is done.' : "The number of 
tuples Failed by this Bolt."}>Failed</span></th>
+                                                                               
        </tr>
+                                                                               
</thead>
+                                                                               
<tbody>
+                                                                               
        {this.renderStatsRow()}
+                                                                               
</tbody>
+                                                                       </table>
+                                                               </div>
+                                                       </div>
+                                               </div>
+                                       </div>
+                                       <div className="row">
+                                               <div className="col-sm-12">
+                                                       
{this.state.componentObj.inputStats ? this.renderInputStats() : null}
+                                                       
{this.state.componentObj.outputStats ? this.renderOutputStats() : null}
+                                                       
{this.state.componentObj.executorStats ? this.renderExecutorStats() : null}
+                                                       
{this.state.componentObj.componentErrors ? this.renderErrorStats() : null}
+                                               </div>
+                                       </div>
+                                       {this.state.profilingModalOpen ? 
<ProfilingView modalId="modal-profiling" topologyId={this.props.id} 
executorStats={this.state.componentObj.executorStats} /> : null}
+                               </div>
+                       );
+           },
+           handleProfiling: function(){
+               this.setState({"profilingModalOpen":true});
+           },
+           debugAction: function(toEnableFlag){
+               if(toEnableFlag){
+                       bootbox.prompt({
+                               title: 'Do you really want to debug this 
component ? If yes, please, specify sampling percentage.',
+                               value: "10",
+                               buttons: {
+                                 confirm: {
+                                   label: 'Yes',
+                                   className: "btn-success",
+                                 },
+                                 cancel: {
+                                   label: 'No',
+                                   className: "btn-default",
+                                 }
+                               },
+                               callback: function(result) {
+                                 if(result != null){
+                                   this.model.debugComponent({
+                                               id: 
this.state.componentObj.topologyId,
+                                               name: 
this.state.componentObj.id,
+                                               debugType: 'enable',
+                                               percent: result,
+                                               success: function(model, 
response){
+                                                       if(response.error){
+                                                                       
Utils.notifyError(response.error);
+                                                               } else {
+                                                                       
this.initializeData();
+                                                               
Utils.notifySuccess("Debugging enabled successfully.");
+                                                               }
+                                               }.bind(this),
+                                                       error: function(model, 
response, options){
+                                                               
Utils.notifyError("Error occured in enabling debugging.");
+                                                       }
+                                       });
+                                 } else {
+                                       
$(".boot-switch.debug").bootstrapSwitch('toggleState', true)
+                                 }
+                               }.bind(this)
+                           });
+               } else {
+                       var title = "Do you really want to stop debugging this 
component ?";
+                       var successCb = function(){
+                               this.model.debugComponent({
+                                       id: this.state.componentObj.topologyId,
+                                       name: this.state.componentObj.id,
+                                       debugType: 'disable',
+                                       percent: '0',
+                                       success: function(model, response){
+                                               if(response.error){
+                                                               
Utils.notifyError(response.error);
+                                                       } else {
+                                                               
this.initializeData();
+                                                       
Utils.notifySuccess("Debugging disabled successfully.");
+                                                       }
+                                       }.bind(this),
+                                               error: function(model, 
response, options){
+                                                       
Utils.notifyError("Error occured in disabling debugging.");
+                                               }
+                               });
+                       }.bind(this);
+                       var cancelCb = function(){
+                               
$(".boot-switch.debug").bootstrapSwitch('toggleState', true)
+                       }.bind(this);
+                       Utils.ConfirmDialog('&nbsp;', title, successCb, 
cancelCb);
+               }
+           },
+       });
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/529ef7f7/contrib/views/storm/src/main/resources/scripts/views/Dashboard.jsx
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/views/Dashboard.jsx 
b/contrib/views/storm/src/main/resources/scripts/views/Dashboard.jsx
new file mode 100644
index 0000000..3f4f682
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/views/Dashboard.jsx
@@ -0,0 +1,65 @@
+/**
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+*
+     http://www.apache.org/licenses/LICENSE-2.0
+*
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+define([
+       'jsx!components/Table',
+       'jsx!components/RadialChart',
+       'react',
+       'react-dom',
+       'jsx!containers/ClusterSummary',
+       'jsx!containers/NimbusSummary',
+       'jsx!containers/SupervisorSummary',
+       'jsx!containers/TopologyListing',
+       'jsx!containers/NimbusConfigSummary'
+       ],function(Table,RadialChart, React, ReactDOM, ClusterSummary, 
NimbusSummary, SupervisorSummary, TopologyListing, NimbusConfigSummary){
+       'use strict';
+
+       return React.createClass({
+               displayName: 'Dashboard',
+               getInitialState: function(){
+                       return null;
+               },
+               componentWillMount: function(){
+                       $('.loader').show();
+               },
+               componentDidMount: function(){
+                       $('.loader').hide();
+               },
+               componentWillUpdate: function(){
+                       $('.loader').show();
+               },
+               componentDidUpdate: function(){
+                       $('.loader').hide();
+               },
+               render: function() {
+                       return (
+                               <div>
+                                       <div className="row" style={{marginTop: 
'20px'}}>
+                                               <ClusterSummary />
+                                               <TopologyListing 
fromDashboard={true} />
+                                       </div>
+                                       <div className="row">
+                                           <div className="col-sm-12">
+                                               <NimbusConfigSummary />
+                                           </div>
+                                       </div>
+                               </div>
+                       );
+           }
+       });
+});
\ No newline at end of file

Reply via email to