ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From yus...@apache.org
Subject [05/22] ambari git commit: Revert "AMBARI-21955. Update React version to 15.6.2 to get MIT license. (Sanket Shah via yusaku)"
Date Fri, 20 Oct 2017 21:01:02 GMT
http://git-wip-us.apache.org/repos/asf/ambari/blob/03735c99/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
new file mode 100644
index 0000000..136d95f
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/views/TopologyDetailView.jsx
@@ -0,0 +1,1039 @@
+/**
+ 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/03735c99/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
new file mode 100644
index 0000000..25441fa
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/views/TopologyListingView.jsx
@@ -0,0 +1,65 @@
+/**
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+*
+     http://www.apache.org/licenses/LICENSE-2.0
+*
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+define([
+	'jsx!components/Table',
+	'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/03735c99/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 71c26c4..f6b1685 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,8 +140,7 @@ body {
 }
 
 /* Boxes */
-.box,
-.panel.panel-default {
+.box {
     position: relative;
     margin-bottom: 15px;
     border: 1px #bcbcbc solid;
@@ -162,8 +161,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;
@@ -171,12 +170,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-control a {
+.box .box-header .box-control a {
     display: inline-block;
     width: 20px;
     height: 20px;
@@ -188,21 +187,18 @@ 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, .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-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-body {
     padding: 10px;
@@ -289,7 +285,7 @@ body {
 .tile.warning > .tile-header {
     background-color: #ED940E;
 }
-.tile.success, .label-success {
+.tile.success {
     background: #1bbb60;
 }
 .tile.success > .tile-header {
@@ -476,12 +472,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 {
@@ -538,7 +534,7 @@ ul.legends li.legend{
 }
 #modal-rebalance .modal-body{
   max-height: 450px;
-  overflow-y: auto;
+  overflow-y: auto; 
 }
 .loader {
   position: fixed;
@@ -546,7 +542,7 @@ ul.legends li.legend{
   bottom: 0;
   left: 0;
   right: 0;
-  background: url('../img/loader.gif') rgba(255,255,255,0.75) no-repeat center center;
+  background: url('../images/loader.gif') rgba(255,255,255,0.75) no-repeat center center;
   z-index: 9;
 }
 .inner-loader{
@@ -555,7 +551,7 @@ ul.legends li.legend{
   left: 0px;
   bottom: 0px;
   right: 0px;
-  background: url('../img/loader.gif') rgba(255,255,255,0.75) no-repeat center center;
+  background: url('../images/loader.gif') rgba(255,255,255,0.75) no-repeat center center;
 }
 .searchbar{
   margin-top: 15px;
@@ -577,260 +573,7 @@ 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;
-}
-.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;
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/03735c99/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
deleted file mode 100644
index b533394..0000000
--- a/contrib/views/storm/src/main/resources/ui/.babelrc
+++ /dev/null
@@ -1,25 +0,0 @@
-{
-  "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/03735c99/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
deleted file mode 100644
index 2c4e446..0000000
--- a/contrib/views/storm/src/main/resources/ui/.eslintignore.js
+++ /dev/null
@@ -1,3 +0,0 @@
-node_modules/*
-**/bower_components/*
-**/vendor/*.js

http://git-wip-us.apache.org/repos/asf/ambari/blob/03735c99/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
deleted file mode 100644
index 473fe48..0000000
--- a/contrib/views/storm/src/main/resources/ui/.eslintrc.js
+++ /dev/null
@@ -1,58 +0,0 @@
-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/03735c99/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
deleted file mode 100644
index dffd898..0000000
--- a/contrib/views/storm/src/main/resources/ui/app/scripts/components/BarChart.jsx
+++ /dev/null
@@ -1,429 +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.
-**/
-
-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/03735c99/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
deleted file mode 100644
index e4926ab..0000000
--- a/contrib/views/storm/src/main/resources/ui/app/scripts/components/Breadcrumbs.jsx
+++ /dev/null
@@ -1,45 +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.
-**/
-
-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/03735c99/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
deleted file mode 100644
index 34e402c..0000000
--- a/contrib/views/storm/src/main/resources/ui/app/scripts/components/CommonNotification.jsx
+++ /dev/null
@@ -1,69 +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.
-**/
-
-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/03735c99/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
deleted file mode 100644
index 5128a09..0000000
--- a/contrib/views/storm/src/main/resources/ui/app/scripts/components/CommonPagination.jsx
+++ /dev/null
@@ -1,56 +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.
-**/
-
-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/03735c99/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
deleted file mode 100644
index 804f51e..0000000
--- a/contrib/views/storm/src/main/resources/ui/app/scripts/components/CommonSwitchComponent.jsx
+++ /dev/null
@@ -1,41 +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.
-**/
-
-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/03735c99/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
deleted file mode 100644
index 0f8130f..0000000
--- a/contrib/views/storm/src/main/resources/ui/app/scripts/components/CommonWindowPanel.jsx
+++ /dev/null
@@ -1,99 +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.
-**/
-
-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>
-    );
-  }
-}


Mime
View raw message