Repository: ambari
Updated Branches:
  refs/heads/trunk e3a8cd552 -> c53de061f


AMBARI-16625. Storm Ambari view should work with Firefox 25 (Sriharsha 
Chintalapani via srimanth)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/c53de061
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/c53de061
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/c53de061

Branch: refs/heads/trunk
Commit: c53de061f3c48504881a18a9fb19f1c702bd72ce
Parents: e3a8cd5
Author: Srimanth Gunturi <[email protected]>
Authored: Wed May 18 13:45:35 2016 -0700
Committer: Srimanth Gunturi <[email protected]>
Committed: Wed May 18 13:45:44 2016 -0700

----------------------------------------------------------------------
 .../scripts/collections/BaseCollection.js       | 24 ++++++++-
 .../scripts/components/Breadcrumbs.jsx          |  3 ++
 .../main/resources/scripts/components/Modal.jsx |  6 +++
 .../scripts/components/RadialChart.jsx          | 11 +++-
 .../resources/scripts/components/SpoutGraph.jsx |  3 ++
 .../main/resources/scripts/components/Table.jsx | 11 +++-
 .../scripts/components/TopologyGraph.jsx        |  5 ++
 .../scripts/containers/NimbusSummary.jsx        | 14 ++++-
 .../scripts/containers/SupervisorSummary.jsx    | 20 ++++++-
 .../containers/TopologyConfiguration.jsx        |  3 ++
 .../scripts/containers/TopologyDetailGraph.jsx  |  4 ++
 .../scripts/containers/TopologyListing.jsx      | 14 ++++-
 .../scripts/modules/Table/Pagination.jsx        |  5 +-
 .../src/main/resources/scripts/router/Router.js |  4 +-
 .../scripts/views/ComponentDetailView.jsx       | 35 +++++++++++--
 .../resources/scripts/views/ProfilingView.jsx   | 11 ++++
 .../resources/scripts/views/RebalanceView.jsx   |  9 +++-
 .../scripts/views/TopologyDetailView.jsx        | 55 +++++++++++++++++---
 18 files changed, 214 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/c53de061/contrib/views/storm/src/main/resources/scripts/collections/BaseCollection.js
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/collections/BaseCollection.js 
b/contrib/views/storm/src/main/resources/scripts/collections/BaseCollection.js
index 29b1ce9..ab1b64a 100644
--- 
a/contrib/views/storm/src/main/resources/scripts/collections/BaseCollection.js
+++ 
b/contrib/views/storm/src/main/resources/scripts/collections/BaseCollection.js
@@ -52,7 +52,29 @@ define(['require',
             
this.getFirstPage().fullCollection.reset(this.unfilteredCollection.models);
           }
           var results = _.filter(this.fullCollection.models,function(model) {
-             var regexTest = new RegExp(letters,"i");
+              var pattern = letters;
+              if(pattern.indexOf('\\') > -1)
+                pattern = pattern.replace(/\\/g, '\\\\');
+              if(pattern.indexOf('*') > -1)
+                pattern = pattern.replace(/\*/g, '\\*');
+              if(pattern.indexOf('$') > -1)
+                pattern = pattern.replace(/\$/g, '\\$');
+              if(pattern.indexOf('^') > -1)
+                pattern = pattern.replace(/\^/g, '\\^');
+              if(pattern.indexOf('+') > -1)
+                pattern = pattern.replace(/\+/g, '\\+');
+              if(pattern.indexOf('?') > -1)
+                pattern = pattern.replace(/\?/g, '\\?');
+              if(pattern.indexOf('(') > -1)
+                pattern = pattern.replace(/\(/g, '\\(');
+              if(pattern.indexOf(')') > -1)
+                pattern = pattern.replace(/\)/g, '\\)');
+              if(pattern.indexOf('[') > -1)
+                pattern = pattern.replace(/\[/g, '\\[');
+              if(pattern.indexOf(']') > -1)
+                pattern = pattern.replace(/\]/g, '\\]');
+
+             var regexTest = new RegExp(pattern,"i");
              var result = false;
               _.each(this.searchFields, function(field) {
                 if(regexTest.test(model.get(field))) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/c53de061/contrib/views/storm/src/main/resources/scripts/components/Breadcrumbs.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/components/Breadcrumbs.jsx 
b/contrib/views/storm/src/main/resources/scripts/components/Breadcrumbs.jsx
index 75c2fa9..deff030 100644
--- a/contrib/views/storm/src/main/resources/scripts/components/Breadcrumbs.jsx
+++ b/contrib/views/storm/src/main/resources/scripts/components/Breadcrumbs.jsx
@@ -22,6 +22,9 @@ define(['react',
        'use strict';
     return React.createClass({
                displayName: 'Breadcrumbs',
+        propTypes: {
+            links: React.PropTypes.array.isRequired
+        },
                getInitialState: function() {
                        return null;
                },

http://git-wip-us.apache.org/repos/asf/ambari/blob/c53de061/contrib/views/storm/src/main/resources/scripts/components/Modal.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/components/Modal.jsx 
b/contrib/views/storm/src/main/resources/scripts/components/Modal.jsx
index e37b734..3ac9d8c 100644
--- a/contrib/views/storm/src/main/resources/scripts/components/Modal.jsx
+++ b/contrib/views/storm/src/main/resources/scripts/components/Modal.jsx
@@ -20,6 +20,12 @@ define(['react', 'react-dom', 'bootstrap'], function(React, 
ReactDOM) {
        'use strict';
        return React.createClass({
                displayName: 'Modal',
+               propTypes: {
+                       modalId: React.PropTypes.string.isRequired,
+                       header: React.PropTypes.node,
+                       content: React.PropTypes.node,
+                       footer: React.PropTypes.node
+               },
                getInitialState: function(){
                        
                        return null;

http://git-wip-us.apache.org/repos/asf/ambari/blob/c53de061/contrib/views/storm/src/main/resources/scripts/components/RadialChart.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/components/RadialChart.jsx 
b/contrib/views/storm/src/main/resources/scripts/components/RadialChart.jsx
index f28b08a..10432a8 100644
--- a/contrib/views/storm/src/main/resources/scripts/components/RadialChart.jsx
+++ b/contrib/views/storm/src/main/resources/scripts/components/RadialChart.jsx
@@ -20,10 +20,19 @@ define(['react', 'react-dom', 'd3', 'd3.tip'], 
function(React, ReactDOM, d3) {
        'use strict';
        return React.createClass({
                displayName: 'RadialChart',
+               propTypes: {
+                       data: React.PropTypes.array.isRequired,
+                       labels: React.PropTypes.array.isRequired,
+                       width: React.PropTypes.string,
+                       height: React.PropTypes.string,
+                       innerRadius: React.PropTypes.string.isRequired,
+                       outerRadius: React.PropTypes.string.isRequired,
+                       color: React.PropTypes.array
+               },
                getInitialState: function(){
                        this.const = {
                                tau: 2 * Math.PI,
-                               width: this.props.width || "64",
+                               width: this.props.width || "44",
                                height: this.props.height || "52",
                                innerRadius: parseInt(this.props.innerRadius, 
10) || 20,
                                outerRadius: parseInt(this.props.outerRadius, 
10) || 25,

http://git-wip-us.apache.org/repos/asf/ambari/blob/c53de061/contrib/views/storm/src/main/resources/scripts/components/SpoutGraph.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/components/SpoutGraph.jsx 
b/contrib/views/storm/src/main/resources/scripts/components/SpoutGraph.jsx
index cec4c85..94bad11 100644
--- a/contrib/views/storm/src/main/resources/scripts/components/SpoutGraph.jsx
+++ b/contrib/views/storm/src/main/resources/scripts/components/SpoutGraph.jsx
@@ -22,6 +22,9 @@ define(['react',
        'use strict';
        return React.createClass({
                displayName: 'SpoutGraph',
+               propTypes: {
+                       spout: React.PropTypes.object.isRequired
+               },
                getInitialState: function(){
                        this.syncData();
                        this.fields = ['', 'Acked', 'Failed', 'Emitted', 
'Transferred'];

http://git-wip-us.apache.org/repos/asf/ambari/blob/c53de061/contrib/views/storm/src/main/resources/scripts/components/Table.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/components/Table.jsx 
b/contrib/views/storm/src/main/resources/scripts/components/Table.jsx
index 3b0ad50..d5d06ef 100644
--- a/contrib/views/storm/src/main/resources/scripts/components/Table.jsx
+++ b/contrib/views/storm/src/main/resources/scripts/components/Table.jsx
@@ -20,6 +20,9 @@ define(['react', 'react-dom'], function(React, ReactDOM) {
        'use strict';
        var Row = React.createClass({
                displayName: 'Row',
+               propTypes: {
+                       model: React.PropTypes.object.isRequired
+               },
                componentDidMount: function(){
                        if(!this.props.model._highlighted){
                                $(ReactDOM.findDOMNode(this)).addClass('');
@@ -32,6 +35,12 @@ define(['react', 'react-dom'], function(React, ReactDOM) {
        });
        return React.createClass({
                displayName: 'Table',
+               propTypes: {
+                       collection: React.PropTypes.object.isRequired,
+                       emptyText: React.PropTypes.string,
+                       columns: React.PropTypes.array.isRequired,
+                       limitRows: React.PropTypes.string
+               },
                getInitialState: function(){
                        this.highlight = false;
                        return null;
@@ -84,7 +93,7 @@ define(['react', 'react-dom'], function(React, ReactDOM) {
                getHeaderTHs: function(){
                        var ths = this.props.columns.map(function(column, i){
                                var stringTitle = typeof column.title === 
'string' ? true : false;
-                               return (<th key={i}><span data-rel="tooltip" 
title={column.tooltip ? column.tooltip : ""}>{stringTitle ? column.title : 
<column.title/>}</span></th>);
+                               return (<th key={i}><span data-rel="tooltip" 
data-placement="bottom" title={column.tooltip ? column.tooltip : 
""}>{stringTitle ? column.title : <column.title/>}</span></th>);
                        });
                        return ths;                     
                }

http://git-wip-us.apache.org/repos/asf/ambari/blob/c53de061/contrib/views/storm/src/main/resources/scripts/components/TopologyGraph.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/components/TopologyGraph.jsx 
b/contrib/views/storm/src/main/resources/scripts/components/TopologyGraph.jsx
index e74a251..1b1baf7 100644
--- 
a/contrib/views/storm/src/main/resources/scripts/components/TopologyGraph.jsx
+++ 
b/contrib/views/storm/src/main/resources/scripts/components/TopologyGraph.jsx
@@ -20,6 +20,11 @@ define(['react', 'react-dom', 'd3', 'd3.tip'], 
function(React, ReactDOM, d3) {
        'use strict';
        return React.createClass({
                displayName: 'TopologyGraph',
+        propTypes: {
+            data: React.PropTypes.object.isRequired,
+            width: React.PropTypes.string,
+            height: React.PropTypes.string
+        },
                getInitialState: function(){
                        this.width = this.props.width || '1100';
                        this.height = this.props.height || '260';

http://git-wip-us.apache.org/repos/asf/ambari/blob/c53de061/contrib/views/storm/src/main/resources/scripts/containers/NimbusSummary.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/containers/NimbusSummary.jsx 
b/contrib/views/storm/src/main/resources/scripts/containers/NimbusSummary.jsx
index ee901b9..a0ec366 100644
--- 
a/contrib/views/storm/src/main/resources/scripts/containers/NimbusSummary.jsx
+++ 
b/contrib/views/storm/src/main/resources/scripts/containers/NimbusSummary.jsx
@@ -28,6 +28,9 @@ define(['react',
 
        return React.createClass({
                displayName: 'NimbusSummary',
+               propTypes: {
+                       fromDashboard: React.PropTypes.bool
+               },
                getInitialState: function(){
                        this.initializeCollection();
                        return null;
@@ -58,11 +61,17 @@ define(['react',
                getColumns: function(){
                        return [
                                {name: 'host', title: 'Host:Port', tooltip: 
'Nimbus hostname and port number', component: React.createClass({
+                                       propTypes: {
+                                               model: 
React.PropTypes.object.isRequired
+                                       },
                                        render: function(){
                                                return ( <a 
href={this.props.model.get('nimbusLogLink')} target="_blank"> 
{this.props.model.get('host:port')} </a> );
                                        }
                                })},
                                {name: 'status', title: 'Status', tooltip: 
'Leader if this host is leader, Not a Leader for all other live hosts, note 
that these hosts may or may not be in leader lock queue, and Dead for hosts 
that are part of nimbus.seeds list but are not alive.', component: 
React.createClass({
+                                       propTypes: {
+                                               model: 
React.PropTypes.object.isRequired
+                                       },
                                        render: function(){
                                                var classname="label ";
                                                
switch(this.props.model.get("status")){
@@ -80,6 +89,9 @@ define(['react',
                                        }
                                })},
                                {name: 'nimbusUpTime', title: 'Uptime', 
tooltip: 'Time since this nimbus host has been running.', component: 
React.createClass({
+                                       propTypes: {
+                                               model: 
React.PropTypes.object.isRequired
+                                       },
                                        render: function(){
                                                return 
(<small>{this.props.model.get('nimbusUpTime')}</small>);
                                        }
@@ -102,7 +114,7 @@ define(['react',
                        pagination = ( <Pagination collection={this.collection} 
/> );
                        elemBox = (
                                        <div className="input-group col-sm-4">
-                                                               <input 
type="text"  onKeyUp={this.handleFilter} className="form-control" 
placeholder="Search By Key" />
+                                                               <input 
type="text"  onKeyUp={this.handleFilter} className="form-control" 
placeholder="Search By Host Name" />
                                                                <span 
className="input-group-btn">
                                                                <button 
className="btn btn-primary" type="button"><i className="fa 
fa-search"></i></button>
                                                                </span>

http://git-wip-us.apache.org/repos/asf/ambari/blob/c53de061/contrib/views/storm/src/main/resources/scripts/containers/SupervisorSummary.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/containers/SupervisorSummary.jsx
 
b/contrib/views/storm/src/main/resources/scripts/containers/SupervisorSummary.jsx
index e403b86..d2727f5 100644
--- 
a/contrib/views/storm/src/main/resources/scripts/containers/SupervisorSummary.jsx
+++ 
b/contrib/views/storm/src/main/resources/scripts/containers/SupervisorSummary.jsx
@@ -29,6 +29,9 @@ define(['react',
 
        return React.createClass({
                displayName: 'SupervisorSummary',
+               propTypes: {
+                       fromDashboard: React.PropTypes.bool
+               },
                getInitialState: function(){
                        this.initializeCollection();
                        return null;
@@ -58,11 +61,17 @@ define(['react',
                getColumns: function(){
                        return [
                                {name: 'host', title: 'Host', tooltip:'The 
hostname reported by the remote host. (Note that this hostname is not the 
result of a reverse lookup at the Nimbus node.)', component: React.createClass({
+                                       propTypes: {
+                                               model: 
React.PropTypes.object.isRequired
+                                       },
                                        render: function(){
                                                return ( <a 
href={this.props.model.get('logLink')} target="_blank"> 
{this.props.model.get('host')} </a> );
                                        }
                                })},
                                {name: 'slotsTotal', title: 'Slots', 
tooltip:'Slots are Workers (processes).', component: React.createClass({
+                                       propTypes: {
+                                               model: 
React.PropTypes.object.isRequired
+                                       },
                                        render: function(){
                                                return (<RadialChart 
innerRadius="19" outerRadius="21" 
                                                        color={["#bcbcbc", 
"#235693"]} 
@@ -72,6 +81,9 @@ define(['react',
                                        }
                                })},
                                {name: 'totalCpu', title: 'CPU', tooltip:'CPU 
that has been allocated.', component: React.createClass({
+                                       propTypes: {
+                                               model: 
React.PropTypes.object.isRequired
+                                       },
                                        render: function(){
                                                return (<RadialChart 
innerRadius="19" outerRadius="21" 
                                                        color={["#bcbcbc", 
"#235693"]} 
@@ -81,6 +93,9 @@ define(['react',
                                        }
                                })},
                                {name: 'totalMem', title: 'Memory', 
tooltip:'Memory that has been allocated.', component: React.createClass({
+                                       propTypes: {
+                                               model: 
React.PropTypes.object.isRequired
+                                       },
                                        render: function(){
                                                return (<RadialChart 
innerRadius="19" outerRadius="21" 
                                                        color={["#bcbcbc", 
"#235693"]} 
@@ -90,6 +105,9 @@ define(['react',
                                        }
                                })},
                                {name: 'uptime', title: 'Uptime', tooltip:'The 
length of time a Supervisor has been registered to the cluster.', component: 
React.createClass({
+                                       propTypes: {
+                                               model: 
React.PropTypes.object.isRequired
+                                       },
                                        render: function(){
                                                return 
(<small>{this.props.model.get('uptime')}</small>);
                                        }
@@ -112,7 +130,7 @@ define(['react',
                        pagination = ( <Pagination collection={this.collection} 
/> );
                        elemBox = (
                                        <div className="input-group col-sm-4">
-                                                               <input 
type="text"  onKeyUp={this.handleFilter} className="form-control" 
placeholder="Search By Key" />
+                                                               <input 
type="text"  onKeyUp={this.handleFilter} className="form-control" 
placeholder="Search By Host" />
                                                                <span 
className="input-group-btn">
                                                                <button 
className="btn btn-primary" type="button"><i className="fa 
fa-search"></i></button>
                                                                </span>

http://git-wip-us.apache.org/repos/asf/ambari/blob/c53de061/contrib/views/storm/src/main/resources/scripts/containers/TopologyConfiguration.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/containers/TopologyConfiguration.jsx
 
b/contrib/views/storm/src/main/resources/scripts/containers/TopologyConfiguration.jsx
index dd2ad64..21dc4ff 100644
--- 
a/contrib/views/storm/src/main/resources/scripts/containers/TopologyConfiguration.jsx
+++ 
b/contrib/views/storm/src/main/resources/scripts/containers/TopologyConfiguration.jsx
@@ -28,6 +28,9 @@ define(['react',
 
        return React.createClass({
                displayName: 'TopologyConfiguration',
+               propTypes: {
+                       configArr: React.PropTypes.object.isRequired
+               },
                getInitialState: function(){
                        this.collection = new VTopologyConfigList();
                        this.collection.comparator = "key";

http://git-wip-us.apache.org/repos/asf/ambari/blob/c53de061/contrib/views/storm/src/main/resources/scripts/containers/TopologyDetailGraph.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/containers/TopologyDetailGraph.jsx
 
b/contrib/views/storm/src/main/resources/scripts/containers/TopologyDetailGraph.jsx
index 64fdee1..e19cb30 100644
--- 
a/contrib/views/storm/src/main/resources/scripts/containers/TopologyDetailGraph.jsx
+++ 
b/contrib/views/storm/src/main/resources/scripts/containers/TopologyDetailGraph.jsx
@@ -23,6 +23,10 @@ define(['react',
        'use strict';
        return React.createClass({
                displayName: 'TopologyDetailGraph',
+               propTypes: {
+                       model: React.PropTypes.object.isRequired,
+                       graphData: React.PropTypes.object.isRequired
+               },
                getInitialState: function(){
                        return null;
                },

http://git-wip-us.apache.org/repos/asf/ambari/blob/c53de061/contrib/views/storm/src/main/resources/scripts/containers/TopologyListing.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/containers/TopologyListing.jsx 
b/contrib/views/storm/src/main/resources/scripts/containers/TopologyListing.jsx
index 9ce19f0..d0649b9 100644
--- 
a/contrib/views/storm/src/main/resources/scripts/containers/TopologyListing.jsx
+++ 
b/contrib/views/storm/src/main/resources/scripts/containers/TopologyListing.jsx
@@ -30,6 +30,9 @@ define(['react',
 
        return React.createClass({
                displayName: 'TopologyListing',
+               propTypes: {
+                       fromDashboard: React.PropTypes.bool
+               },
                getInitialState: function(){
                        this.initializeCollection();
                        return null;
@@ -59,11 +62,17 @@ define(['react',
                getColumns: function(){
                        var columns = [
                                {name: 'name', title: 'Topology Name', 
tooltip:'The name given to the topology by when it was submitted. Click the 
name to view the Topology\'s information.', component: React.createClass({
+                                       propTypes: {
+                                               model: 
React.PropTypes.object.isRequired
+                                       },
                                        render: function(){
                                                return ( <a 
href={"#!/topology/"+this.props.model.get('id')}> 
{this.props.model.get('name')} </a>);
                                        }
                                })},
                                {name: 'status', title: 'Status', tooltip:'The 
status can be one of ACTIVE, INACTIVE, KILLED, or REBALANCING.', component: 
React.createClass({
+                                       propTypes: {
+                                               model: 
React.PropTypes.object.isRequired
+                                       },
                                        render: function(){
                                                var classname="label ";
                                                
switch(this.props.model.get("status")){
@@ -98,6 +107,9 @@ define(['react',
                                Array.prototype.push.apply(columns, 
additionalColumns);
                        }
                        columns.push({name: 'uptime', title: 'Uptime', 
tooltip:'The time since the Topology was submitted.', component: 
React.createClass({
+                               propTypes: {
+                                       model: React.PropTypes.object.isRequired
+                               },
                                render: function(){
                                        return 
(<small>{this.props.model.get('uptime')}</small>);
                                }
@@ -151,7 +163,7 @@ define(['react',
                        var bodyElem = (
                                <div className="box-body">
                                        <div className="input-group col-sm-4">
-                                                               <input 
type="text"  onKeyUp={this.handleFilter} className="form-control" 
placeholder="Search By Key" />
+                                                               <input 
type="text"  onKeyUp={this.handleFilter} className="form-control" 
placeholder="Search By Topology Name" />
                                                                <span 
className="input-group-btn">
                                                                <button 
className="btn btn-primary" type="button"><i className="fa 
fa-search"></i></button>
                                                                </span>

http://git-wip-us.apache.org/repos/asf/ambari/blob/c53de061/contrib/views/storm/src/main/resources/scripts/modules/Table/Pagination.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/modules/Table/Pagination.jsx 
b/contrib/views/storm/src/main/resources/scripts/modules/Table/Pagination.jsx
index 41a763c..985a760 100644
--- 
a/contrib/views/storm/src/main/resources/scripts/modules/Table/Pagination.jsx
+++ 
b/contrib/views/storm/src/main/resources/scripts/modules/Table/Pagination.jsx
@@ -20,7 +20,10 @@ define(['react', 'utils/Globals'], function(React, Globals){
   'use strict';
   return React.createClass({
     displayName: 'Pagination',
-    
+    propTypes: {
+      collection: React.PropTypes.object.isRequired,
+      maximumPages: React.PropTypes.number
+    },
     getInitialState: function(){
       this.props.collection.on('reset', function(data){
         this.setState({'collection': data});

http://git-wip-us.apache.org/repos/asf/ambari/blob/c53de061/contrib/views/storm/src/main/resources/scripts/router/Router.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/router/Router.js 
b/contrib/views/storm/src/main/resources/scripts/router/Router.js
index 24fc1e0..1239b6f 100644
--- a/contrib/views/storm/src/main/resources/scripts/router/Router.js
+++ b/contrib/views/storm/src/main/resources/scripts/router/Router.js
@@ -73,12 +73,12 @@ define([
                },
                topologyDetailsAction: function(id){
                        require(['jsx!views/TopologyDetailView'], 
function(TopologyDetailView){
-                               
ReactDOM.render(React.createElement(TopologyDetailView, Object.assign({}, 
this.props, {id: id})), App.Container);
+                               
ReactDOM.render(React.createElement(TopologyDetailView, _.extend({}, 
this.props, {id: id})), App.Container);
                        }.bind(this));
                },
                componentDetailsAction: function(id, name){
                        require(['jsx!views/ComponentDetailView'], 
function(ComponentDetailView){
-                               
ReactDOM.render(React.createElement(ComponentDetailView, Object.assign({}, 
this.props, {id: id, name: name})), App.Container);
+                               
ReactDOM.render(React.createElement(ComponentDetailView, _.extend({}, 
this.props, {id: id, name: name})), App.Container);
                        }.bind(this));
                },
                nimbusAction: function(){

http://git-wip-us.apache.org/repos/asf/ambari/blob/c53de061/contrib/views/storm/src/main/resources/scripts/views/ComponentDetailView.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/views/ComponentDetailView.jsx 
b/contrib/views/storm/src/main/resources/scripts/views/ComponentDetailView.jsx
index 14f7527..5d77bdf 100644
--- 
a/contrib/views/storm/src/main/resources/scripts/views/ComponentDetailView.jsx
+++ 
b/contrib/views/storm/src/main/resources/scripts/views/ComponentDetailView.jsx
@@ -34,6 +34,10 @@ define([
 
        return React.createClass({
                displayName: 'ComponentDetailView',
+               propTypes: {
+                       id: React.PropTypes.string.isRequired,
+                       name: React.PropTypes.string.isRequired
+               },
                getInitialState: function(){
                        this.model = new VTopology({'id': this.props.id});
                        this.systemFlag = (this.props.name.startsWith('__')) ? 
true : false;
@@ -262,6 +266,9 @@ define([
                                        {name: 'id', title: 'Id', tooltip: 'The 
unique executor ID.'},
                                        {name: 'uptime', title: 'Uptime', 
tooltip: 'The length of time an Executor (thread) has been alive.'},
                                        {name: 'port', title: 'Host:Port', 
tooltip: 'The hostname reported by the remote host. (Note that this hostname is 
not the result of a reverse lookup at the Nimbus node.) Click on it to open the 
logviewer page for this Worker.', component: React.createClass({
+                                               propTypes: {
+                                                       model: 
React.PropTypes.object.isRequired
+                                               },
                                                render: function(){
                                                        return ( <a 
href={this.props.model.get('workerLogLink')} target="_blank"> 
{this.props.model.get('host')}:{this.props.model.get('port')} </a>);
                                                }
@@ -272,6 +279,9 @@ define([
                                        {name: 'acked', title: 'Acked', 
tooltip: 'The number of Tuple "trees" successfully processed. A value of 0 is 
expected if no acking is done.'},
                                        {name: 'failed', title: 'Failed', 
tooltip: 'The number of Tuple "trees" that were explicitly failed or timed out 
before acking was completed. A value of 0 is expected if no acking is done.'},
                                        {name: 'workerLogLink', title: 'Dumps', 
component: React.createClass({
+                                               propTypes: {
+                                                       model: 
React.PropTypes.object.isRequired
+                                               },
                                                render: function(){
                                                        var link = 
this.props.model.get('workerLogLink');
                                                        link = 
""+link.split('/log')[0]+"/dumps/"+self.props.id+"/"+this.props.model.get('host')+":"+this.props.model.get('port');
@@ -284,6 +294,9 @@ define([
                                        {name: 'id', title: 'Id', tooltip: 'The 
unique executor ID.'},
                                        {name: 'uptime', title: 'Uptime', 
tooltip: 'The length of time an Executor (thread) has been alive.'},
                                        {name: 'port', title: 'Host:Port', 
tooltip: 'The hostname reported by the remote host. (Note that this hostname is 
not the result of a reverse lookup at the Nimbus node.) Click on it to open the 
logviewer page for this Worker.', component: React.createClass({
+                                               propTypes: {
+                                                       model: 
React.PropTypes.object.isRequired
+                                           },
                                                render: function(){
                                                        return ( <a 
href={this.props.model.get('workerLogLink')} target="_blank"> 
{this.props.model.get('host')}:{this.props.model.get('port')} </a>);
                                                }
@@ -297,6 +310,9 @@ define([
                                        {name: 'acked', title: 'Acked', 
tooltip: 'The number of Tuples acknowledged by this Bolt.'},
                                        {name: 'failed', title: 'Failed', 
tooltip: 'The number of tuples Failed by this Bolt.'},
                                        {name: 'workerLogLink', title: 'Dumps', 
component: React.createClass({
+                                               propTypes: {
+                                                       model: 
React.PropTypes.object.isRequired
+                                               },
                                                render: function(){
                                                        var link = 
this.props.model.get('workerLogLink');
                                                        link = 
""+link.split('/log')[0]+"/dumps/"+self.props.id+"/"+this.props.model.get('host')+":"+this.props.model.get('port');
@@ -321,15 +337,21 @@ define([
                getErrorColumns: function(){
                        return [
                                {name: 'errorTime', title: 'Time', component: 
React.createClass({
+                                       propTypes: {
+                                               model: 
React.PropTypes.object.isRequired
+                                       },
                                        render: function(){
                                                
if(this.props.model.get('errorTime') != 0) {
-                                                       var d = new 
Date(this.props.model.get('errorTime')),
+                                                       var d = new 
Date(this.props.model.get('errorTime') * 1000),
                                                        date = 
d.toLocaleDateString() + ' ' + d.toLocaleTimeString();
                                                        return 
(<span>{date}</span>);
                                                } else return (<span></span>);
                                        }
                                })},
                                {name: 'errorPort', title: 'Host:Port', 
component: React.createClass({
+                                       propTypes: {
+                                               model: 
React.PropTypes.object.isRequired
+                                       },
                                        render: function(){
                                                return ( <a 
href={this.props.model.get('errorWorkerLogLink')} target="_blank"> 
{this.props.model.get('errorHost')}:{this.props.model.get('errorPort')} </a>);
                                        }
@@ -441,7 +463,7 @@ define([
                if(toEnableFlag){
                        bootbox.prompt({
                                title: 'Do you really want to debug this 
component ? If yes, please, specify sampling percentage.',
-                               value: "10",
+                               value: this.state.componentObj.samplingPct ? 
this.state.componentObj.samplingPct : "10",
                                buttons: {
                                  confirm: {
                                    label: 'Yes',
@@ -453,7 +475,12 @@ define([
                                  }
                                },
                                callback: function(result) {
-                                 if(result != null){
+                                         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.debugComponent({
                                                id: 
this.state.componentObj.topologyId,
                                                name: 
this.state.componentObj.id,
@@ -471,8 +498,6 @@ define([
                                                                
Utils.notifyError("Error occured in enabling debugging.");
                                                        }
                                        });
-                                 } else {
-                                       
$(".boot-switch.debug").bootstrapSwitch('toggleState', true)
                                  }
                                }.bind(this)
                            });

http://git-wip-us.apache.org/repos/asf/ambari/blob/c53de061/contrib/views/storm/src/main/resources/scripts/views/ProfilingView.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/views/ProfilingView.jsx 
b/contrib/views/storm/src/main/resources/scripts/views/ProfilingView.jsx
index eb9d0d1..f5ffefe 100644
--- a/contrib/views/storm/src/main/resources/scripts/views/ProfilingView.jsx
+++ b/contrib/views/storm/src/main/resources/scripts/views/ProfilingView.jsx
@@ -28,6 +28,11 @@ define(['react',
        'use strict';
        return React.createClass({
                displayName: 'Profiling',
+               propTypes: {
+                       modalId: React.PropTypes.string.isRequired,
+                       topologyId: React.PropTypes.string.isRequired,
+                       executorStats: React.PropTypes.array.isRequired
+               },
                getInitialState: function(){
                        this.model = new VTopology();
                        this.selectedWorker = [];
@@ -130,6 +135,9 @@ define(['react',
                                                }
                                        }), 
                                        component: React.createClass({
+                                               propTypes: {
+                                                       model: 
React.PropTypes.object.isRequired
+                                               },
                                                handleChange: function(e){
                                                        var hostPort = 
this.props.model.get('hostPort')
                                                        
if($(e.currentTarget).prop('checked')){
@@ -150,6 +158,9 @@ define(['react',
                                },
                                {name: 'hostPort', title:'Host:Port'},
                                {name: 'executorId', title:'Executor Id', 
component: React.createClass({
+                                       propTypes: {
+                                               model: 
React.PropTypes.object.isRequired
+                                       },
                                        render: function(){
                                                var executors = 
this.props.model.get('executorId').join(', ');
                                                return (

http://git-wip-us.apache.org/repos/asf/ambari/blob/c53de061/contrib/views/storm/src/main/resources/scripts/views/RebalanceView.jsx
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/views/RebalanceView.jsx 
b/contrib/views/storm/src/main/resources/scripts/views/RebalanceView.jsx
index 96f01a6..33f5963 100644
--- a/contrib/views/storm/src/main/resources/scripts/views/RebalanceView.jsx
+++ b/contrib/views/storm/src/main/resources/scripts/views/RebalanceView.jsx
@@ -26,6 +26,13 @@ define(['react',
        'use strict';
        return React.createClass({
                displayName: 'Rebalance',
+               propTypes: {
+                       modalId: React.PropTypes.string.isRequired,
+                       topologyId: React.PropTypes.string.isRequired,
+                       topologyExecutors: React.PropTypes.string.isRequired,
+                       spouts: React.PropTypes.array.isRequired,
+                       bolts: React.PropTypes.array.isRequired
+               },
                getInitialState: function(){
                        var spoutArr = [];
                        var boltArr = [];
@@ -175,7 +182,7 @@ define(['react',
                render: function() {
                        var totalExecutor = this.state.workers + 
this.state.freeSlots;
                        return (
-                               <div className="modal fade" 
id={this.props.modalId} role="dialog">
+                               <div className="modal fade" 
id={this.props.modalId} role="dialog" data-backdrop="static">
                                    <div className="modal-dialog">
                                        <div className="modal-content">
                                                <div className="modal-header">

http://git-wip-us.apache.org/repos/asf/ambari/blob/c53de061/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
index bf66903..7486948 100644
--- 
a/contrib/views/storm/src/main/resources/scripts/views/TopologyDetailView.jsx
+++ 
b/contrib/views/storm/src/main/resources/scripts/views/TopologyDetailView.jsx
@@ -38,6 +38,9 @@ define([
 
        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();
@@ -230,6 +233,9 @@ define([
                        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>);
@@ -243,15 +249,21 @@ define([
                                {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') != 0) {
-                                                       var d = new 
Date(this.props.model.get('errorTime')),
+                                                       var d = new 
Date(this.props.model.get('errorTime') * 1000),
                                                        date = 
d.toLocaleDateString() + ' ' + d.toLocaleTimeString();
                                                        return 
(<span>{date}</span>);
                                                } else return (<span></span>);
@@ -279,6 +291,9 @@ define([
                        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>);
@@ -295,15 +310,21 @@ define([
                                {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') != 0) {
-                                                       var d = new 
Date(this.props.model.get('errorTime')),
+                                                       var d = new 
Date(this.props.model.get('errorTime') * 1000),
                                                        date = 
d.toLocaleDateString() + ' ' + d.toLocaleTimeString();
                                                        return 
(<span>{date}</span>);
                                                } else return (<span></span>);
@@ -441,6 +462,9 @@ define([
                        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>);
@@ -453,6 +477,9 @@ define([
                                        }})
                            },
                                {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')}>
@@ -469,6 +496,9 @@ define([
                                        }
                                })},
                                {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>);
                                        },
@@ -479,6 +509,9 @@ define([
                                        }})
                            },
                                {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')),
@@ -490,6 +523,9 @@ define([
                                        })
                                },
                                {name: 'action', title: 'Action', component: 
React.createClass({
+                                       propTypes: {
+                                               model: 
React.PropTypes.object.isRequired
+                                       },
                                        render: function(){
                                                
if(this.props.model.get('isAdd'))
                                                        return(
@@ -645,10 +681,10 @@ define([
                                        </div>
                                        <div className="row">
                                                <div className="col-sm-12">
-                                                       <TopologyConfiguration 
configArr={this.state.model.get('configuration')}/>
+                                                       <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')} bolts={this.state.model.get('bolts')}/> 
: null}
+                                       {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>
                        );
            },
@@ -742,7 +778,7 @@ define([
                if(toEnableFlag){
                        bootbox.prompt({
                                title: 'Do you really want to debug this 
topology ? If yes, please, specify sampling percentage.',
-                               value: "10",
+                               value: this.model.get("samplingPct") ? 
this.model.get("samplingPct") : '10',
                                buttons: {
                                  confirm: {
                                    label: 'Yes',
@@ -754,7 +790,12 @@ define([
                                  }
                                },
                                callback: function(result) {
-                                 if(result != null){
+                                         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',
@@ -771,8 +812,6 @@ define([
                                                                
Utils.notifyError("Error occured in enabling debugging.");
                                                        }
                                        });
-                                 } else {
-                                       
$(".boot-switch.debug").bootstrapSwitch('toggleState', true)
                                  }
                                }.bind(this)
                            });

Reply via email to