http://git-wip-us.apache.org/repos/asf/ambari/blob/0c188aea/contrib/views/storm/src/main/resources/scripts/views/TopologyDetailView.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/views/TopologyDetailView.jsx 
b/contrib/views/storm/src/main/resources/scripts/views/TopologyDetailView.jsx
deleted file mode 100644
index 136d95f..0000000
--- 
a/contrib/views/storm/src/main/resources/scripts/views/TopologyDetailView.jsx
+++ /dev/null
@@ -1,1039 +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([
-       'jsx!components/Table',
-       'jsx!modules/Table/Pagination',
-       'utils/Utils',
-       'react',
-       'react-dom',
-       'collections/BaseCollection',
-       'models/VTopology',
-       'models/BaseModel',
-       'jsx!containers/TopologyConfiguration',
-       'jsx!containers/TopologyDetailGraph',
-       'jsx!components/Breadcrumbs',
-       'jsx!components/SearchLogs',
-       'jsx!components/BarChart',
-       'jsx!views/RebalanceView',
-       'bootbox',
-       'x-editable',
-       'bootstrap',
-       'bootstrap-switch'
-       ],function(Table, Pagination, Utils, React, ReactDOM, BaseCollection, 
VTopology, BaseModel, TopologyConfiguration, TopologyDetailGraph, Breadcrumbs, 
SearchLogs, BarChart, RebalanceView, bootbox, XEditable){
-       'use strict';
-
-       return React.createClass({
-               displayName: 'TopologyDetailView',
-               propTypes: {
-                       id: React.PropTypes.string.isRequired
-               },
-               getInitialState: function(){
-                       this.model = new VTopology({'id': this.props.id});
-                       this.spoutCollection = new BaseCollection();
-                       this.boltCollection = new BaseCollection();
-                       this.lagCollection = new BaseCollection();
-                       this.systemFlag = false;
-                       this.windowSize = ':all-time';
-                       return {
-                               model: this.model,
-                               graphData: {},
-                               logLevels: {},
-                               rebalanceModalOpen: false,
-                               lagData: [],
-                               hideKafkaLagBox: false,
-                               workerHostPort: ''
-                       };
-               },
-               componentWillMount: function(){
-                       $('.loader').show();
-                       this.initializeData();
-               },
-               componentDidMount: function(){
-                       $(".boot-switch.systemSum").bootstrapSwitch({
-                               size: 'small',
-                               onSwitchChange: function(event, state){
-                                       this.systemFlag = state;
-                                       this.initializeData();
-                               }.bind(this)
-                       });
-                       $("#slideContent").hide();
-                       $(".boot-switch.debug").bootstrapSwitch({
-                               size: 'small',
-                               onSwitchChange: function(event, state){
-                                       this.debugAction(state);
-                               }.bind(this)
-                       });
-                       $("#lag-graph").hide();
-                       $("#kafkaSpout").bootstrapSwitch({
-                       onSwitchChange: function() {
-                               $('#lag-graph, #lag-table').slideToggle();
-                       }
-                   });
-                       $('[data-rel="tooltip"]').tooltip();
-                       $('.loader').hide();
-               },
-               componentWillUpdate: function(){
-                       $('#collapse-spout').off('hidden.bs.collapse');
-                       $('#collapse-spout').off('shown.bs.collapse');
-                       $('#collapse-bolt').off('hidden.bs.collapse');
-                       $('#collapse-bolt').off('shown.bs.collapse');
-                       $('#modal-rebalance').off('hidden.bs.modal');
-                       
this.spoutCollection.getFirstPage().fullCollection.reset([]);
-                       this.spouts = this.renderSpouts();
-                       
this.boltCollection.getFirstPage().fullCollection.reset([]);
-                       this.bolts = this.renderBolts();
-               },
-               componentDidUpdate: function(){
-                       $('#collapse-spout').on('hidden.bs.collapse', function 
() {
-                               $("#spout-box").toggleClass("fa-compress 
fa-expand");
-                       }).on('shown.bs.collapse', function() {
-                               $("#spout-box").toggleClass("fa-compress 
fa-expand");
-                       });
-
-                       $('#collapse-bolt').on('hidden.bs.collapse', function 
() {
-                               $("#bolt-box").toggleClass("fa-compress 
fa-expand");
-                       }).on('shown.bs.collapse', function() {
-                               $("#bolt-box").toggleClass("fa-compress 
fa-expand");
-                       });
-                       $('#modal-rebalance').on('hidden.bs.modal', function 
(e) {
-                         this.initializeData();
-                         this.setState({"rebalanceModalOpen":false});
-                       }.bind(this));
-                       if(this.state.rebalanceModalOpen){
-                               $('#modal-rebalance').modal("show");
-                       }
-                       if(this.refs.barChart){
-                               
ReactDOM.findDOMNode(document.getElementById('lag-graph')).appendChild(this.refs.barChart.legendsEl)
-                       }
-               },
-               initializeData: function(){
-                       this.model.getData({
-                               id: this.model.get('id'),
-                               window: this.windowSize,
-                               sys: this.systemFlag,
-                               success: function(model, response){
-                                       if(response.error || model.error){
-                                               
Utils.notifyError(response.error || 
model.error+'('+model.errorMessage.split('(')[0]+')');
-                                       } else {
-                                               this.model.set(model);
-                                               this.setState({"model": 
this.model});
-                                       }
-                               }.bind(this),
-                               error: function(model, response, options){
-                                       Utils.notifyError("Error occured in 
fetching topology details.");
-                               }
-                       });
-                       this.initializeGraphData();
-                       this.initializeLogConfig();
-                       this.initializeLagData();
-                       this.initializeWorkerData();
-               },
-               initializeGraphData: function(){
-                       $('#graphLoader').show();
-                       this.model.getGraphData({
-                               id: this.model.get('id'),
-                               window: this.windowSize,
-                               success: function(model, response){
-                                       if(response.error || model.error){
-                                               
Utils.notifyError(response.error || 
model.error+'('+model.errorMessage.split('(')[0]+')');
-                                       } else {
-                                               if(_.isString(model)){
-                                                       model = 
JSON.parse(model);
-                                               }
-                                               this.setState({graphData: 
model});
-                                       }
-                                       $('#graphLoader').hide();
-                               }.bind(this),
-                               error: function(model, response, options){
-                                       Utils.notifyError("Error occured in 
fetching topology visualization data.");
-                               }
-                       });
-               },
-
-               initializeLogConfig: function() {
-                       this.collection = new BaseCollection();
-                       this.model.getLogConfig({
-                               id: this.model.get('id'),
-                               success: function(model, response){
-                                       if(response.error || model.error){
-                                               
Utils.notifyError(response.error || 
model.error+'('+model.errorMessage.split('(')[0]+')');
-                                       } else {
-                                               this.resetLogCollection(model);
-                                       }
-                               }.bind(this),
-                               error: function(model, response, options){
-                                       Utils.notifyError("Error occured in 
fetching log configuration data.");
-                               }
-                       });
-               },
-
-               initializeLagData: function(){
-                       $('#kafkaLoader').show();
-                       this.model.getTopologyLag({
-                               id: this.model.get('id'),
-                               success: function(model, response){
-                                       if(response.error || model.error){
-                                               
Utils.notifyError(response.error || 
model.error+'('+model.errorMessage.split('(')[0]+')');
-                                       } else {
-                                               if(model && 
_.keys(model).length > 0){
-                                                       var keys = 
_.keys(model);
-                                                       var arr = [];
-                                                       for(var i = 0; i < 
keys.length; i++){
-                                                               var data = 
model[keys[i]];
-                                                               var topicKeys = 
_.keys(data.spoutLagResult);
-                                                               for(var j = 0; 
j < topicKeys.length; j++){
-                                                                       var 
topicName = topicKeys[j];
-                                                                       var 
partitionData = data.spoutLagResult[topicName];
-                                                                       var id 
= _.keys(partitionData);
-                                                                       for(var 
k = 0; k < id.length; k++){
-                                                                               
var partitionId = id[k];
-                                                                               
var obj = partitionData[partitionId];
-                                                                               
obj['spoutId'] = data.spoutId;
-                                                                               
obj['spoutType'] = data.spoutType;
-                                                                               
obj['partition'] = partitionId;
-                                                                               
obj['topic'] = topicName;
-                                                                               
arr.push(obj);
-                                                                       }
-                                                               }
-                                                       }
-                                                       
this.resetLagCollection(arr);
-                                               } else {
-                                                       
this.setState({hideKafkaLagBox : true});
-                                               }
-                                       }
-                                       $('#kafkaLoader').hide();
-                               }.bind(this)
-                       })
-               },
-               initializeWorkerData: function(){
-                       this.model.getWorkerHost({
-                               id: this.model.get('id'),
-                               success: function(model, response){
-                                       if(response.error || model.error){
-                                               
Utils.notifyError(response.error || 
model.error+'('+model.errorMessage.split('(')[0]+')');
-                                       } else {
-                                               var workerHostPortArr = 
model.hostPortList;
-                                               var result = '';
-                                               for(var i = 0; i < 
workerHostPortArr.length; i++){
-                                                       result += 
workerHostPortArr[i].host+':'+workerHostPortArr[i].port
-                                                       if(i !== 
workerHostPortArr.length - 1){
-                                                               result += ', 
\n';
-                                                       }
-                                               }
-                                               
this.setState({'workerHostPort': result})
-                                       }
-                               }.bind(this)
-                       })
-               },
-               resetLagCollection: function(model){
-                       this.lagCollection.reset(model);
-                       this.setState({"lagData": model});
-               },
-               getLagColums: function(){
-                       var self = this;
-                       return [
-                               {name: 'spoutId', title: 'Id', tooltip:'Id'},
-                               {name: 'topic', title: 'Topic', 
tooltip:'Topic'},
-                               {name: 'partition', title: 'Partition', 
tooltip:'Partition'},
-                               {name: 'logHeadOffset', title: 'Latest Offset', 
tooltip:'Latest Offset'},
-                               {name: 'consumerCommittedOffset', title: 'Spout 
Committed Offset', tooltip:'Spout Committed Offset'},
-                               {name: 'lag', title: 'Lag', tooltip:'Lag'},
-                       ];
-               },
-               resetLogCollection: function(model) {
-                       this.collection.reset();
-                       this.setState({logLevels: model.namedLoggerLevels});
-                       var keys = _.keys(this.state.logLevels);
-                               keys.map(function(key, index) {
-                                               var obj = 
this.state.logLevels[key];
-                                               var model = new BaseModel({
-                                                       logger: key,
-                                                       target_level: 
obj.target_level,
-                                                       timeout: obj.timeout,
-                                                       timeout_epoch: 
obj.timeout_epoch
-                                               });
-                                               this.collection.add(model);
-                               }.bind(this));
-
-                       this.collection.add(new BaseModel({
-                                       logger: 
'com.your.organization.LoggerName',
-                                       target_level: 'ALL',
-                                       timeout: 30,
-                                       timeout_epoch: 0,
-                                       isAdd: true
-                       }));
-               },
-
-               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}</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()} />
-                                               <Pagination 
collection={collection} />
-                           </div>
-                               </div>
-                       );
-               },
-               renderSpouts: function(){
-                       if(this.state.model.has('spouts')){
-                               
Utils.ArrayToCollection(this.state.model.get('spouts'), this.spoutCollection);
-                               this.spoutCollection.searchFields = ['spoutId'];
-                               var searchCb = function(e){
-                                       var value = e.currentTarget.value;
-                                       this.spoutCollection.search(value);
-                               }.bind(this);
-                               var toggleCb = function(e){
-                                       $("#collapse-spout").collapse('toggle');
-                               }
-                               return this.renderAccordion('spout', 'Spouts', 
'id', searchCb, this.spoutCollection, 'No spouts found !', 
this.getSpoutColumns, toggleCb);
-                       } else {
-                               return null;
-                       }
-               },
-               getSpoutColumns: function(){
-                       var self = this;
-                       return [
-                               {name: 'spoutId', title: 'Id', tooltip:'The ID 
assigned to a the Component by the Topology. Click on the name to view the 
Component\'s page.', component: React.createClass({
-                                       propTypes: {
-                                               model: 
React.PropTypes.object.isRequired
-                                       },
-                                       render: function(){
-                                               var topologyId = 
self.state.model.has('id') ? self.state.model.get('id') : "";
-                                               return ( <a 
href={"#!/topology/"+topologyId+"/component/"+this.props.model.get('spoutId')}>{this.props.model.get('spoutId')}</a>);
-                                       }
-                               })},
-                               {name: 'executors', title: 'Executors', 
tooltip:'Executors are threads in a Worker process.'},
-                               {name: 'tasks', title: 'Tasks', tooltip:'A Task 
is an instance of a Bolt or Spout. The number of Tasks is almost always equal 
to the number of Executors.'},
-                               {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: 'errorHost', title: 'Error Host:Port', 
component: React.createClass({
-                                       propTypes: {
-                                               model: 
React.PropTypes.object.isRequired
-                                       },
-                                       render: function(){
-                                               return 
(<span>{this.props.model.has('errorHost') && this.props.model.get('errorHost') 
!== '' ? 
this.props.model.get('errorHost')+':'+this.props.model.get('errorPort') : 
null}</span>);
-                                       }
-                               })},
-                               {name: 'lastError', title: 'Last Error'},
-                               {name: 'errorTime', title: 'Error Time', 
component: React.createClass({
-                                       propTypes: {
-                                               model: 
React.PropTypes.object.isRequired
-                                       },
-                                       render: function(){
-                                               
if(this.props.model.get('errorTime') && this.props.model.get('errorTime') != 0) 
{
-                                                       var d = new 
Date(this.props.model.get('errorTime') * 1000),
-                                                       date = 
d.toLocaleDateString() + ' ' + d.toLocaleTimeString();
-                                                       return 
(<span>{date}</span>);
-                                               } else return (<span></span>);
-                                       }
-                               })}
-                       ];
-               },
-               renderBolts: function(){
-                       if(this.state.model.has('bolts')){
-                               
Utils.ArrayToCollection(this.state.model.get('bolts'), this.boltCollection);
-                               this.boltCollection.searchFields = ['boltId'];
-                               var searchCb = function(e){
-                                       var value = e.currentTarget.value;
-                                       this.boltCollection.search(value);
-                               }.bind(this);
-                               var toggleCb = function(e){
-                                       $("#collapse-bolt").collapse('toggle');
-                               }
-                               return this.renderAccordion('bolt', 'Bolts', 
'id', searchCb, this.boltCollection, 'No bolts found !', this.getBoltColumns, 
toggleCb);
-                       } else {
-                               return null;
-                       }
-               },
-               getBoltColumns: function(){
-                       var self = this;
-                       return [
-                               {name: 'boltId', title: 'Id', tooltip:'The ID 
assigned to a the Component by the Topology. Click on the name to view the 
Component\'s page.', component: React.createClass({
-                                       propTypes: {
-                                               model: 
React.PropTypes.object.isRequired
-                                       },
-                                       render: function(){
-                                               var topologyId = 
self.state.model.has('id') ? self.state.model.get('id') : "";
-                                               return ( <a 
href={"#!/topology/"+topologyId+"/component/"+this.props.model.get('boltId')}>{this.props.model.get('boltId')}</a>);
-                                       }
-                               })},
-                               {name: 'executors', title: 'Executors', 
tooltip:'Executors are threads in a Worker process.'},
-                               {name: 'tasks', title: 'Tasks', tooltip:'A Task 
is an instance of a Bolt or Spout. The number of Tasks is almost always equal 
to the number of Executors.'},
-                               {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: 'errorHost', title: 'Error Host:Port', 
component: React.createClass({
-                                       propTypes: {
-                                               model: 
React.PropTypes.object.isRequired
-                                       },
-                                       render: function(){
-                                               return 
(<span>{this.props.model.has('errorHost') && this.props.model.get('errorHost') 
!== '' ? 
this.props.model.get('errorHost')+':'+this.props.model.get('errorPort') : 
null}</span>);
-                                       }
-                               })},
-                               {name: 'lastError', title: 'Last Error'},
-                               {name: 'errorTime', title: 'Error Time', 
component: React.createClass({
-                                       propTypes: {
-                                               model: 
React.PropTypes.object.isRequired
-                                       },
-                                       render: function(){
-                                               
if(this.props.model.get('errorTime') && this.props.model.get('errorTime') != 0) 
{
-                                                       var d = new 
Date(this.props.model.get('errorTime') * 1000),
-                                                       date = 
d.toLocaleDateString() + ' ' + d.toLocaleTimeString();
-                                                       return 
(<span>{date}</span>);
-                                               } else return (<span></span>);
-                                       }
-                               })}
-                       ];
-               },
-               renderWindowOptions: function(){
-                       if(this.state.model.has('topologyStats')){
-                               return 
this.state.model.get('topologyStats').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: 'javascript:void(0);', title: 
this.state.model.has('name') ? this.state.model.get('name') : ""}
-                               ];
-                       return links;
-               },
-
-               addLogLevel: function(e) {
-                       var self = this;
-                       var id = e.currentTarget.getAttribute('data-name');
-                       var namedLoggerLevels = {};
-                       var targetLevel = 
$(e.currentTarget).parent().siblings().find('.target-level').val(),
-                               timeout = 
$(e.currentTarget).parent().siblings().find('.timeout').html(),
-                               logger = 
$(e.currentTarget).parent().siblings().find('.logger').html();
-
-                       namedLoggerLevels[logger] = {
-                               target_level: targetLevel,
-                               reset_level: 'INFO',
-                               timeout: parseInt(timeout, 10)
-                       };
-
-            var dataObj = {
-                               namedLoggerLevels: namedLoggerLevels
-                       }
-
-                       this.model.saveLogConfig({
-                               id: this.model.get('id'),
-                               data: JSON.stringify(dataObj),
-                               contentType: "application/json",
-               success: function(model, response, options){
-                       if(response.error || model.error){
-                                               
Utils.notifyError(response.error || 
model.error+'('+model.errorMessage.split('(')[0]+')');
-                                       } else {
-                                               this.resetLogCollection(model);
-                               Utils.notifySuccess("Log configuration added 
successfully.");
-                                       }
-               }.bind(this),
-                               error: function(model, response, options){
-                                       Utils.notifyError("Error occured in 
saving log configuration data.");
-                               }
-
-                       });
-               },
-               applyLogLevel: function(e) {
-                       var self = this;
-                       var id = e.currentTarget.getAttribute('data-name');
-                       var namedLoggerLevels = {};
-                       var targetLevel = 
$(e.currentTarget).parents('td').siblings().find('.target-level').val(),
-                               timeout = 
$(e.currentTarget).parents('td').siblings().find('.timeout').html(),
-                               logger = 
$(e.currentTarget).parents('td').siblings().find('.logger').html();
-
-                       namedLoggerLevels[logger] = {
-                               target_level: targetLevel,
-                               reset_level: 'INFO',
-                               timeout: parseInt(timeout, 10)
-                       };
-
-            var dataObj = {
-                               namedLoggerLevels: namedLoggerLevels
-                       }
-
-                       this.model.saveLogConfig({
-                               id: this.model.get('id'),
-                               data: JSON.stringify(dataObj),
-                               contentType: "application/json",
-               success: function(model, response, options){
-                       if(response.error || model.error){
-                                               
Utils.notifyError(response.error || 
model.error+'('+model.errorMessage.split('(')[0]+')');
-                                       } else {
-                                               this.resetLogCollection(model);
-                               Utils.notifySuccess("Log configuration applied 
successfully.");
-                                       }
-               }.bind(this),
-                               error: function(model, response, options){
-                                       Utils.notifyError("Error occured in 
applying log configuration data.");
-                               }
-                       });
-               },
-               clearLogLevel: function(e) {
-                       var self = this;
-                       var id = e.currentTarget.getAttribute('data-name');
-                       var namedLoggerLevels = {};
-                       var logger = 
$(e.currentTarget).parents('td').siblings().find('.logger').html();
-
-                       namedLoggerLevels[logger] = {
-                               target_level: null,
-                               reset_level: 'INFO',
-                               timeout: 0
-                       };
-
-            var dataObj = {
-                               namedLoggerLevels: namedLoggerLevels
-                       }
-
-                       this.model.saveLogConfig({
-                               id: this.model.get('id'),
-                               data: JSON.stringify(dataObj),
-                               contentType: "application/json",
-               success: function(model, response, options){
-                       if(response.error || model.error){
-                                               
Utils.notifyError(response.error || 
model.error+'('+model.errorMessage.split('(')[0]+')');
-                                       } else {
-                                               this.resetLogCollection(model);
-                               Utils.notifySuccess("Log configuration cleared 
successfully.");
-                                       }
-               }.bind(this),
-                               error: function(model, response, options){
-                                       Utils.notifyError("Error occured in 
clearing log configuration data.");
-                               }
-                       });
-               },
-               getColumns: function(){
-                       var self = this;
-                       return [
-                               {name: 'logger', title: 'Logger', component: 
React.createClass({
-                                       propTypes: {
-                                               model: 
React.PropTypes.object.isRequired
-                                       },
-                                       render: function(){
-                                               
if(this.props.model.get('isAdd'))
-                                                       return (<a 
href="javascript:void(0)" className="x-editable 
logger">{this.props.model.get('logger')}</a>);
-                                               else return (<a 
href="javascript:void(0)" 
className="logger">{this.props.model.get('logger')}</a>);
-                                       },
-                                       componentDidMount: function() {
-                                               $(".x-editable").editable({
-                                                       mode: 'inline'
-                                               });
-                                       }})
-                           },
-                               {name: 'target_level', title: 'Level', 
component: React.createClass({
-                                       propTypes: {
-                                               model: 
React.PropTypes.object.isRequired
-                                       },
-                                       render: function() {
-                                               return (
-                                                       <select 
className="form-control target-level" 
defaultValue={this.props.model.get('target_level')}>
-                                                               <option 
value="ALL">ALL</option>
-                                                               <option 
value="TRACE">TRACE</option>
-                                                               <option 
value="DEBUG">DEBUG</option>
-                                                               <option 
value="INFO">INFO</option>
-                                                               <option 
value="WARN">WARN</option>
-                                                               <option 
value="ERROR">ERROR</option>
-                                                               <option 
value="FATAL">FATAL</option>
-                                                               <option 
value="OFF">OFF</option>
-                                                       </select>
-                                                       );
-                                       }
-                               })},
-                               {name: 'timeout', title: 'Timeout', component: 
React.createClass({
-                                       propTypes: {
-                                               model: 
React.PropTypes.object.isRequired
-                                       },
-                                       render: function(){
-                                               return (<a 
href="javascript:void(0)" className="x-editable 
timeout">{this.props.model.get('timeout')}</a>);
-                                       },
-                                       componentDidMount: function() {
-                                               $(".x-editable").editable({
-                                                       mode: 'inline'
-                                               });
-                                       }})
-                           },
-                               {name: 'timeout_epoch', title: 'Expires At', 
component: React.createClass({
-                                       propTypes: {
-                                               model: 
React.PropTypes.object.isRequired
-                                       },
-                                       render: function(){
-                                               
if(this.props.model.get('timeout_epoch') != 0) {
-                                                       var d = new 
Date(this.props.model.get('timeout_epoch')),
-                                                       date = 
d.toLocaleDateString() + ' ' + d.toLocaleTimeString();
-                                                       return 
(<span>{date}</span>);
-                                               } else return (<span></span>);
-
-                                       }
-                                       })
-                               },
-                               {name: 'action', title: 'Action', component: 
React.createClass({
-                                       propTypes: {
-                                               model: 
React.PropTypes.object.isRequired
-                                       },
-                                       render: function(){
-                                               
if(this.props.model.get('isAdd'))
-                                                       return(
-                                                       <a 
href="javascript:void(0)"  data-name={this.props.model.get('logger')} 
className="btn btn-primary btn-xs" onClick={self.addLogLevel}><i className="fa 
fa-plus"></i></a>
-                                                       )
-                                               else
-                                               return (
-                                                       <span>
-                                                       <a 
href="javascript:void(0)" data-name={this.props.model.get('logger')} 
className="btn btn-success btn-xs" onClick={self.applyLogLevel}><i 
className="fa fa-check"></i></a>&nbsp;
-                                                       <a 
href="javascript:void(0)" data-name={this.props.model.get('logger')} 
className="btn btn-danger btn-xs" onClick={self.clearLogLevel}><i className="fa 
fa-times"></i></a>
-                                                       </span>
-                                               );
-                                       }
-                               })}
-                       ];
-               },
-               toggleSlide: function() {
-                       $("#slideContent").slideToggle();
-               },
-               
-               renderStatsRow: function(){
-                       var statsArr = this.state.model.get('topologyStats');
-                       if(statsArr){
-                               return statsArr.map(function(stats, i){
-                                       return (
-                                               <tr key={i}>
-                                                       
<td>{stats.windowPretty}</td>
-                                                       <td>{stats.emitted}</td>
-                                                       
<td>{stats.transferred}</td>
-                                                       
<td>{stats.completeLatency}</td>
-                                                       <td>{stats.acked}</td>
-                                                       <td>{stats.failed}</td>
-                                               </tr>
-                                       );
-                               });
-                       }
-               },
-               render: function() {
-                       var status = this.state.model.has('status') ? 
this.state.model.get('status') : null;
-                       var workersTotal = this.state.model.has('workersTotal') 
? this.state.model.get('workersTotal').toString() : '0';
-                       if(this.state.model.get('debug')){
-                               
$(".boot-switch.debug").bootstrapSwitch('state', true, true);
-                       } else {
-                               
$(".boot-switch.debug").bootstrapSwitch('state', false, true);
-                       }
-                       return (
-                               <div>
-                                       <Breadcrumbs links={this.getLinks()} />
-                                       <SearchLogs id={this.model.get('id')}/>
-                                       <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.handleTopologyActivation} title="Activate" data-rel="tooltip" 
disabled={status === 'ACTIVE' ? "disabled" : null}>
-                                                                               
                        <i className="fa fa-play"></i>
-                                                                               
                </button>
-                                                                               
                <button type="button" className="btn btn-primary" 
onClick={this.handleTopologyDeactivation} title="Deactivate" data-rel="tooltip" 
disabled={status === 'INACTIVE' ? "disabled" : null}>
-                                                                               
                        <i className="fa fa-stop"></i>
-                                                                               
                </button>
-                                                                               
                <button type="button" className="btn btn-primary" 
onClick={this.handleTopologyRebalancing} title="Rebalance" data-rel="tooltip" 
disabled={status === 'REBALANCING' ? "disabled" : null}>
-                                                                               
                        <i className="fa fa-balance-scale"></i>
-                                                                               
                </button>
-                                                                               
                <button type="button" className="btn btn-primary" 
onClick={this.handleTopologyKilling} title="Kill" data-rel="tooltip" 
disabled={status === 'KILLED' ? "disabled" : null}>
-                                                                               
                        <i className="fa fa-ban"></i>
-                                                                               
                </button>
-                                                                               
                <button type="button" className="btn btn-primary" 
onClick={this.toggleSlide} title="Change Log Level" data-rel="tooltip">
-                                                                               
                        <i className="fa fa-file-o"></i>
-                                                                               
                </button>
-                                                                               
        </div>
-                                                                               
</div>
-                                                                       </div>
-                                                                       <div 
className="row" id="slideContent">
-                                                                               
<div className="col-sm-12">
-                                                                               
        <hr/>
-                                                                               
        <h4 className="col-sm-offset-5">Change Log Level</h4>
-                                                                               
        <p>Modify the logger levels for topology. Note that applying a setting 
restarts the timer in the workers. To configure the root logger, use the name 
ROOT.</p>
-                                                                               
        <Table className="table no-margin" collection={this.collection} 
columns={this.getColumns()}/>
-                                                                               
</div>
-                                                                       </div>
-                                                               </div>
-                                                       </div>
-                                               </div>
-                                       </div>
-                                       <div className="row">
-                                               <div className="col-sm-5">
-                                                       <div 
className="summary-tile">
-                                                               <div 
className="summary-title">Topology Summary</div>
-                                                               <div 
className="summary-body form-horizontal">
-                                                                       <div 
className="form-group">
-                                                                               
<label className="col-sm-4 control-label">ID:</label>
-                                                                               
<div className="col-sm-8">
-                                                                               
<p className="form-control-static">{this.state.model.get('id')}</p>
-                                                                               
</div>
-                                                                       </div>
-                                                                       <div 
className="form-group">
-                                                                               
<label className="col-sm-4 control-label">Owner:</label>
-                                                                               
<div className="col-sm-8">
-                                                                               
<p className="form-control-static">{this.state.model.get('owner')}</p>
-                                                                               
</div>
-                                                                       </div>
-                                                                       <div 
className="form-group">
-                                                                               
<label className="col-sm-4 control-label">Status:</label>
-                                                                               
<div className="col-sm-8">
-                                                                               
<p className="form-control-static">{this.state.model.get('status')}</p>
-                                                                               
</div>
-                                                                       </div>
-                                                                       <div 
className="form-group">
-                                                                               
<label className="col-sm-4 control-label">Uptime:</label>
-                                                                               
<div className="col-sm-8">
-                                                                               
<p className="form-control-static">{this.state.model.get('uptime')}</p>
-                                                                               
</div>
-                                                                       </div>
-                                                                       <div 
className="form-group">
-                                                                               
<label className="col-sm-4 control-label">Workers:</label>
-                                                                               
<div className="col-sm-8">
-                                                                               
<p className="form-control-static">{this.state.model.get('workersTotal')}</p>
-                                                                               
</div>
-                                                                       </div>
-                                                                       <div 
className="form-group">
-                                                                               
<label className="col-sm-4 control-label">Executors:</label>
-                                                                               
<div className="col-sm-8">
-                                                                               
<p className="form-control-static">{this.state.model.get('executorsTotal')}</p>
-                                                                               
</div>
-                                                                       </div>
-                                                                       <div 
className="form-group">
-                                                                               
<label className="col-sm-4 control-label">Tasks:</label>
-                                                                               
<div className="col-sm-8">
-                                                                               
<p className="form-control-static">{this.state.model.get('tasksTotal')}</p>
-                                                                               
</div>
-                                                                       </div>
-                                                                       <div 
className="form-group">
-                                                                               
<label className="col-sm-4 control-label">Memory:</label>
-                                                                               
<div className="col-sm-8">
-                                                                               
<p 
className="form-control-static">{this.state.model.get('assignedTotalMem')}</p>
-                                                                               
</div>
-                                                                       </div>
-                                                                       <div 
className="form-group">
-                                                                               
<label className="col-sm-4 control-label">Worker-Host:Port:</label>
-                                                                               
<div className="col-sm-8">
-                                                                               
<p className="form-control-static preformatted">{this.state.workerHostPort}</p>
-                                                                               
</div>
-                                                                       </div>
-
-                                                               </div>
-                                                       </div>
-                                               </div>
-                                               <div className="col-sm-7">
-                                                       <div 
className="stats-tile">
-                                                               <div 
className="stats-title">Topology Stats</div>
-                                                               <div 
className="stats-body">
-                                                                       <table 
className="table table-enlarge">
-                                                                               
<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>
-                                                                               
                <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>
-                                                                               
                <th><span data-rel="tooltip" title='The number of Tuple "trees" 
successfully processed. A value of 0 is expected if no acking is 
done.'>Acked</span></th>
-                                                                               
                <th><span data-rel="tooltip" title='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.'>Failed</span></th>
-                                                                               
        </tr>
-                                                                               
</thead>
-                                                                               
<tbody>
-                                                                               
        {this.renderStatsRow()}
-                                                                               
</tbody>
-                                                                       </table>
-                                                               </div>
-                                                       </div>
-                                               </div>
-                                       </div>
-                                       <div className="row">
-                                               <div className="col-sm-12">
-                                                       <div 
className="inner-loader" id="graphLoader" />
-                                                       <TopologyDetailGraph 
model={this.state.model} graphData={this.state.graphData}/>
-                                               </div>
-                                       </div>
-                                       {this.state.hideKafkaLagBox ? null : 
-                                               <div className="row">
-                                                       <div 
className="col-sm-12">
-                                                               <div 
className="box">
-                                                                       <div 
className="box-header">
-                                                                               
<h4>Kafka Spout Lag</h4>
-                                                                               
<div className="box-control">
-                                                                               
        <input 
-                                                                               
                id="kafkaSpout" 
-                                                                               
                type="checkbox" 
-                                                                               
                data-size="mini" 
-                                                                               
                data-off-color="success" 
-                                                                               
                data-off-text="Table" 
-                                                                               
                data-on-color="info" 
-                                                                               
                data-on-text="Graph" />
-                                                                               
</div>
-                                                                       </div>
-                                                                       <div 
className="box-body">
-                                                                               
<div className="row">
-                                                                               
        <div className="col-sm-12">
-                                                                               
                <div className="inner-loader" id="kafkaLoader" />
-                                                                               
                <div id="lag-graph">
-                                                                               
                        {this.lagCollection.length > 0 ? 
-                                                                               
                        <BarChart
-                                                                               
                                ref="barChart"
-                                                                               
                                width={window != window.parent ? 1100 : 1300}
-                                                                               
                                height={400}
-                                                                               
                                xAttr="spoutId-partition"
-                                                                               
                                yAttr="count"
-                                                                               
                                
data={this.lagCollection.toJSON().map(function(d){
-                                                                               
                                        return {
-                                                                               
                                                'Latest Offset': 
d.logHeadOffset,
-                                                                               
                                                'Spout Committed Offset': 
d.consumerCommittedOffset,
-                                                                               
                                                'spoutId-partition': 
d.spoutId+'-'+d.partition
-                                                                               
                                        };
-                                                                               
                                })}
-                                                                               
                        />
-                                                                               
                        : null}
-                                                                               
                </div>
-                                                                               
                <div id="lag-table">
-                                                                               
                        <Table 
-                                                                               
                                className="table table-striped table-bordered" 
-                                                                               
                                collection={this.lagCollection} 
-                                                                               
                                emptyText="No Data Found." 
-                                                                               
                                columns={this.getLagColums()} 
-                                                                               
                        />
-                                                                               
                </div>
-                                                                               
        </div>
-                                                                               
</div>
-                                                                       </div>
-                                                               </div>
-                                                       </div>
-                                               </div>
-                                       }
-                                       <div className="row">
-                                               <div className="col-sm-12">
-                                                       {this.spouts}
-                                               </div>
-                                       </div>
-                                       <div className="row">
-                                               <div className="col-sm-12">
-                                                       {this.bolts}
-                                               </div>
-                                       </div>
-                                       <div className="row">
-                                               <div className="col-sm-12">
-                                                       <TopologyConfiguration 
configArr={this.state.model.get('configuration') ? 
this.state.model.get('configuration') : {}}/>
-                                               </div>
-                                       </div>
-                                       {this.state.rebalanceModalOpen ? 
<RebalanceView modalId="modal-rebalance" 
topologyId={this.state.model.get('id')} topologyExecutors={workersTotal} 
spouts={this.state.model.get('spouts') ? this.state.model.get('spouts') : []} 
bolts={this.state.model.get('bolts') ? this.state.model.get('bolts') : []}/> : 
null}
-                               </div>
-                       );
-           },
-           handleTopologyActivation: function(e){
-               if(this.model.get('status') !== 'ACTIVE'){
-                       var msg = "Do you really want to activate this topology 
?";
-                       var successCb = function(){
-                               this.model.activateTopology({
-                                       id: this.model.get('id'),
-                                       success: function(model, response){
-                                               if(response.error || 
model.error){
-                                                               
Utils.notifyError(response.error || 
model.error+'('+model.errorMessage.split('(')[0]+')');
-                                                       } else {
-                                                               
this.initializeData();
-                                                       
Utils.notifySuccess("Topology activated successfully.")
-                                                       }
-                                       }.bind(this),
-                                               error: function(model, 
response, options){
-                                                       
Utils.notifyError("Error occured in activating topology.");
-                                               }
-                               });
-                       }.bind(this);
-                       Utils.ConfirmDialog(msg, '', successCb);
-               }
-           },
-           handleTopologyDeactivation: function(e){
-               if(this.model.get('status') !== 'INACTIVE'){
-                       var msg = "Do you really want to deactivate this 
topology ?";
-                       var successCb = function(){
-                               this.model.deactivateTopology({
-                                       id: this.model.get('id'),
-                                       success: function(model, response){
-                                               if(response.error || 
model.error){
-                                                               
Utils.notifyError(response.error || 
model.error+'('+model.errorMessage.split('(')[0]+')');
-                                                       } else {
-                                                               
this.initializeData();
-                                                       
Utils.notifySuccess("Topology deactivated successfully.")
-                                                       }
-                                       }.bind(this),
-                                               error: function(model, 
response, options){
-                                                       
Utils.notifyError("Error occured in deactivating topology.");
-                                               }
-                               });
-                       }.bind(this);
-                       Utils.ConfirmDialog(msg, '', successCb);
-               }
-           },
-           handleTopologyRebalancing: function(e){
-               if(this.model.get('status') !== 'REBALANCING'){
-                       this.setState({"rebalanceModalOpen":true});
-               }
-           },
-           handleTopologyKilling: function(e){
-               if(this.model.get('status') !== 'KILLED'){
-                       bootbox.prompt({
-                               title: 'Are you sure you want to kill this 
topology ? If yes, please, specify wait time in seconds.',
-                               value: "30",
-                               buttons: {
-                                 confirm: {
-                                   label: 'Yes',
-                                   className: "btn-success",
-                                 },
-                                 cancel: {
-                                   label: 'No',
-                                   className: "btn-default",
-                                 }
-                               },
-                               callback: function(result) {
-                                 if(result != null){
-                                   this.model.killTopology({
-                                               id: this.model.get('id'),
-                                               waitTime: result,
-                                               success: function(model, 
response){
-                                                       if(response.error || 
model.error){
-                                                                       
Utils.notifyError(response.error || 
model.error+'('+model.errorMessage.split('(')[0]+')');
-                                                               } else {
-                                                                       
this.initializeData();
-                                                               
Utils.notifySuccess("Topology killed successfully.")
-                                                               }
-                                               }.bind(this),
-                                                       error: function(model, 
response, options){
-                                                               
Utils.notifyError("Error occured in killing topology.");
-                                                       }
-                                       });
-                                 }
-                               }.bind(this)
-                           });
-               }
-           },
-           debugAction: function(toEnableFlag){
-               if(toEnableFlag){
-                       bootbox.prompt({
-                               title: 'Do you really want to debug this 
topology ? If yes, please, specify sampling percentage.',
-                               value: this.model.get("samplingPct") ? 
this.model.get("samplingPct") : '10',
-                               buttons: {
-                                 confirm: {
-                                   label: 'Yes',
-                                   className: "btn-success",
-                                 },
-                                 cancel: {
-                                   label: 'No',
-                                   className: "btn-default",
-                                 }
-                               },
-                               callback: function(result) {
-                                         if(result == null) {
-                                               
$(".boot-switch.debug").bootstrapSwitch('toggleState', true);
-                                 } else if(result == "" || isNaN(result) || 
result < 0) {
-                                               Utils.notifyError("Enter valid 
sampling percentage");
-                                               
$(".boot-switch.debug").bootstrapSwitch('toggleState', true);
-                                 } else {
-                                   this.model.debugTopology({
-                                               id: this.model.get('id'),
-                                               debugType: 'enable',
-                                               percent: result,
-                                               success: function(model, 
response){
-                                                       if(response.error || 
model.error){
-                                                                       
Utils.notifyError(response.error || 
model.error+'('+model.errorMessage.split('(')[0]+')');
-                                                               } else {
-                                                                       
this.initializeData();
-                                                               
Utils.notifySuccess("Debugging enabled successfully.")
-                                                               }
-                                               }.bind(this),
-                                                       error: function(model, 
response, options){
-                                                               
Utils.notifyError("Error occured in enabling debugging.");
-                                                       }
-                                       });
-                                 }
-                               }.bind(this)
-                           });
-               } else {
-                       var title = "Do you really want to stop debugging this 
topology ?";
-                       var successCb = function(){
-                               this.model.debugTopology({
-                                       id: this.model.get('id'),
-                                       debugType: 'disable',
-                                       percent: '0',
-                                       success: function(model, response){
-                                               if(response.error || 
model.error){
-                                                               
Utils.notifyError(response.error || 
model.error+'('+model.errorMessage.split('(')[0]+')');
-                                                       } 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);
-               }
-           },
-       });
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/0c188aea/contrib/views/storm/src/main/resources/scripts/views/TopologyListingView.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/views/TopologyListingView.jsx 
b/contrib/views/storm/src/main/resources/scripts/views/TopologyListingView.jsx
deleted file mode 100644
index 25441fa..0000000
--- 
a/contrib/views/storm/src/main/resources/scripts/views/TopologyListingView.jsx
+++ /dev/null
@@ -1,65 +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([
-       'jsx!components/Table',
-       'react',
-       'react-dom',
-       'jsx!containers/TopologyListing',
-       'jsx!components/Breadcrumbs'
-       ],function(Table, React, ReactDOM, TopologyListing, Breadcrumbs){
-       'use strict';
-
-       return React.createClass({
-               displayName: 'TopologyListingView',
-               getInitialState: function(){
-                       return null;
-               },
-               componentWillMount: function(){
-                       $('.loader').show();
-               },
-               componentDidMount: function(){
-                       $('.loader').hide();
-               },
-               componentWillUpdate: function(){
-                       $('.loader').show();
-               },
-               componentDidUpdate: function(){
-                       $('.loader').hide();
-               },
-               render: function() {                    
-                       return (
-                               <div>                                   
-                                       <Breadcrumbs links={this.getLinks()} />
-                                       <div className="row">
-                                               <div className="col-sm-12">
-                                                       <TopologyListing />
-                                               </div>
-                                       </div>
-                               </div>
-                       );
-           },
-           getLinks: function() {
-               var links = [
-                               {link: '#!/dashboard', title: 'Dashboard'},
-                               {link: 'javascript:void(0);', title: 'Topology 
Listing'}
-                               ];
-                       return links;
-           }
-       });
-});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/0c188aea/contrib/views/storm/src/main/resources/styles/style.css
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/styles/style.css 
b/contrib/views/storm/src/main/resources/styles/style.css
index f6b1685..71c26c4 100644
--- a/contrib/views/storm/src/main/resources/styles/style.css
+++ b/contrib/views/storm/src/main/resources/styles/style.css
@@ -14,7 +14,7 @@
  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.
-*/
+**/
 /*
     Theme: Apache Storm
     Author: Sanket
@@ -37,12 +37,12 @@ body {
 .row-margin-bottom {
   margin-bottom: 20px;
 }
- 
-.table-borderless>tbody>tr>td, 
-.table-borderless>tbody>tr>th, 
-.table-borderless>tfoot>tr>td, 
-.table-borderless>tfoot>tr>th, 
-.table-borderless>thead>tr>td, 
+
+.table-borderless>tbody>tr>td,
+.table-borderless>tbody>tr>th,
+.table-borderless>tfoot>tr>td,
+.table-borderless>tfoot>tr>th,
+.table-borderless>thead>tr>td,
 .table-borderless>thead>tr>th {
     border-top: none;
 }
@@ -140,7 +140,8 @@ body {
 }
 
 /* Boxes */
-.box {
+.box,
+.panel.panel-default {
     position: relative;
     margin-bottom: 15px;
     border: 1px #bcbcbc solid;
@@ -161,8 +162,8 @@ body {
     border-bottom: 1px #bcbcbc solid;
     border-radius: 4px 4px 0px 0px;
 }
-.box .box-header h4 {  
-    float: left;  
+.box .box-header h4 {
+    float: left;
     margin: 0px;
     font-size: 16px;
     font-weight: 700;
@@ -170,12 +171,12 @@ body {
     letter-spacing: 1px;
 }
 .box .box-header .box-control {
-    float: right;
+  float: right;
 }
 .box .box-header .box-control .bootstrap-switch {
   margin: 9px 2px;
 }
-.box .box-header .box-control a {
+.box .box-header .box-control a,.box-control a {
     display: inline-block;
     width: 20px;
     height: 20px;
@@ -187,18 +188,21 @@ body {
     background-color: #4b4b4b;
     color: rgba(255,255,255,0.75);
 }
+.box-control a {
+  margin: 0 2px;
+}
 /*.box .box-header .box-control a i {
     visibility: hidden;
 }
 .box .box-header .box-control:hover a i {
     visibility: visible;
 }*/
-.box .box-header .box-control a.primary {background-color: #1b75bb;}
-.box .box-header .box-control a.success {background-color: #1bbb60;}
-.box .box-header .box-control a.info {background-color: #27a9e1;}
-.box .box-header .box-control a.warning {background-color: #fbaf3f;}
-.box .box-header .box-control a.danger {background-color: #ff5816;}
-.box .box-header .box-control a.secondary {background-color: #df206a;}
+.box .box-header .box-control a.primary, .box-control a.primary 
{background-color: #1b75bb;}
+.box .box-header .box-control a.success, .box-control a.success 
{background-color: #1bbb60;}
+.box .box-header .box-control a.info, .box-control a.info {background-color: 
#27a9e1;}
+.box .box-header .box-control a.warning, .box-control a.warning 
{background-color: #fbaf3f;}
+.box .box-header .box-control a.danger, .box-control a.danger 
{background-color: #ff5816;}
+.box .box-header .box-control a.secondary, .box-control a.secondary 
{background-color: #df206a;}
 
 .box .box-body {
     padding: 10px;
@@ -285,7 +289,7 @@ body {
 .tile.warning > .tile-header {
     background-color: #ED940E;
 }
-.tile.success {
+.tile.success, .label-success {
     background: #1bbb60;
 }
 .tile.success > .tile-header {
@@ -472,12 +476,12 @@ text.id {
   font-weight: bold;
 }
 .d3-tip ul {
-  padding:0; 
-  margin:0; 
+  padding:0;
+  margin:0;
   list-style: none;
-}

+}

 .d3-tip ul li {
-  font-size: 12px; 
+  font-size: 12px;
   line-height: 20px;
 }
 marker {
@@ -534,7 +538,7 @@ ul.legends li.legend{
 }
 #modal-rebalance .modal-body{
   max-height: 450px;
-  overflow-y: auto; 
+  overflow-y: auto;
 }
 .loader {
   position: fixed;
@@ -542,7 +546,7 @@ ul.legends li.legend{
   bottom: 0;
   left: 0;
   right: 0;
-  background: url('../images/loader.gif') rgba(255,255,255,0.75) no-repeat 
center center;
+  background: url('../img/loader.gif') rgba(255,255,255,0.75) no-repeat center 
center;
   z-index: 9;
 }
 .inner-loader{
@@ -551,7 +555,7 @@ ul.legends li.legend{
   left: 0px;
   bottom: 0px;
   right: 0px;
-  background: url('../images/loader.gif') rgba(255,255,255,0.75) no-repeat 
center center;
+  background: url('../img/loader.gif') rgba(255,255,255,0.75) no-repeat center 
center;
 }
 .searchbar{
   margin-top: 15px;
@@ -573,7 +577,260 @@ ul.legends li.legend{
   vertical-align: top;
   margin-right: 5px;
 }
-.searchbar .open > .dropdown-toggle.btn-default:hover, 
+.searchbar .open > .dropdown-toggle.btn-default:hover,
 .searchbar .open > .dropdown-toggle.btn-default:focus{
   border: 1px solid transparent;
-}
\ No newline at end of file
+}
+.searchbar .form-group, .searchbar .checkbox {
+  margin-top: 0;
+  margin-bottom: 0;
+}
+.searchbar .checkbox label {
+  font-weight: 600;
+  margin-bottom: 5px;
+}
+.topology-table{
+  margin-bottom: 0 !important;
+}
+.topology-table a:hover,.panel-heading:hover{
+  cursor: pointer;
+}
+.pagination-wrapper{
+  width: 100%;
+  height: 35px;
+  display: block;
+  margin-top: 10px;
+}
+.pagination-wrapper > div > p {
+  line-height: 35px;
+}
+.pagination-wrapper > ul {
+  margin : 0 !important;
+}
+.panel-title > a {
+  display: block;
+  text-decoration: none;
+}
+.reactable-pagination{
+  display: none;
+}
+.pagination > li > a {
+  padding: 5px 10px;
+  font-size: 12px;
+  line-height: 1.5;
+}
+
+.panel-default > .panel-heading{
+  background-color: #f3f6f9;
+  /*padding: 0 10px;*/
+  border-bottom: 1px #bcbcbc solid;
+  border-radius: 4px 4px 0px 0px;
+}
+
+.panel-default > .panel-heading h4 {
+  margin: 0px;
+  font-size: 16px;
+  font-weight: 700;
+  letter-spacing: 1px;
+}
+/*------------------------------------------------*/
+/* Switch SECTION START*/
+/*------------------------------------------------*/
+.switchWrapper{
+  width: 90px;
+  height: 30px;
+  line-height: 30px;
+  overflow: hidden;
+  position: relative;
+  border-radius: 4px;
+  border: 1px solid #ccc;
+}
+.switchSlider{
+  width: 135px;
+  height: auto;
+  position: absolute;
+  top:0;
+  left:-46px;
+  cursor: pointer;
+}
+.switchItemOn{
+  width: 45px;
+  height: 30px;
+  color: #ffffff;
+  background-color: #337ab7;
+  float: left;
+}
+.switchItemMid{
+  width: 44px;
+  height: 30px;
+  background-color: #ffffff;
+  float: left;
+}
+.switchItemOff{
+  width: 45px;
+  height: 30px;
+  color: #000000;
+  background-color: #eeeeee;
+  float: left;
+  clear: right;
+}
+
+.switchSlider.onSlider{
+  left : 0 !important;
+  transition: all 0.5s ease;
+}
+.switchSlider.offSlider{
+  left : -46px !important;
+  transition: all 0.5s ease;
+}
+.sliderText{
+  text-align: center;
+  font-size: 12px;
+  line-height: 29px;
+}
+.switchItemOn.graphSwitchOn{
+    background-color: #5cb85c;
+}
+
+.switchItemOff.graphSwitchOff{
+    background-color: #5bc0de;
+    color: #fff;
+}
+/*------------------------------------------------*/
+/* Switch SECTION END*/
+/*------------------------------------------------*/
+.toast-message {
+  display: none;
+}
+.switchWrapper.lagSwitchSetting{
+  margin-top: 0;
+  width: 90px;
+  height: 20px;
+}
+.lagSwitchSetting .sliderText{
+  line-height: 1.5;
+}
+.box .box-header .box-control span,.box-control span {
+    display: inline-block;
+    width: 20px;
+    height: 20px;
+    font-size: 12px;
+    line-height: 20px;
+    text-align: center;
+    margin: 10px 2px;
+    border-radius: 50%;
+    background-color: #4b4b4b;
+    color: rgba(255,255,255,0.75);
+}
+.box-control span {
+  margin: 0 2px;
+}
+/*.box .box-header .box-control a i {
+    visibility: hidden;
+}
+.box .box-header .box-control:hover a i {
+    visibility: visible;
+}*/
+.box .box-header .box-control span.primary, .box-control span.primary 
{background-color: #1b75bb;}
+/* input range css start here*/
+input[type=range] {
+  -webkit-appearance: none;
+  width: 100%;
+  margin: 6.8px 0;
+}
+input[type=range]:focus {
+  outline: none;
+}
+input[type=range]::-webkit-slider-runnable-track {
+  width: 100%;
+  height: 6.4px;
+  cursor: pointer;
+  box-shadow: 1px 1px 1px rgba(1, 1, 1, 0), 0px 0px 1px rgba(14, 14, 14, 0);
+  background: -moz-linear-gradient(0deg, #cccccc 0%, #ffffff 27%, #ffffff 
100%); /* ff3.6+ */
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, 
#ffffff), color-stop(73%, #ffffff), color-stop(100%, #cccccc)); /* 
safari4+,chrome */
+  background: -webkit-linear-gradient(0deg, #cccccc 0%, #ffffff 27%, #ffffff 
100%); /* safari5.1+,chrome10+ */
+  background: -o-linear-gradient(0deg, #cccccc 0%, #ffffff 27%, #ffffff 100%); 
/* opera 11.10+ */
+  background: -ms-linear-gradient(0deg, #cccccc 0%, #ffffff 27%, #ffffff 
100%); /* ie10+ */
+  background: linear-gradient(0deg, #cccccc 0%, #ffffff 27%, #ffffff 100%); /* 
w3c */
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', 
endColorstr='#cccccc',GradientType=0 ); /* ie6-9 */
+  border-radius: 1px;
+  border: 0px solid #010101;
+}
+input[type=range]::-webkit-slider-thumb {
+  box-shadow: 1px 1px 1px rgba(0, 0, 0, 0), 0px 0px 1px rgba(13, 13, 13, 0);
+  border: 1px solid #186ef7;
+  height: 20px;
+  width: 20px;
+  border-radius: 10px;
+  background: #186ef7;
+  cursor: pointer;
+  -webkit-appearance: none;
+  margin-top: -6.8px;
+}
+input[type=range]:focus::-webkit-slider-runnable-track {
+  background: -moz-linear-gradient(0deg, #cccccc 10%, #ffffff 27%, #ffffff 
100%); /* ff3.6+ */
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(10%, 
#ffffff), color-stop(73%, #ffffff), color-stop(100%, #cccccc)); /* 
safari4+,chrome */
+  background: -webkit-linear-gradient(0deg, #cccccc 10%, #ffffff 27%, #ffffff 
100%); /* safari5.1+,chrome10+ */
+  background: -o-linear-gradient(0deg, #cccccc 10%, #ffffff 27%, #ffffff 
100%); /* opera 11.10+ */
+  background: -ms-linear-gradient(0deg, #cccccc 10%, #ffffff 27%, #ffffff 
100%); /* ie10+ */
+  background: linear-gradient(0deg, #cccccc 10%, #ffffff 27%, #ffffff 100%); 
/* w3c */
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', 
endColorstr='#cccccc',GradientType=0 ); /* ie6-9 */
+}
+input[type=range]::-moz-range-track {
+  width: 100%;
+  height: 6.4px;
+  cursor: pointer;
+  box-shadow: 1px 1px 1px rgba(1, 1, 1, 0), 0px 0px 1px rgba(14, 14, 14, 0);
+  background: #c6c6c6;
+  border-radius: 1px;
+  border: 0px solid #010101;
+}
+input[type=range]::-moz-range-thumb {
+  box-shadow: 1px 1px 1px rgba(0, 0, 0, 0), 0px 0px 1px rgba(13, 13, 13, 0);
+  border: 1px solid #186ef7;
+  height: 20px;
+  width: 20px;
+  border-radius: 10px;
+  background: #186ef7;
+  cursor: pointer;
+}
+input[type=range]::-ms-track {
+  width: 100%;
+  height: 6.4px;
+  cursor: pointer;
+  background: transparent;
+  border-color: transparent;
+  color: transparent;
+}
+input[type=range]::-ms-fill-lower {
+  background: #c6c6c6;
+  border: 0px solid #010101;
+  border-radius: 2px;
+  box-shadow: 1px 1px 1px rgba(1, 1, 1, 0), 0px 0px 1px rgba(14, 14, 14, 0);
+}
+input[type=range]::-ms-fill-upper {
+  background: #c6c6c6;
+  border: 0px solid #010101;
+  border-radius: 2px;
+  box-shadow: 1px 1px 1px rgba(1, 1, 1, 0), 0px 0px 1px rgba(14, 14, 14, 0);
+}
+input[type=range]::-ms-thumb {
+  box-shadow: 1px 1px 1px rgba(0, 0, 0, 0), 0px 0px 1px rgba(13, 13, 13, 0);
+  border: 1px solid #186ef7;
+  height: 20px;
+  width: 20px;
+  border-radius: 10px;
+  background: #186ef7;
+  cursor: pointer;
+  height: 6.4px;
+}
+input[type=range]:focus::-ms-fill-lower {
+  background: #c6c6c6;
+}
+input[type=range]:focus::-ms-fill-upper {
+  background: #c6c6c6;
+}
+input.editInput{
+  width: 68%;
+  float: left;
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/0c188aea/contrib/views/storm/src/main/resources/ui/.babelrc
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/ui/.babelrc 
b/contrib/views/storm/src/main/resources/ui/.babelrc
new file mode 100644
index 0000000..b533394
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/ui/.babelrc
@@ -0,0 +1,25 @@
+{
+  "presets": [
+    ["es2015"],
+    "react",
+    "stage-0",
+    "airbnb"
+  ],
+  "plugins": [
+    "transform-runtime",
+    "transform-decorators-legacy",
+    "transform-flow-strip-types",
+    "transform-es2015-modules-commonjs",
+    "transform-class-properties",
+    "react-hot-loader/babel",
+    "transform-async-to-generator",
+    ["babel-root-slash-import", {
+      "rootPathSuffix": "./app/scripts"
+    }]
+  ],
+  "env": {
+    "production": {
+      "plugins": ["transform-react-remove-prop-types", 
"transform-react-constant-elements","transform-async-to-generator"]
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/0c188aea/contrib/views/storm/src/main/resources/ui/.eslintignore.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/ui/.eslintignore.js 
b/contrib/views/storm/src/main/resources/ui/.eslintignore.js
new file mode 100644
index 0000000..2c4e446
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/ui/.eslintignore.js
@@ -0,0 +1,3 @@
+node_modules/*
+**/bower_components/*
+**/vendor/*.js

http://git-wip-us.apache.org/repos/asf/ambari/blob/0c188aea/contrib/views/storm/src/main/resources/ui/.eslintrc.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/ui/.eslintrc.js 
b/contrib/views/storm/src/main/resources/ui/.eslintrc.js
new file mode 100644
index 0000000..473fe48
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/ui/.eslintrc.js
@@ -0,0 +1,58 @@
+module.exports = {
+  "parser": "babel-eslint",
+  "rules": {
+    "strict": 0
+  },
+  "env": {
+    "browser": true,
+    "es6": true,
+    "jquery": true
+  },
+  "parserOptions": {
+    "sourceType": "module"
+  },
+  "plugins": [
+    "header",
+    "react"
+  ],
+  "rules": {
+    "header/header": [2, "block", [
+      "*",
+      " 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.",
+      "*"
+    ]],
+    "comma-dangle": [
+      "error",
+      "never"
+    ],
+    "indent": [
+      "error",
+      2
+    ],
+    "linebreak-style": [
+      "error",
+      "unix"
+    ],
+    "semi": [
+      "error",
+      "always"
+    ],
+    /* Advanced Rules*/
+    "no-unexpected-multiline": 2,
+    "curly": [2,"all"]
+  }
+};

http://git-wip-us.apache.org/repos/asf/ambari/blob/0c188aea/contrib/views/storm/src/main/resources/ui/app/scripts/components/BarChart.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/ui/app/scripts/components/BarChart.jsx 
b/contrib/views/storm/src/main/resources/ui/app/scripts/components/BarChart.jsx
new file mode 100644
index 0000000..dffd898
--- /dev/null
+++ 
b/contrib/views/storm/src/main/resources/ui/app/scripts/components/BarChart.jsx
@@ -0,0 +1,429 @@
+/**
+ 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.
+**/
+
+import React, {Component} from 'react';
+import PropTypes from 'prop-types';
+import ReactDOM from 'react-dom';
+import d3 from 'd3';
+import d3Tip from 'd3-tip';
+
+export default class BarChart extends Component{
+  static propTypes = {
+    data: PropTypes.array.isRequired,
+    width: PropTypes.number,
+    height: PropTypes.number
+  }
+
+  constructor(props) {
+    super(props);
+  }
+
+  componentDidMount(){
+    this.setUpSVG();
+    this.initToolTip();
+    this.setLayout();
+    this.initSets();
+    this.barTypeTransition = this.transitionGrouped;
+    this.hiddenLayers = [];
+    this.drawBars();
+    this.drawXAxis();
+    this.drawYAxis();
+    this.drawTooltip();
+    this.drawLegends();
+  }
+
+  initSets(){
+    this.layers = this.dataMapY(this.props.data);
+    // this.setMax();
+    this.setX();
+    this.setY();
+    this.colorDomain();
+    this.setXAxis();
+    this.setYAxis();
+  }
+
+  setUpSVG(){
+    this.svg = d3.select(ReactDOM.findDOMNode(this))
+      .attr('width', this.props.width+"px")
+      .attr('height', this.props.height+50+"px");
+      // .attr("viewBox", "-46 -5 " + (this.props.width+82) + " " + 
(this.props.height+28) );
+
+    this.container = this.svg.append("g")
+      .attr('class', 'svg-container')
+      .attr("transform", "translate(50,10)");
+
+    this.tipcontainer = this.svg.append('g').classed('tip-g', true)
+      .attr("transform", "translate(" + 40 + "," + 0 + ")");
+
+    this.tipcontainer.append('g').classed('tipLine-g', 
true).append('line').classed('tipline', true)
+      .style('stroke', '#aaa')
+      .style('visibility', 'hidden')
+      // .style('shape-rendering', 'crispEdges')
+      .attr('x1', 0).attr('x2', 0).attr('y1', 0).attr('y2', this.props.height);
+  }
+
+  initToolTip() {
+    let self = this;
+    this.tip = d3Tip()
+      .attr('class', 'd3-tip')
+      .offset([-10, 0])
+      .html(function(d) {
+        return self.toolTipHtml.call(self, d);
+      });
+    this.svg.call(this.tip);
+    // const container = document.getElementById('app_container');
+    // container.append($('body > .d3-tip'));
+  }
+
+  setMax() {
+    this.yGroupMax = d3.max(this.layers, function(layer) {
+      return d3.max(layer, function(d) {
+        return d.y;
+      });
+    });
+    this.yGroupMin = d3.min(this.layers, function(layer) {
+      return d3.min(layer, function(d) {
+        return d.y;
+      });
+    });
+    this.yStackMax = d3.max(this.layers, function(layer) {
+      return d3.max(layer, function(d) {
+        return d.y0 + d.y;
+      });
+    });
+    this.yStackMin = d3.min(this.layers, function(layer) {
+      return d3.min(layer, function(d) {
+        return d3.min([d.y0, d.y]);
+      });
+    });
+  }
+
+  setX() {
+    let self = this;
+    this.x = d3.scale.ordinal()
+      .domain(self.layers[0].map(function(d) {
+        return d.x;
+      }))
+      .rangeRoundBands([0, this.props.width], 0.08);
+  }
+
+  setY() {
+    this.y = d3.scale.linear()
+      .domain([this.yStackMin, this.yStackMax])
+      .range([this.props.height, 0]);
+  }
+
+  setXAxis() {
+    this.xAxis = d3.svg.axis().scale(this.x).orient("bottom");
+  }
+
+  setYAxis() {
+    let formatValue = d3.format('.2s');
+    this.yAxis = d3.svg
+      .axis()
+      .scale(this.y)
+      .orient("left")
+      .tickFormat(function(d){return formatValue(d);});
+  }
+
+  drawXAxis(xAxis, container, height) {
+    let xA = xAxis || this.xAxis,
+      containor = container || this.container,
+      hght = height || this.props.height;
+
+    this.xAxisGrp = containor['xAxisEl'] = containor.append("g")
+      .attr("class", "x axis")
+      .attr("transform", "translate(0," + hght + ")")
+      .call(xA)
+      .selectAll(".tick text")
+      .call(this.wrap, this.x.rangeBand());
+  }
+
+  wrap(text, width) {
+    text.each(function() {
+      let text = d3.select(this),
+        words = text.text().split(/-+/).reverse(),
+        word,
+        line = [],
+        lineNumber = 0,
+        lineHeight = 1.1, // ems
+        y = text.attr("y"),
+        dy = parseFloat(text.attr("dy")),
+        tspan = text.text(null).append("tspan").attr("x", 0).attr("y", 
y).attr("dy", dy + "em");
+
+      //Hack to show hidden div to find getComputedTextLength
+      // $('#lag-graph').css({visibility: 'hidden', display: 'block', 
position: 'absolute'});
+
+      while (word = words.pop()) {
+        line.push(word);
+        tspan.text(line.join(" "));
+        if (tspan.node().getComputedTextLength() > width) {
+          line.pop();
+          tspan.text(line.join(" "));
+          line = [word];
+          tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", 
++lineNumber * lineHeight + dy + "em").text(word);
+        }
+      }
+      // $('#lag-graph').css({visibility: '', display: 'none', position: ''});
+    });
+  }
+
+  drawYAxis(x) {
+    let yAxis = this.yAxis;
+    this.yAxisGrp = this.container.append("g")
+      .attr("class", "y axis");
+    this.yAxisGrp.ticks = this.yAxisGrp.call(yAxis);
+    this.yAxisGrp.append('text')
+      .text(this.props.yAttr[0].toUpperCase() + 
this.props.yAttr.substr(1,this.props.yAttr.length)).attr("text-anchor", "end")
+      .attr("y", 6)
+      .attr("dy", ".75em")
+      .attr("transform", "rotate(-90)");
+  }
+
+  dataMapY(data) {
+    let self = this;
+    let keys = d3.keys(data[0]).filter(function(key) {
+      return key !== self.props.xAttr;
+    });
+    let layers = this.stack(keys.map(function(yAttr) {
+      return data.map(function(d) {
+        return {
+          x: d[self.props.xAttr],
+          y: d[yAttr],
+          type: yAttr
+        };
+      });
+    }));
+    let allLayers = layers.allLayers = [];
+    layers.forEach(function(d) {
+      allLayers.push(d);
+    });
+    return layers;
+  }
+
+  setLayout() {
+    let self = this;
+    this.stack = d3.layout.stack();
+  }
+
+  colorDomain() {
+    let self = this;
+    this.color = d3.scale.ordinal()
+      .range(["#b9cde5", "#1B76BB"]);
+    // this.color = d3.scale.category20c();
+    // this.color.domain(d3.keys(this.props.data[0]).filter(function(key) {
+    //         return key !== self.props.xAttr;
+    // }));
+  }
+
+  drawBars() {
+    let self = this;
+
+    this.layers_g = this.container.selectAll(".barLayer")
+      .data(this.layers);
+
+    this.layers_g
+      .exit()
+      .remove();
+
+    this.layers_g
+      .enter().append("g")
+      .attr("class", "barLayer")
+      .style("fill", function(d, i) {
+        return self.color(d[0].type);
+      });
+
+    this.rect = this.layers_g.selectAll("rect")
+      .data(function(d) {
+        return d;
+      });
+
+    this.rect
+      .exit()
+      .remove();
+
+    this.rect
+      .enter().append("rect")
+      .attr("x", function(d) {
+        return self.x(d.x);
+      })
+      .attr("y", function(d) {
+        return self.props.height;
+      })
+      .attr("width", function(d) {
+        return self.x.rangeBand();
+      })
+      .classed("visible", true)
+      .attr("height", function(d) {
+        return 0;
+      });
+
+    this.barTypeTransition();
+  }
+
+  transitionGrouped() {
+    let x = this.x,
+      y = this.y,
+      height = this.props.height,
+      n = this.layers.length;
+    this.setMax();
+    let yMin = this.yGroupMin < 0 ? this.yGroupMin : 0;
+    this.y.domain([yMin, this.yGroupMax]);
+
+    let barWidth = (x.rangeBand() / n > 25) ? 25 : x.rangeBand() / n;
+    let xArr = new Array(n);
+    this.layers_g.selectAll('rect.visible')
+      .attr("x", function(d, i, j) {
+        if (xArr[i] == undefined) {
+          xArr[i] = x(d.x) + (x.rangeBand() / 2) - (n / 2 * barWidth);
+        } else {
+          xArr[i] += barWidth;
+        }
+        return xArr[i];
+      })
+      .attr("width", barWidth)
+      .transition().duration(500)
+      .attr("y", function(d) {
+        let _y = y(d.y);
+        if (d.y < 0){
+          _y = y(d.y) - (height - y(0));
+        }
+        return _y;
+      })
+      .attr("height", function(d) {
+        return (height - y(Math.abs(d.y))) - (height - y(0));
+      });
+    
this.container.select(".y.axis").transition().duration(500).call(this.yAxis);
+  }
+
+  transitionStacked() {
+    this.stack(this.layers);
+    let x = this.x,
+      y = this.y,
+      height = this.props.height,
+      self = this,
+      n = this.layers.length;
+    this.setMax();
+    this.y.domain([this.yStackMin, this.yStackMax]);
+
+    let barWidth = (x.rangeBand() / n > 25) ? 25 : x.rangeBand() / n;
+    let xArr = new Array(n);
+    this.layers_g.selectAll('rect.visible').transition().duration(500)
+      .attr("y", function(d) {
+        let _y = y(d.y0 + d.y);
+        if (d.y < 0){
+          _y = y(d.y) - Math.abs(y(d.y0) - y(d.y0 + d.y));
+        }
+        return _y;
+      })
+      .attr("height", function(d) {
+        return Math.abs(y(d.y0) - y(d.y0 + d.y));
+      })
+      .attr("x", function(d, i, j) {
+        xArr[i] = x(d.x) + (x.rangeBand() / 2) - (barWidth / 2);
+        return xArr[i];
+      })
+      .attr("width", barWidth);
+    
this.container.select(".y.axis").transition().duration(500).call(this.yAxis);
+  }
+
+  drawTooltip() {
+    let self = this;
+    let x = this.x.rangeBand ? this.x : d3.scale.ordinal()
+      .domain(self.data.map(function(d) {
+        return d[self.props.xAttr];
+      }))
+      .rangeRoundBands([0, this.props.width]);
+
+    let tipline = this.tipcontainer.select('.tipline');
+
+    this.tipcontainer.append('g').classed('tipRect-g', 
true).selectAll(".tipRect")
+      .data(this.props.data)
+      .enter().append("rect")
+      .attr("class", "tipRect")
+      .style('opacity', '0')
+      .attr("x", function(d) {
+        return self.x(d[self.props.xAttr]);
+      })
+      .attr("width", function() {
+        return x.rangeBand();
+      })
+      .attr("y", function(d) {
+        return 0;
+      })
+      .attr("height", function(d) {
+        return self.props.height;
+      })
+      .on('mouseover', function(d) {
+        let x1 = parseInt(d3.select(this).attr('x')) + parseInt((x.rangeBand() 
/ 2));
+        tipline.attr('x1', x1).attr('x2', x1);
+        tipline.style('visibility', 'visible');
+        return self.tip.show(d,this);
+      })
+      .on('mouseout', function(d) {
+        tipline.style('visibility', 'hidden');
+        return self.tip.hide(d,this);
+      });
+  }
+
+  toolTipHtml(d) {
+    let self = this;
+    let html = d[self.props.xAttr] + '<table><tbody>';
+    _.each(d, function(val, key) {
+      if (key != self.props.xAttr){
+        html += '<tr><td>' + key + ' </td><td> ' + val + '</td></tr>';
+      }
+    });
+    html += '</tbody></table>';
+    return html;
+  }
+
+  drawLegends() {
+    let self = this;
+    let legends = this.legendsEl = document.createElement('ul');
+    legends = d3.select(legends)
+      .attr('class', 'legends')
+      .style('list-style', 'none');
+
+    let legend = legends.selectAll('.legend')
+      .data(this.color.domain())
+      .enter()
+      .append('li')
+      .attr('class', 'legend');
+
+    legend.append('div')
+      .style('width', '10px')
+      .style('height', '10px')
+      .style('display', 'inline-block')
+      .style('background-color', function(d) {
+        return self.color(d);
+      });
+
+    legend.append('span')
+      .style('padding', '4px 0 4px 4px')
+      .text(function(d) {
+        return d;
+      });
+  }
+
+  render() {
+    return (
+      <svg></svg>
+    );
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/0c188aea/contrib/views/storm/src/main/resources/ui/app/scripts/components/Breadcrumbs.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/ui/app/scripts/components/Breadcrumbs.jsx
 
b/contrib/views/storm/src/main/resources/ui/app/scripts/components/Breadcrumbs.jsx
new file mode 100644
index 0000000..e4926ab
--- /dev/null
+++ 
b/contrib/views/storm/src/main/resources/ui/app/scripts/components/Breadcrumbs.jsx
@@ -0,0 +1,45 @@
+/**
+ 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.
+**/
+
+import React, {Component} from 'react';
+import PropTypes from 'prop-types';
+import ReactDom from 'react-dom';
+
+export default class Breadcrumbs extends Component{
+  static propTypes = {
+    links: PropTypes.array.isRequired
+  }
+  render() {
+    return (
+      <ol id="breadcrumb">
+        {this.renderLinks()}
+      </ol>
+    );
+  }
+  renderLinks() {
+    var links = [];
+    for(var i = 0; i < this.props.links.length; i++){
+      var object = this.props.links[i];
+      if(object.link === '#/'){
+        object.title = <i className="fa fa-home"></i>;
+      }
+      links.push(<li key={i}><a href={object.link}>{object.title}</a></li>);
+    }
+    return links;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/0c188aea/contrib/views/storm/src/main/resources/ui/app/scripts/components/CommonNotification.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/ui/app/scripts/components/CommonNotification.jsx
 
b/contrib/views/storm/src/main/resources/ui/app/scripts/components/CommonNotification.jsx
new file mode 100644
index 0000000..34e402c
--- /dev/null
+++ 
b/contrib/views/storm/src/main/resources/ui/app/scripts/components/CommonNotification.jsx
@@ -0,0 +1,69 @@
+/**
+ 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.
+**/
+
+import React, {Component} from 'react';
+import PropTypes from 'prop-types';
+import {notifyTextLimit} from '../utils/Constants';
+
+class CommonNotification extends Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      data: false,
+      text: "Read more"
+    };
+  }
+  showMore = () => {
+    if (this.state.text === "Read more") {
+      this.setState({text: "Hide", data: true});
+    } else {
+      this.setState({text: "Read more", data: false});
+    }
+  }
+
+  render() {
+    /* flag value         error, info, sucess */
+    const {text, data} = this.state;
+    const {flag, content} = this.props;
+    const initial = content.substr(0, notifyTextLimit);
+    const moreText = content.substr(notifyTextLimit);
+    const readMoreTag = <a href="javascript:void(0)" 
onClick={this.showMore}>{text}</a>;
+    return (
+      <div>
+        {initial}
+        {(data)
+          ? moreText
+          : null
+}
+        <div>
+          {(flag === 'error' && moreText.length > 0)
+            ? readMoreTag
+            : null
+}
+        </div>
+      </div>
+    );
+  }
+}
+
+export default CommonNotification;
+
+CommonNotification.propTypes = {
+  flag: PropTypes.string.isRequired,
+  content: PropTypes.string
+};

http://git-wip-us.apache.org/repos/asf/ambari/blob/0c188aea/contrib/views/storm/src/main/resources/ui/app/scripts/components/CommonPagination.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/ui/app/scripts/components/CommonPagination.jsx
 
b/contrib/views/storm/src/main/resources/ui/app/scripts/components/CommonPagination.jsx
new file mode 100644
index 0000000..5128a09
--- /dev/null
+++ 
b/contrib/views/storm/src/main/resources/ui/app/scripts/components/CommonPagination.jsx
@@ -0,0 +1,56 @@
+/**
+ 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.
+**/
+
+import React, {Component} from 'react';
+import _ from 'lodash';
+import {Pagination} from 'react-bootstrap';
+
+export default class CommonPagination extends Component{
+  constructor(props){
+    super(props);
+  }
+
+  handleSelect = (eventKey) => {
+    this.props.callBackFunction(eventKey,this.props.tableName);
+  }
+
+  render(){
+    const {activePage,pageSize,filteredEntities} = this.props;
+    const totalPages = Math.ceil(filteredEntities.length / pageSize);
+
+    return(
+      <div className="pagination-wrapper">
+        <div className="pull-left">
+          <span>{`Showing ${activePage > 1 ? (activePage-1)*pageSize : 
activePage }  to ${activePage*pageSize > filteredEntities.length ? 
filteredEntities.length : (activePage*pageSize)} of ${filteredEntities.length} 
entries`}</span>
+        </div>
+        <Pagination
+         className={`${filteredEntities.length === 0? 'hidden':'shown 
pull-right'}`}
+         prev={false}
+         next={false}
+         first
+         last
+         ellipsis
+         items={totalPages}
+         maxButtons={5}
+         activePage={activePage}
+         onSelect={this.handleSelect}>
+      </Pagination>
+      </div>
+    );
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/0c188aea/contrib/views/storm/src/main/resources/ui/app/scripts/components/CommonSwitchComponent.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/ui/app/scripts/components/CommonSwitchComponent.jsx
 
b/contrib/views/storm/src/main/resources/ui/app/scripts/components/CommonSwitchComponent.jsx
new file mode 100644
index 0000000..804f51e
--- /dev/null
+++ 
b/contrib/views/storm/src/main/resources/ui/app/scripts/components/CommonSwitchComponent.jsx
@@ -0,0 +1,41 @@
+/**
+ 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.
+**/
+
+import React, {Component} from 'react';
+
+export default class CommonSwitchComponent extends Component {
+  render(){
+    const {switchCallBack,checked,textON,textOFF,KYC} = this.props;
+    let switchId = "switch-"+((Math.random())*100).toFixed(0);
+    return (
+      <div className={`switchWrapper ${!!KYC ? 'lagSwitchSetting pull-right' : 
''}`}>
+        <span className={`switchSlider ${checked ?  'onSlider' : 
'offSlider'}`} onClick={switchCallBack}>
+          <span className={`switchItemOn sliderText ${!!KYC ? 'graphSwitchOn' 
: ''}`}>{textON}</span>
+          <span className="switchItemMid"></span>
+          <span className={`switchItemOff sliderText ${!!KYC ? 
'graphSwitchOff' : ''}`}>{textOFF}</span>
+        </span>
+      </div>
+
+    );
+  }
+}
+
+CommonSwitchComponent.defaultProps = {
+  textON : "ON",
+  textOFF : "OFF"
+};

http://git-wip-us.apache.org/repos/asf/ambari/blob/0c188aea/contrib/views/storm/src/main/resources/ui/app/scripts/components/CommonWindowPanel.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/ui/app/scripts/components/CommonWindowPanel.jsx
 
b/contrib/views/storm/src/main/resources/ui/app/scripts/components/CommonWindowPanel.jsx
new file mode 100644
index 0000000..0f8130f
--- /dev/null
+++ 
b/contrib/views/storm/src/main/resources/ui/app/scripts/components/CommonWindowPanel.jsx
@@ -0,0 +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
+*
+     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.
+**/
+
+import React, {Component} from 'react';
+import Select from 'react-select';
+import CommonSwitchComponent from './CommonSwitchComponent';
+import {OverlayTrigger, Tooltip} from 'react-bootstrap';
+
+export default class CommonWindowPanel extends Component{
+  constructor(props){
+    super(props);
+  }
+
+  windowChange = (obj) => {
+    this.props.handleWindowChange(obj);
+  }
+
+  commonToggleChange = (params) => {
+    this.props.toggleSystem(params);
+  }
+
+  commonTopologyActionHandler = (action) => {
+    this.props.handleTopologyAction(action);
+  }
+
+  render(){
+    const 
{selectedWindowKey,windowOptions,systemFlag,debugFlag,handleLogLevel,topologyStatus,KYC,handleProfiling}
 = this.props;
+    return(
+      <div className="form-group no-margin">
+        <label className="col-sm-1 control-label">Window</label>
+        <div className="col-sm-2">
+          <Select value={selectedWindowKey} options={windowOptions} 
onChange={this.windowChange.bind(this)} valueKey="label" labelKey="label" 
clearable={false}/>
+        </div>
+        <label className="col-sm-2 control-label">System Summary</label>
+        <div className="col-sm-2">
+          <CommonSwitchComponent checked={systemFlag} 
switchCallBack={this.commonToggleChange.bind(this,'systemFlag')}/>
+        </div>
+        <label className="col-sm-1 control-label">Debug</label>
+        <div className="col-sm-1">
+          <CommonSwitchComponent checked={debugFlag} 
switchCallBack={this.commonToggleChange.bind(this,'debugFlag')}/>
+        </div>
+        <div className="col-sm-3 text-right">
+          <div className="btn-group" role="group">
+            {
+              KYC === 'detailView'
+              ? [ <OverlayTrigger  key={1} placement="top" overlay={<Tooltip 
id="tooltip1">Activate</Tooltip>}>
+                    <button type="button" className="btn btn-primary" 
onClick={this.commonTopologyActionHandler.bind(this,'activate')} 
disabled={topologyStatus === 'ACTIVE' ? "disabled" : null}>
+                      <i className="fa fa-play"></i>
+                    </button>
+                  </OverlayTrigger>,
+                <OverlayTrigger key={2}  placement="top" overlay={<Tooltip 
id="tooltip1">Deactivate</Tooltip>}>
+                  <button type="button" className="btn btn-primary" 
onClick={this.commonTopologyActionHandler.bind(this,'deactivate')}  
disabled={topologyStatus === 'INACTIVE' ? "disabled" : null}>
+                    <i className="fa fa-stop"></i>
+                  </button>
+                </OverlayTrigger>,
+                <OverlayTrigger key={3} placement="top" overlay={<Tooltip 
id="tooltip1">Rebalance</Tooltip>}>
+                  <button type="button" className="btn btn-primary" 
onClick={this.commonTopologyActionHandler.bind(this,'rebalance')} 
disabled={topologyStatus === 'REBALANCING' ? "disabled" : null}>
+                    <i className="fa fa-balance-scale"></i>
+                  </button>
+                </OverlayTrigger>,
+                <OverlayTrigger  key={4} placement="top" overlay={<Tooltip 
id="tooltip1">Kill</Tooltip>}>
+                  <button type="button" className="btn btn-primary" 
onClick={this.commonTopologyActionHandler.bind(this,'kill')} 
disabled={topologyStatus === 'KILLED' ? "disabled" : null}>
+                    <i className="fa fa-ban"></i>
+                  </button>
+                </OverlayTrigger>,
+                <OverlayTrigger key={5} placement="top" overlay={<Tooltip 
id="tooltip1">Change Log Level</Tooltip>}>
+                  <button  type="button" className="btn btn-primary" 
onClick={handleLogLevel}>
+                    <i className="fa fa-file-o"></i>
+                  </button>
+                </OverlayTrigger>
+              ]
+              : <OverlayTrigger placement="top" overlay={<Tooltip 
id="tooltip1">Profiling & Debugging</Tooltip>}>
+                  <button type="button" className="btn btn-primary" 
onClick={handleProfiling}>
+                   <i className="fa fa-cogs"></i>
+                 </button>
+                </OverlayTrigger>
+
+            }
+          </div>
+        </div>
+      </div>
+    );
+  }
+}

Reply via email to