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

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/utils/Overrides.js
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/scripts/utils/Overrides.js 
b/contrib/views/storm/src/main/resources/scripts/utils/Overrides.js
new file mode 100644
index 0000000..7b8a844
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/utils/Overrides.js
@@ -0,0 +1,218 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+define(['require',
+        'utils/Globals',
+        'utils/Utils',
+        'backgrid',
+        'bootstrap.filestyle',
+        'backbone.forms'], function (require, Globals, Utils) {
+  'use strict';
+
+  /**********************************************************************
+   *                      Backgrid related                              *
+   **********************************************************************/
+
+  /*
+   * HtmlCell renders any html code
+   * @class Backgrid.HtmlCell
+   * @extends Backgrid.Cell
+  */
+  var HtmlCell = Backgrid.HtmlCell = Backgrid.Cell.extend({
+
+     /** @property */
+     className: "html-cell",
+
+     render: function () {
+         this.$el.empty();
+         var rawValue = this.model.get(this.column.get("name"));
+         var formattedValue = this.formatter.fromRaw(rawValue, this.model);
+         this.$el.append(formattedValue);
+         this.delegateEvents();
+         return this;
+     }
+  });
+
+  var UriCell = Backgrid.UriCell = Backgrid.Cell.extend({
+    className: "uri-cell",
+    title: null,
+    target: "_blank",
+
+    initialize: function (options) {
+      UriCell.__super__.initialize.apply(this, arguments);
+      this.title = options.title || this.title;
+      this.target = options.target || this.target;
+    },
+
+    render: function () {
+      this.$el.empty();
+      var rawValue = this.model.get(this.column.get("name"));
+      var href = _.isFunction(this.column.get("href")) ? 
this.column.get('href')(this.model) : this.column.get('href');
+      var klass = this.column.get("klass");
+      var formattedValue = this.formatter.fromRaw(rawValue, this.model);
+      this.$el.append($("<a>", {
+        tabIndex: -1,
+        href: href,
+        title: this.title || formattedValue,
+        'class' : klass
+      }).text(formattedValue));
+
+      if(this.column.has("iconKlass")){
+        var iconKlass = this.column.get("iconKlass");
+        var iconTitle = this.column.get("iconTitle");
+        this.$el.find('a').append('<i class="'+iconKlass+'" 
title="'+iconTitle+'"></i>');
+      }
+      this.delegateEvents();
+      return this;
+    }
+
+  });
+
+
+  /**
+     Renders a checkbox for Provision Table Cell.
+     @class Backgrid.CheckboxCell
+     @extends Backgrid.Cell
+  */
+  Backgrid.CheckboxCell = Backgrid.Cell.extend({
+
+    /** @property */
+    className: "select-cell",
+
+    /** @property */
+    tagName: "td",
+
+    /** @property */
+    events: {
+      "change input[type=checkbox]": "onChange",
+      "click input[type=checkbox]": "enterEditMode"
+    },
+
+    /**
+       Initializer. If the underlying model triggers a `select` event, this 
cell
+       will change its checked value according to the event's `selected` value.
+
+       @param {Object} options
+       @param {Backgrid.Column} options.column
+       @param {Backbone.Model} options.model
+    */
+    initialize: function (options) {
+
+      this.column = options.column;
+      if (!(this.column instanceof Backgrid.Column)) {
+        this.column = new Backgrid.Column(this.column);
+      }
+
+      if(!this.column.has("checkedVal")){
+        this.column.set("checkedVal", "true"); // it is not a boolean value 
for EPM
+        this.column.set("uncheckedVal", "false");
+      }
+
+      var column = this.column, model = this.model, $el = this.$el;
+      this.listenTo(column, "change:renderable", function (column, renderable) 
{
+        $el.toggleClass("renderable", renderable);
+      });
+
+      if (Backgrid.callByNeed(column.renderable(), column, model)){
+        $el.addClass("renderable");
+      }
+
+      this.listenTo(model, "change:" + column.get("name"), function () {
+        if (!$el.hasClass("editor")){
+          this.render();
+        }
+      });
+
+      this.listenTo(model, "backgrid:select", function (model, selected) {
+        this.$el.find("input[type=checkbox]").prop("checked", 
selected).change();
+      });
+
+
+    },
+
+    /**
+       Focuses the checkbox.
+    */
+    enterEditMode: function () {
+      this.$el.find("input[type=checkbox]").focus();
+    },
+
+    /**
+       Unfocuses the checkbox.
+    */
+    exitEditMode: function () {
+      this.$el.find("input[type=checkbox]").blur();
+    },
+
+    /**
+       When the checkbox's value changes, this method will trigger a Backbone
+       `backgrid:selected` event with a reference of the model and the
+       checkbox's `checked` value.
+    */
+    onChange: function () {
+      var checked = this.$el.find("input[type=checkbox]").prop("checked");
+      this.model.set(this.column.get("name"), checked);
+      this.model.trigger("backgrid:selected", this.model, checked);
+    },
+
+    /**
+       Renders a checkbox in a table cell.
+    */
+    render: function () {
+      var model = this.model, column = this.column;
+      var val = (model.get(column.get("name")) === column.get("checkedVal") || 
model.get(column.get("name")) === true) ? true : false;
+      var editable = Backgrid.callByNeed(column.editable(), column, model);
+
+      this.$el.empty();
+
+      this.$el.append($("<input>", {
+        tabIndex: -1,
+        type: "checkbox",
+        checked: val,
+        disabled: !editable
+      }));
+      this.delegateEvents();
+      return this;
+    }
+
+  });
+
+  Backbone.Form.editors.Fileupload = Backbone.Form.editors.Base.extend({
+    initialize: function(options){
+      Backbone.Form.editors.Base.prototype.initialize.call(this, options);
+      this.template = _.template('<input type="file" name="fileInput" 
class="filestyle">');
+    },
+    render: function(){
+      this.$el.html( this.template );
+      this.$(":file").filestyle();
+      return this;
+    },
+    getValue: function(){
+      return $('input[name="fileInput"]')[0].files[0];
+    }
+  });
+
+  Backbone.ajax = function() {
+    var urlPart = arguments[0].url.split('url=')[0];
+    var stormUrlPart = arguments[0].url.split('url=')[1];
+    urlPart += 'url=' + encodeURIComponent(stormUrlPart);
+    arguments[0].url = urlPart;
+    return Backbone.$.ajax.apply(Backbone.$, arguments);
+  };
+
+});

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

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

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

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/views/Spout/SpoutCollectionView.js
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/views/Spout/SpoutCollectionView.js
 
b/contrib/views/storm/src/main/resources/scripts/views/Spout/SpoutCollectionView.js
new file mode 100644
index 0000000..eadab4d
--- /dev/null
+++ 
b/contrib/views/storm/src/main/resources/scripts/views/Spout/SpoutCollectionView.js
@@ -0,0 +1,53 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+define([
+  'require',
+  'views/Spout/SpoutItemView'
+  ], function(require, vSpoutItemView) {
+  'use strict';
+
+  var spoutCollectionView = Marionette.CollectionView.extend({
+    childView: vSpoutItemView,
+
+    childViewOptions: function() {
+      return {
+        collection: this.collection,
+        topologyId: this.topologyId,
+        systemBoltFlag: this.systemBoltFlag,
+        windowTimeFrame: this.windowTimeFrame,
+        emptyMsg: "No spouts"
+      };
+    },
+
+    initialize: function(options) {
+      this.collection = options.collection;
+      if(options.collection.length == 0){
+        this.collection.add(new Backbone.Model());
+      }
+      this.topologyId = options.topologyId;
+      this.systemBoltFlag = options.systemBoltFlag;
+      this.windowTimeFrame = options.windowTimeFrame;
+    },
+
+    onRender: function(){}
+
+  });
+
+  return spoutCollectionView;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/views/Spout/SpoutItemView.js
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/views/Spout/SpoutItemView.js 
b/contrib/views/storm/src/main/resources/scripts/views/Spout/SpoutItemView.js
new file mode 100644
index 0000000..f41e8d1
--- /dev/null
+++ 
b/contrib/views/storm/src/main/resources/scripts/views/Spout/SpoutItemView.js
@@ -0,0 +1,355 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+define([
+  'require',
+  'utils/LangSupport',
+  'models/VOutputStat',
+  'models/VExecutor',
+  'models/VError',
+  'utils/TableLayout',
+  'hbs!tmpl/spout/spoutItemView'
+], function(require, localization, vOutputStat, vExecutors, vError, 
TableLayout, tmpl) {
+  'use strict';
+
+  var spoutItemView = Marionette.ItemView.extend({
+    template: tmpl,
+    tagName: 'div',
+    templateHelpers: function() {
+      return {
+        id: this.model.id,
+        name: this.model.get('name')
+      };
+    },
+    initialize: function(options) {
+      this.spoutsCollection = new Backbone.Collection();
+      options.model.opstCollection = new Backbone.Collection();
+      options.model.extrCollection = new Backbone.Collection();
+      options.model.errorCollection = new Backbone.Collection();
+      if(!_.isUndefined(options.topologyId) && 
options.model.has('errorWorkerLogLink')){
+        this.getDetails(options.model, options.topologyId, 
options.systemBoltFlag, options.windowTimeFrame);
+      }
+    },
+
+    events: {},
+
+    onRender: function() {
+      this.showSpoutsSummaryTable();
+      this.showOpstSummaryTable();
+    },
+
+    getDetails: function(model, topologyId, systemBoltFlag, windowTimeFrame) {
+      var that = this;
+      this.spoutsCollection.trigger('request', this.spoutsCollection);
+      model.getDetails({
+        topologyId: topologyId,
+        spoutId: model.get('spoutId'),
+        systemBoltFlag: systemBoltFlag,
+        windowTimeFrame: windowTimeFrame,
+        success: function(spoutsModel, response, options) {
+          that.spoutsCollection.trigger('sync', that.spoutsCollection);
+          if (spoutsModel) {
+            spoutsModel = new Backbone.Model(spoutsModel);
+            if (spoutsModel.has('outputStats') && 
spoutsModel.get('outputStats').length) {
+
+              var arr = [];
+              _.each(spoutsModel.get('outputStats'), function(object) {
+                arr.push(new vOutputStat(object))
+              });
+              model.opstCollection.reset(arr);
+            }
+
+            if (spoutsModel.has('executorStats') && 
spoutsModel.get('executorStats').length) {
+              var arr = [];
+              _.each(spoutsModel.get('executorStats'), function(object) {
+                arr.push(new vExecutors(object))
+              });
+              model.extrCollection.reset(arr);
+            }
+
+            if (spoutsModel.has('componentErrors') && 
spoutsModel.get('componentErrors').length) {
+
+              var arr = [];
+              _.each(spoutsModel.get('componentErrors'), function(object) {
+                arr.push(new vError(object))
+              });
+              model.errorCollection.reset(arr);
+            }
+
+            that.spoutsCollection.reset(model);
+          }
+        },
+        error: function() {
+          that.spoutsCollection.trigger('error', that.spoutsCollection);
+          return null;
+        }
+      });
+    },
+
+    showSpoutsSummaryTable: function() {
+
+      this.$('[data-id="SpoutsSummaryTable"]').html(new TableLayout({
+        columns: this.getSpoutColumns(),
+        collection: this.spoutsCollection,
+        includeFilter: false,
+        includePagination: false,
+        includeFooterRecords: false,
+        gridOpts: {
+          emptyText: localization.tt('msg.noSpoutFound'),
+          className: 'table table-borderless table-striped table-header'
+        }
+      }).render().$el);
+    },
+
+    showOpstSummaryTable: function() {
+      var that = this;
+
+      that.$('[data-id="OpstSummaryTable"]').html(new TableLayout({
+        columns: that.getOpstColumns(),
+        collection: that.model.opstCollection,
+        includeFilter: false,
+        includePagination: false,
+        includeFooterRecords: false,
+        gridOpts: {
+          emptyText: localization.tt('msg.noOutputStatsFound'),
+          className: 'table table-borderless table-striped'
+        }
+      }).render().$el);
+
+      that.$('[data-id="ExtrSummaryTable"]').html(new TableLayout({
+        columns: that.getExtrColumns(),
+        collection: that.model.extrCollection,
+        includeFilter: false,
+        includePagination: false,
+        includeFooterRecords: false,
+        gridOpts: {
+          emptyText: localization.tt('msg.noExecutorsFound'),
+          className: 'table table-borderless table-striped'
+        }
+      }).render().$el);
+
+      that.$('[data-id="ErrorSummaryTable"]').html(new TableLayout({
+        columns: that.getErrorColumns(),
+        collection: that.model.errorCollection,
+        includeFilter: false,
+        includePagination: false,
+        includeFooterRecords: false,
+        gridOpts: {
+          emptyText: localization.tt('msg.noErrorFound'),
+          className: 'table table-borderless table-striped'
+        }
+      }).render().$el);
+    },
+
+
+    getSpoutColumns: function() {
+      var cols = [{
+        name: "spoutId",
+        cell: "string",
+        label: localization.tt('lbl.id'),
+        sortable: true,
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.spoutId')
+      }, {
+        name: "executors",
+        cell: "string",
+        label: localization.tt('lbl.executors'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.spoutExecutors')
+      }, {
+        name: "tasks",
+        cell: "string",
+        label: localization.tt('lbl.tasks'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.spoutTasks')
+      }, {
+        name: "emitted",
+        cell: "string",
+        label: localization.tt('lbl.emitted'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.emitted')
+      }, {
+        name: "transferred",
+        cell: "string",
+        label: localization.tt('lbl.transferred'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.transferred')
+      }, {
+        name: "completeLatency",
+        cell: "string",
+        label: localization.tt('lbl.completeLatency'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.completeLatency')
+      }, {
+        name: "acked",
+        cell: "string",
+        label: localization.tt('lbl.acked'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.acked')
+      }, {
+        name: "failed",
+        cell: "string",
+        label: localization.tt('lbl.failed'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.failed')
+      }];
+      return cols;
+    },
+
+    getOpstColumns: function() {
+      var cols = [{
+        name: "stream",
+        cell: "string",
+        label: localization.tt('lbl.stream'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.stream'),
+        sortable: true
+      }, {
+        name: "emitted",
+        cell: "string",
+        label: localization.tt('lbl.emitted'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.emitted')
+      }, {
+        name: "transferred",
+        cell: "string",
+        label: localization.tt('lbl.transferred'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.transferred')
+      }, {
+        name: "completeLatency",
+        cell: "string",
+        label: localization.tt('lbl.completeLatencyMS'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.completeLatency')
+      }, {
+        name: "acked",
+        cell: "string",
+        label: localization.tt('lbl.acked'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.acked')
+      }, {
+        name: "failed",
+        cell: "string",
+        label: localization.tt('lbl.failed'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.failed')
+      }];
+      return cols;
+    },
+
+    getExtrColumns: function() {
+      var cols = [{
+        name: "id",
+        cell: "string",
+        label: localization.tt('lbl.id'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.uniqueExecutorId'),
+        sortable: true
+      }, {
+        name: "uptime",
+        cell: "string",
+        label: localization.tt('lbl.uptime'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.extensionUptime')
+      }, {
+        name: "host",
+        cell: "string",
+        label: localization.tt('lbl.host'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.extensionHost')
+      }, {
+        name: "port",
+        cell: "string",
+        label: localization.tt('lbl.port'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.extensionPort')
+      }, {
+        name: "emitted",
+        cell: "string",
+        label: localization.tt('lbl.emitted'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.emitted')
+      }, {
+        name: "transferred",
+        cell: "string",
+        label: localization.tt('lbl.transferred'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.transferred')
+      }, {
+        name: "completeLatency",
+        cell: "string",
+        label: localization.tt('lbl.completeLatencyMS'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.completeLatency')
+      }, {
+        name: "acked",
+        cell: "string",
+        label: localization.tt('lbl.acked'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.acked')
+      }, {
+        name: "failed",
+        cell: "string",
+        label: localization.tt('lbl.failed'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.failed')
+      }, {
+        name: "logs",
+        cell: "Html",
+        label: '',
+        sortable: false,
+        formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+          fromRaw: function(rawValue, model) {
+            if (model) {
+              return "<a href="+model.get('workerLogLink')+" target='_blank' 
class='btn btn-success btn-xs 
center-block'>"+localization.tt('lbl.viewLogs')+"</a>";
+            }
+          }
+        })
+      }];
+      return cols;
+    },
+
+    getErrorColumns: function() {
+      var cols = [
+        {
+          name: "time",
+          cell: "string",
+          label: localization.tt('lbl.time'),
+          sortable: true
+        }, {
+          name: "errorHost",
+          cell: "string",
+          label: localization.tt('lbl.errorHost'),
+        }, {
+          name: "errorPort",
+          cell: "string",
+          label: localization.tt('lbl.errorPort'),
+        }, {
+          name: "error",
+          cell: "string",
+          label: localization.tt('lbl.error'),
+        }
+      ];
+      return cols;
+    },
+
+    onClose: function() {}
+  });
+  return spoutItemView;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/views/Topology/RebalanceForm.js
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/views/Topology/RebalanceForm.js
 
b/contrib/views/storm/src/main/resources/scripts/views/Topology/RebalanceForm.js
new file mode 100644
index 0000000..3b35c71
--- /dev/null
+++ 
b/contrib/views/storm/src/main/resources/scripts/views/Topology/RebalanceForm.js
@@ -0,0 +1,84 @@
+/**
+* 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(['utils/LangSupport',
+  'utils/Globals',
+  'backbone.forms'
+  ], function (localization, Globals) {
+  'use strict';
+
+  var RebalanceForm = Backbone.Form.extend({
+
+    initialize: function (options) {
+      this.spoutCollection = options.spoutCollection;
+      this.boltCollection = options.boltCollection;
+      Backbone.Form.prototype.initialize.call(this, options);
+    },
+
+    schema: function () {
+      var that = this;
+      var obj = {
+        workers: {
+          type: 'Number',
+          title: localization.tt('lbl.workers')
+        }
+      };
+
+      if(that.spoutCollection.length){
+        _.each(that.spoutCollection.models, function(model){
+          if(model.has('spoutId')) {
+            obj[model.get('spoutId')] = {
+              type: 'Number',
+              title: model.get('spoutId')
+            };
+          }
+        });
+      }
+      if(that.boltCollection.length){
+        _.each(that.boltCollection.models, function(model){
+          if(model.has('boltId')) {
+            obj[model.get('boltId')] = {
+              type: 'Number',
+              title: model.get('boltId')
+            };
+          }
+        });
+      }
+      obj.waitTime = {
+        type: 'Number',
+        title: localization.tt('lbl.waitTime')+'*',
+        validators: ['required']
+      }
+      return obj
+    },
+
+    render: function(options){
+      Backbone.Form.prototype.render.call(this,options);
+    },
+
+    getData: function () {
+      return this.getValue();
+    },
+
+    close: function () {
+      console.log('Closing form view');
+    }
+  });
+
+  return RebalanceForm;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/views/Topology/TopologyDetail.js
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/views/Topology/TopologyDetail.js
 
b/contrib/views/storm/src/main/resources/scripts/views/Topology/TopologyDetail.js
new file mode 100644
index 0000000..ec9c4fc
--- /dev/null
+++ 
b/contrib/views/storm/src/main/resources/scripts/views/Topology/TopologyDetail.js
@@ -0,0 +1,734 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+define(['require',
+  'utils/Globals',
+  'modules/Vent',
+  'utils/LangSupport',
+  'models/VTopology',
+  'models/VSpout',
+  'models/VBolt',
+  'models/VTopologyConfig',
+  'views/Spout/SpoutCollectionView',
+  'views/Topology/TopologyGraphView',
+  'utils/TableLayout',
+  'utils/Utils',
+  'bootbox',
+  'hbs!tmpl/topology/topologyDetail'
+], function(require, Globals, vent, localization, vTopology, vSpout, vBolt, 
vTopologyConfig, vSpoutCollectionView, vTopologyGraphView, TableLayout, Utils, 
bootbox, tmpl) {
+
+  'use strict';
+
+  var masterView = Marionette.LayoutView.extend({
+
+    template: tmpl,
+
+    regions: {
+      'rTopologyDetailsTbl': '#topologyDetail',
+      'rTopologyGraph': '#graph',
+      'rTopologySummary': '#topo-summary',
+      'rSpoutsTable': '#SpoutsTable',
+      'rBoltsSummaryTable': '#BoltsSummaryTable',
+      'rTopologyConfigTable': '#TopologyConfigTable'
+    },
+
+    ui: {
+      topologySummary: '#topo-summary',
+      summaryLoader: '#summaryLoader',
+      BoltsSummaryDetails: '[data-id="BoltsSummary"]'
+    },
+
+    events: {
+      'change #tFrame': 'evChangeTimeFrame',
+      'click #btnActivate': 'evActivateTopology',
+      'click #btnDeactivate': 'evDeactivateTopology',
+      'click #btnRebalance': 'evRebalanceTopology',
+      'click #btnKill': 'evKillTopology',
+      'click #openAll': 'openAllTables',
+      'change #sysBolt': 'evSysBoltToggle'
+    },
+
+    initialize: function(options) {
+      this.model = new vTopology();
+      this.systemBoltFlag = false;
+      this.topologyDetailsColl = new Backbone.Collection();
+      this.summaryArr = [];
+      this.windowTimeFrame = ":all-time";
+      this.fetchData(options.id, this.systemBoltFlag, this.windowTimeFrame);
+      this.generateTemplate();
+
+      this.spoutsCollection = new Backbone.Collection();
+      this.boltsCollection = new Backbone.Collection();
+      this.topoConfigCollection = new Backbone.Collection();
+    },
+
+    fetchData: function(id, flag, timeFrame){
+      var that = this;
+      $('.loading').show();
+      this.model.getDetails({
+        id: id,
+        sysBoltFlag: flag,
+        windowTimeFrame: timeFrame,
+        success: function(model, response, options) {
+          that.model = new vTopology(model);
+          that.getDetails(that.model);
+          that.render();
+          that.disableBtnAction(model.status);
+          that.$('#sysBolt').prop("checked",that.systemBoltFlag)
+          that.startPollingAction(that.model.get('id'), 
that.model.get('window'));
+          $('.loading').hide();
+        },
+        error: function(model, response, options) {
+          that.startPollingAction(that.model.get('id'), 
that.model.get('window'));
+          $('.loading').hide();
+          Utils.notifyError(model.statusText);
+        }
+      });
+    },
+
+    generateTemplate: function() {
+      this.summaryTemplate = _.template('<table class="table 
table-borderless"><tbody>' +
+        '<tr>' +
+        '<th>'+localization.tt('lbl.emitted')+'</th>' +
+        '<td><%if (emitted) { %> <%=emitted%> <%} else { %> 0 <% } %></td>' +
+        '</tr>' +
+        '<tr>' +
+        '<th>'+localization.tt('lbl.transferred')+'</th>' +
+        '<td><%if (transferred) { %> <%=transferred%> <%} else { %> 0 <% } 
%></td>' +
+        '</tr>' +
+        '<tr>' +
+        '<th>'+localization.tt('lbl.completeLatency')+'</th>' +
+        '<td><%if (completeLatency) { %> <%=completeLatency%> <%} else { %> 0 
<% } %></td>' +
+        '</tr>' +
+        '<tr>' +
+        '<th>'+localization.tt('lbl.acked')+'</th>' +
+        '<td><%if (acked) { %> <%=acked%> <%} else { %> 0 <% } %></td>' +
+        '</tr>' +
+        '<tr>' +
+        '<th>'+localization.tt('lbl.failed')+'</th>' +
+        '<td><%if (failed) { %> <%=failed%> <%} else { %> 0 <% } %></td>' +
+        '</tr>' +
+        '</tbody></table>');
+
+    },
+
+    onRender: function() {
+      if(! this.$el.hasClass('topologyDetailView')){
+        this.$el.addClass('topologyDetailView');
+      }
+      this.$('.topology-title').html(this.model.has('name') ? 
this.model.get('name') : '');
+      this.showDetailsTable(this.topologyDetailsColl);
+      if(this.summaryArr.length){
+        this.setTimeFrameOptions();
+      }
+      this.windowTimeFrame = this.model.get('window');
+      this.$('#tFrame').val(this.windowTimeFrame);
+      this.showSummaryTable(this.windowTimeFrame);
+
+      this.showBoltsSummaryTable();
+      this.showTopologyConfigTable();
+
+      this.showSpoutsSummaryTable();
+
+      if(this.model.has('id')){
+        this.rTopologyGraph.show(new vTopologyGraphView({
+          id: this.model.get('id')
+        }));
+      }
+
+      this.$('.collapse').on('shown.bs.collapse', function() {
+        
$(this).parent().find(".fa-caret-right").removeClass("fa-caret-right").addClass("fa-caret-down");
+      }).on('hidden.bs.collapse', function() {
+        
$(this).parent().find(".fa-caret-down").removeClass("fa-caret-down").addClass("fa-caret-right");
+      });
+
+      this.$('[data-id="r_tableList"]').parent().removeClass('col-md-12');
+      if(this.$el.parent().hasClass('active')){
+        this.showBreadCrumbs();
+      }
+    },
+
+    disableBtnAction: function(status){
+      _.each(this.$el.find('.btn.btn-success.btn-sm'),function(elem){
+        $(elem).removeAttr('disabled')
+      });
+      switch(status){
+        case "ACTIVE":
+          this.$el.find('#btnActivate').attr('disabled','disabled');
+          break;
+        case "INACTIVE":
+          this.$el.find('#btnDeactivate').attr('disabled','disabled');
+          break;
+        case "REBALANCING":
+          this.$el.find('#btnRebalance').attr('disabled','disabled');
+          break;
+        case "KILLED":
+          this.$el.find('#btnKill').attr('disabled','disabled');
+          break;
+      }
+    },
+
+    setTimeFrameOptions: function() {
+        var html = '';
+      _.each(this.summaryArr, function(obj){
+        switch(obj.window){
+          case "600":
+            obj.windowPretty = localization.tt('lbl.last10Min');
+            break;
+          case "10800":
+            obj.windowPretty = localization.tt('lbl.last3Hr');
+            break;
+          case "86400":
+            obj.windowPretty = localization.tt('lbl.last1Day');
+            break;
+        }
+        html += "<option value="+obj.window+">"+obj.windowPretty+"</option>";
+      });
+      this.$('#tFrame').append(html);
+    },
+
+    evChangeTimeFrame: function(e) {
+      this.windowTimeFrame = $(e.currentTarget).val();
+      this.fetchData(this.model.get('id'), this.systemBoltFlag, 
this.windowTimeFrame);
+    },
+
+    getDetails: function(model) {
+      var detModel = new Backbone.Model(_.pick(model.attributes, 'name', 'id', 
'owner', 'status', 'uptime', 'workersTotal', 'executorsTotal', 'tasksTotal', 
'schedulerInfo'));
+
+      this.topologyDetailsColl.reset(detModel);
+
+      this.summaryArr = model.get('topologyStats');
+
+      var that = this;
+
+      var spoutsModel = new vSpout();
+
+      var s_arr = [];
+      _.each(model.get('spouts'), function(spout){
+        var spoutsModel = new vSpout(spout);
+        s_arr.push(spoutsModel)
+      });
+      that.spoutsCollection.reset(s_arr);
+
+      var b_arr =[];
+      _.each(this.model.get("bolts"), function(object){
+        b_arr.push(new vBolt(object));
+      });
+      that.boltsCollection.reset(b_arr);
+
+      var topoConfigModel = this.model.get("configuration");
+      if (model) {
+        var arr = [];
+        for(var key in topoConfigModel){
+          var obj = {};
+          obj.key = key;
+          obj.value = topoConfigModel[key];
+          arr.push(new vTopologyConfig(obj));
+        }
+        that.topoConfigCollection.reset(arr);
+      }
+    },
+
+    showSpoutsSummaryTable: function() {
+      this.rSpoutsTable.show(new vSpoutCollectionView({
+        collection: this.spoutsCollection,
+        systemBoltFlag: this.systemBoltFlag,
+        topologyId: this.model.get('id'),
+        windowTimeFrame: this.windowTimeFrame
+      }));
+    },
+
+    showBoltsSummaryTable: function() {
+
+      this.rBoltsSummaryTable.show(new TableLayout({
+        columns: this.getBoltColumns(),
+        collection: this.boltsCollection,
+        includeFilter: false,
+        includePagination: false,
+        includeFooterRecords: false,
+        gridOpts: {
+          emptyText: localization.tt('msg.noBoltFound'),
+          className: 'table table-borderless table-striped cluster-table'
+        }
+      }));
+    },
+
+    showTopologyConfigTable: function() {
+      this.rTopologyConfigTable.show(new TableLayout({
+        columns: this.getTopoConfigColumns(),
+        collection: this.topoConfigCollection,
+        includeFilter: false,
+        includePagination: false,
+        includeFooterRecords: false,
+        gridOpts: {
+          emptyText: localization.tt('msg.noTopologyConfigFound'),
+          className: 'table table-borderless table-striped cluster-table'
+        }
+      }));
+    },
+
+
+    showDetailsTable: function(collection) {
+      this.rTopologyDetailsTbl.show(new TableLayout({
+        columns: this.getColumns(),
+        collection: collection,
+        gridOpts: {
+          className: 'table table-bordered table-striped backgrid'
+        }
+      }));
+    },
+
+    getColumns: function() {
+      this.countActive = 0;
+      var cols = [{
+        name: "name",
+        cell: "string",
+        label: localization.tt("lbl.name"),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.topologySummaryName')
+      }, {
+        name: "id",
+        cell: "string",
+        label: localization.tt("lbl.id"),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.topologySummaryId')
+      }, {
+        name: "owner",
+        cell: "string",
+        label: localization.tt("lbl.owner"),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.topologySummaryOwner')
+      }, {
+        name: "status",
+        cell: "string",
+        label: localization.tt("lbl.status"),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.topologySummaryStatus')
+      }, {
+        name: "uptime",
+        cell: "string",
+        label: localization.tt("lbl.uptime"),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.topologySummaryUptime')
+      }, {
+        name: "workersTotal",
+        cell: "string",
+        label: "# "+localization.tt("lbl.workers"),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.topologySummaryWorkers')
+      }, {
+        name: "executorsTotal",
+        cell: "string",
+        label: "# "+localization.tt("lbl.executors"),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.topologySummaryExecutors')
+      }, {
+        name: "tasksTotal",
+        cell: "string",
+        label: "# "+localization.tt("lbl.tasks"),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.topologySummaryTasks')
+      }, {
+        name: "schedulerInfo",
+        cell: "string",
+        label: localization.tt("lbl.schedulerInfo"),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.topologySummaryScheduler')
+      }];
+      return cols;
+    },
+
+    showSummaryTable: function(id) {
+      var object = _.findWhere(this.summaryArr, {
+        window: id
+      });
+      if(_.isNull(object) || _.isUndefined(object)){
+        object = {};
+        object.emitted = 0;
+        object.transferred = 0;
+        object.completeLatency = 0;
+        object.acked = 0;
+        object.failed = 0;
+        object.window = id;
+      }
+      this.ui.topologySummary.html(this.summaryTemplate(object));
+    },
+
+    evActivateTopology: function() {
+      var that = this;
+      bootbox.confirm({
+        message: localization.tt('dialogMsg.activateTopologyMsg'),
+        buttons: {
+          confirm: {
+            label: localization.tt('btn.yes'),
+            className: "btn-success",
+          },
+          cancel: {
+            label: localization.tt('btn.no'),
+            className: "btn-default",
+          }
+        },
+        callback: function(result){
+          if(result){
+            that.model.activateTopology({
+              id: that.model.get('id'),
+              success: function(model, response, options){
+                
Utils.notifySuccess(localization.tt('dialogMsg.topologyActivateSuccessfully'));
+                that.fetchData(that.model.get('id'), that.systemBoltFlag, 
that.windowTimeFrame);
+              },
+              error: function(model, response, options){
+                Utils.notifyError(model.statusText);
+              }
+            });
+          }
+        }
+      });
+
+    },
+    evDeactivateTopology: function() {
+      var that = this;
+      bootbox.confirm({
+        message: localization.tt('dialogMsg.deactivateTopologyMsg'),
+        buttons: {
+          confirm: {
+            label: localization.tt('btn.yes'),
+            className: "btn-success",
+          },
+          cancel: {
+            label: localization.tt('btn.no'),
+            className: "btn-default",
+          }
+        },
+        callback: function(result){
+          if(result){
+            that.model.deactivateTopology({
+              id: that.model.get('id'),
+              success: function(model, response, options){
+                
Utils.notifySuccess(localization.tt('dialogMsg.topologyDeactivateSuccessfully'));
+                that.fetchData(that.model.get('id'), that.systemBoltFlag, 
that.windowTimeFrame);
+              },
+              error: function(model, response, options){
+                Utils.notifyError(model.statusText);
+              }
+            });
+          }
+        }
+      });
+    },
+    evRebalanceTopology: function() {
+      var that = this;
+      if(this.view){
+        this.onDialogClosed();
+      }
+      require(['views/Topology/RebalanceForm'], function(rebalanceForm){
+        that.view = new rebalanceForm({
+          spoutCollection : that.spoutsCollection,
+          boltCollection: that.boltsCollection
+        });
+        that.view.render();
+
+        bootbox.dialog({
+          message: that.view.$el,
+          title: localization.tt('lbl.rebalanceTopology'),
+          className: "topology-modal",
+          buttons: {
+            cancel: {
+              label: localization.tt('btn.cancel'),
+              className: "btn-default",
+              callback: function(){
+                that.onDialogClosed();
+              }
+            },
+            success: {
+              label: localization.tt('btn.save'),
+              className: "btn-success",
+              callback: function(){
+                var err = that.view.validate();
+                if(_.isEmpty(err)){
+                  that.rebalanceTopology();
+                } else return false;
+              }
+            }
+          }
+        });
+      });
+    },
+    rebalanceTopology: function(){
+      var that = this,
+          attr = this.view.getValue(),
+          obj = {"rebalanceOptions":{}};
+
+      if(!_.isUndefined(attr.workers) && !_.isNull(attr.workers)){
+        obj.rebalanceOptions.numWorkers = attr.workers;
+      }
+
+      var spoutBoltObj = {};
+      for(var key in attr){
+        if(!_.isEqual(key,'workers') && !_.isEqual(key,'waitTime')){
+          if(!_.isNull(attr[key])){
+            spoutBoltObj[key] = attr[key];
+          }
+        }
+      }
+
+      if(_.keys(spoutBoltObj).length){
+        obj.rebalanceOptions.executors = spoutBoltObj;
+      }
+
+      $.ajax({
+        url: Globals.baseURL + '/api/v1/topology/' + that.model.get('id') + 
'/rebalance/' + attr.waitTime,
+        data: (_.keys(obj.rebalanceOptions).length) ? JSON.stringify(obj) : 
null,
+        cache: false,
+        contentType: 'application/json',
+        type: 'POST',
+        success: function(model, response, options){
+          if(!_.isUndefined(model.error)){
+            Utils.notifyError(model.error);
+          } else {
+            
Utils.notifySuccess(localization.tt('dialogMsg.topologyRebalanceSuccessfully'));
+            that.fetchData(that.model.get('id'), that.systemBoltFlag, 
that.windowTimeFrame);
+          }
+        },
+        error: function(model, response, options){
+          Utils.notifyError(model.statusText);
+        }
+      });
+    },
+    evKillTopology: function() {
+      var that = this;
+      bootbox.prompt({
+        title: localization.tt('dialogMsg.killTopologyMsg'),
+        value: "30",
+        buttons: {
+          confirm: {
+            label: localization.tt('btn.yes'),
+            className: "btn-success",
+          },
+          cancel: {
+            label: localization.tt('btn.no'),
+            className: "btn-default",
+          }
+        },
+        callback: function(result) {
+          if(result != null){
+            that.model.killTopology({
+              id: that.model.get('id'),
+              waitTime: result,
+              success: function(model, response, options){
+                
Utils.notifySuccess(localization.tt('dialogMsg.topologyKilledSuccessfully'));
+                that.fetchData(that.model.get('id'), that.systemBoltFlag, 
that.windowTimeFrame);
+              },
+              error: function(model, response, options){
+                Utils.notifyError(model.statusText);
+              }
+            });
+          }
+        }
+      });
+    },
+    onDialogClosed: function() {
+      if (this.view) {
+        this.view.close();
+        this.view.remove();
+        this.view = null;
+      }
+    },
+    openAllTables: function(){
+      console.log("Open All !!");
+    },
+    evSysBoltToggle: function(e){
+      this.systemBoltFlag = $(e.currentTarget).is(':checked');
+      this.fetchData(this.model.get('id'), this.systemBoltFlag, 
this.windowTimeFrame);
+    },
+
+    getSpoutColumns: function() {
+      var cols = [{
+        name: "spoutId",
+        cell: "string",
+        label: localization.tt("lbl.id"),
+        sortable: true,
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.spoutId')
+      },
+      {
+        name: "executors",
+        cell: "string",
+        label: localization.tt("lbl.executors"),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.spoutExecutors'),
+        sortable: true
+      },
+      {
+        name: "tasks",
+        cell: "string",
+        label: localization.tt("lbl.tasks"),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.spoutTask'),
+        sortable: true,
+      },
+      {
+        name: "emitted",
+        cell: "string",
+        label: localization.tt("lbl.emitted"),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.emitted'),
+        sortable: true
+      },
+      {
+        name: "transferred",
+        cell: "string",
+        label: localization.tt("lbl.transferred"),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.transferred'),
+        sortable: true
+      },
+      {
+        name: "completeLatency",
+        cell: "string",
+        label: localization.tt("lbl.completeLatency"),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.completeLatency'),
+        sortable: true
+      },
+      {
+        name: "acked",
+        cell: "string",
+        label: localization.tt("lbl.acked"),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.acked'),
+        sortable: true
+      },
+      {
+        name: "failed",
+        cell: "string",
+        label: localization.tt("lbl.failed"),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.failed'),
+        sortable: true
+      }
+      ];
+      return cols;
+    },
+
+    getBoltColumns: function() {
+      var cols = [{
+        name: "boltId",
+        cell: "string",
+        label: localization.tt('lbl.id'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.spoutId'),
+        sortable: true
+      }, {
+        name: "executors",
+        cell: "string",
+        label: localization.tt('lbl.executors'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.spoutExecutors'),
+      }, {
+        name: "tasks",
+        cell: "string",
+        label: localization.tt('lbl.tasks'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.spoutTasks'),
+      }, {
+        name: "emitted",
+        cell: "string",
+        label: localization.tt('lbl.emitted'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.emitted'),
+      }, {
+        name: "transferred",
+        cell: "string",
+        label: localization.tt('lbl.transferred'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.transferred'),
+      }, {
+        name: "capacity",
+        cell: "string",
+        label: localization.tt('lbl.capacity'),
+        formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+          fromRaw: function(rawValue, model) {
+            if (model) {
+              return (parseFloat(model.attributes.capacity) < 1 ? " < 1%" : " 
"+model.get('capacity')+" %");
+            }
+          }
+        }),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.boltCapacity'),
+      }, {
+        name: "executeLatency",
+        cell: "string",
+        label: localization.tt('lbl.executeLatency'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.boltExecuteLatency'),
+      }, {
+        name: "executed",
+        cell: "string",
+        label: localization.tt('lbl.executed'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.boltExected'),
+      }, {
+        name: "processLatency",
+        cell: "string",
+        label: localization.tt('lbl.processLatency'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.boltProcessLatency'),
+      }, {
+        name: "acked",
+        cell: "string",
+        label: localization.tt('lbl.acked'),
+        hasTooltip: true,
+        tooltipText: localization.tt('msg.boltAcked'),
+      }];
+      return cols;
+    },
+
+    showBreadCrumbs: function(){
+      vent.trigger('Breadcrumb:Show', (this.model.has('name')) ? 
this.model.get('name') : 'No-Name');
+    },
+
+    getTopoConfigColumns: function() {
+
+      var cols = [
+
+        {
+          name: "key",
+          cell: "string",
+          label: localization.tt('lbl.key'),
+          sortable: true
+        }, {
+          name: "value",
+          cell: "string",
+          label: localization.tt('lbl.value'),
+        }
+      ];
+      return cols;
+    },
+
+    startPollingAction: function(id){
+      var that = this;
+      setTimeout(function(){
+        if(_.isEqual(typeof that.ui.BoltsSummaryDetails, "object")){
+          that.fetchData(id, that.systemBoltFlag, that.windowTimeFrame);
+        }
+      }, Globals.settings.refreshInterval);
+    }
+
+  });
+  return masterView;
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/views/Topology/TopologyForm.js
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/views/Topology/TopologyForm.js 
b/contrib/views/storm/src/main/resources/scripts/views/Topology/TopologyForm.js
new file mode 100644
index 0000000..d08e353
--- /dev/null
+++ 
b/contrib/views/storm/src/main/resources/scripts/views/Topology/TopologyForm.js
@@ -0,0 +1,102 @@
+/**
+* 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(['utils/LangSupport',
+  'utils/Globals',
+  'hbs!tmpl/topology/topologyForm',
+  'backbone.forms'
+  ], function (localization, Globals, tmpl) {
+  'use strict';
+
+  // var tmpl = ;
+  var TopologyForm = Backbone.Form.extend({
+
+    template: tmpl,
+
+    initialize: function (options) {
+      Backbone.Form.prototype.initialize.call(this, options);
+      this.bindEvents();
+    },
+
+    bindEvents: function () {
+      console.log('Binding Events Here !!');
+    },
+
+    schema: function () {
+      return {
+        name: {
+          type: 'Text',
+          title: localization.tt('lbl.name')+'*',
+          editorClass : 'form-control',
+          validators: ['required']
+        },
+        jar: {
+          type: 'Fileupload',
+          title: localization.tt('lbl.jar')+'*',
+          validators: ['required']
+        },
+        // nimbusHostname: {
+        //   type: 'Select',
+        //   title: localization.tt('lbl.nimbusHostname')+'*',
+        //   options: [{
+        //     val: '',
+        //     label: '--'
+        //   },
+        //   {
+        //     val: '1',
+        //     label: 'Hostname 1'
+        //   }, {
+        //     val: '2',
+        //     label: 'Hostname 2'
+        //   }, {
+        //     val: '3',
+        //     label: 'Hostname 3'
+        //   }],
+        //   editorClass : 'form-control',
+        //   validators: ['required']
+        // },
+        topologyClass: {
+          type: 'Text',
+          title: localization.tt('lbl.topologyClass')+'*',
+         editorClass : 'form-control',
+          validators: ['required']
+        },
+        arguments: {
+          type: 'Text',
+          title: localization.tt('lbl.arguments'),
+          editorClass : 'form-control',
+          // validators: ['required']
+        }
+      };
+    },
+
+    // render: function (options) {
+    //   Backbone.Form.prototype.render.call(this, options);
+    // },
+
+    getData: function () {
+      return this.getValue();
+    },
+
+    close: function () {
+      console.log('Closing form view');
+    }
+  });
+
+  return TopologyForm;
+});
\ No newline at end of file

Reply via email to