You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by al...@apache.org on 2014/12/09 18:43:33 UTC

ambari git commit: AMBARI-8404. View: CapScheduler enhancements, cleanup (alexantonenko)

Repository: ambari
Updated Branches:
  refs/heads/trunk cff01d6ff -> 793c8a2c7


AMBARI-8404. View: CapScheduler enhancements, cleanup (alexantonenko)


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

Branch: refs/heads/trunk
Commit: 793c8a2c70421ac7ce8dd6b664fe7a937f1a2a66
Parents: cff01d6
Author: Alex Antonenko <hi...@gmail.com>
Authored: Tue Dec 9 19:09:28 2014 +0200
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Tue Dec 9 19:43:03 2014 +0200

----------------------------------------------------------------------
 contrib/views/capacity-scheduler/pom.xml        |   1 -
 .../capacityscheduler/ConfigurationService.java |  11 +-
 .../src/main/resources/ui/app/adapters.js       |  26 +++-
 .../ui/app/assets/fonts/FontAwesome.otf         | Bin 0 -> 75188 bytes
 .../ui/app/assets/fonts/fontawesome-webfont.eot | Bin 0 -> 72449 bytes
 .../ui/app/assets/fonts/fontawesome-webfont.ttf | Bin 0 -> 141564 bytes
 .../app/assets/fonts/fontawesome-webfont.woff   | Bin 0 -> 83760 bytes
 .../src/main/resources/ui/app/components.js     |   2 +
 .../ui/app/components/clickElsewhere.js         |  49 ++++++++
 .../ui/app/components/confirmDelete.js          |  34 +-----
 .../ui/app/components/dropdownConfirmation.js   |  55 +++++++++
 .../resources/ui/app/components/pathInput.js    |  34 +++++-
 .../ui/app/components/totalCapacity.js          |   8 +-
 .../ui/app/components/userGroupInput.js         |  33 +++---
 .../main/resources/ui/app/controllers/queue.js  |  69 ++++-------
 .../main/resources/ui/app/controllers/queues.js |  60 +++++++---
 .../src/main/resources/ui/app/initialize.js     |   3 +
 .../src/main/resources/ui/app/models/queue.js   |   4 +-
 .../src/main/resources/ui/app/router.js         |   5 +-
 .../resources/ui/app/styles/application.less    |  43 +++++--
 .../ui/app/templates/components/pathInput.hbs   |   2 +-
 .../app/templates/components/totalCapacity.hbs  |  16 +--
 .../main/resources/ui/app/templates/queue.hbs   | 118 ++++++++++---------
 .../main/resources/ui/app/templates/queues.hbs  |  58 ++++++---
 .../ui/app/templates/schedulerPanel.hbs         |  16 +--
 .../src/main/resources/ui/app/views/queues.js   |  34 ++++++
 .../src/main/resources/ui/config.coffee         |  18 ++-
 27 files changed, 463 insertions(+), 236 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/pom.xml
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/pom.xml b/contrib/views/capacity-scheduler/pom.xml
index 6245a3f..7b0eb41 100644
--- a/contrib/views/capacity-scheduler/pom.xml
+++ b/contrib/views/capacity-scheduler/pom.xml
@@ -128,7 +128,6 @@
               <arguments>
                 <argument>node_modules/.bin/brunch</argument>
                 <argument>build</argument>
-                <argument>--production</argument>
               </arguments>
             </configuration>
             </execution>

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/java/org/apache/ambari/view/capacityscheduler/ConfigurationService.java
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/java/org/apache/ambari/view/capacityscheduler/ConfigurationService.java b/contrib/views/capacity-scheduler/src/main/java/org/apache/ambari/view/capacityscheduler/ConfigurationService.java
index 556491e..e6d81d0 100644
--- a/contrib/views/capacity-scheduler/src/main/java/org/apache/ambari/view/capacityscheduler/ConfigurationService.java
+++ b/contrib/views/capacity-scheduler/src/main/java/org/apache/ambari/view/capacityscheduler/ConfigurationService.java
@@ -101,15 +101,12 @@ public class ConfigurationService {
     URL url = null;
     try {
         url = new URL(baseUrl);
-    } catch (MalformedURLException e) {
-        // !!! I know, I know
-        e.printStackTrace();
+    } catch (MalformedURLException ex) {
+      throw new ServiceFormattedException("Error in ambari.server.url property: " + ex.getMessage(), ex);
     }
 
-    // !!! and yes, I know
-    String file = url.getFile();
-    serverUrl = baseUrl.substring(0, baseUrl.length() - file.length());
-
+    String clusterName = url.getFile(); // TODO: make it more robust
+    serverUrl = baseUrl.substring(0, baseUrl.length() - clusterName.length());
   }
 
   // ================================================================================

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/adapters.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/adapters.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/adapters.js
index ca2cdee..cee4ac1 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/adapters.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/adapters.js
@@ -107,6 +107,18 @@ App.QueueAdapter = DS.Adapter.extend({
     });
 
   },
+
+  getPrivilege:function () {
+    var uri = _getCapacitySchedulerUri(this.clusterName, this.tag);
+    return new Ember.RSVP.Promise(function(resolve, reject) {
+      this.ajax([uri,'privilege'].join('/'),'GET').then(function(data) {
+        Ember.run(null, resolve, data);
+      }, function(jqXHR) {
+        jqXHR.then = null;
+        Ember.run(null, reject, jqXHR);
+      });
+    }.bind(this));
+  },
      
   ajax: function(url, type, hash) {
     var adapter = this;
@@ -149,7 +161,7 @@ App.QueueAdapter = DS.Adapter.extend({
     }
 
     return jqXHR;
-  },
+  }
 });
 
 App.SchedulerAdapter = App.QueueAdapter.extend({
@@ -157,13 +169,15 @@ App.SchedulerAdapter = App.QueueAdapter.extend({
     return store.findAll('scheduler').then(function (scheduler) {
       return {"scheduler":scheduler.findBy('id',id).toJSON({includeId:true})};
     });
-  },
+  }
 });
 
 App.ApplicationStore = DS.Store.extend({
 
   adapter: App.QueueAdapter,
 
+  configNote:'',
+
   markForRefresh:function (mark) {
     this.set('defaultAdapter.saveMark','saveAndRefresh');
   },
@@ -209,6 +223,9 @@ App.ApplicationStore = DS.Store.extend({
       record.adapterDidError();
     }
   },
+  checkOperator:function () {
+    return this.get('defaultAdapter').getPrivilege();
+  }
 });
 
 App.ApplicationSerializer = DS.RESTSerializer.extend({
@@ -217,6 +234,7 @@ App.ApplicationSerializer = DS.RESTSerializer.extend({
 
   serializeConfig:function (records) {
     var config = {},
+        note = this.get('store.configNote'),
         prefix = this.PREFIX;
     records.forEach(function (record) {
       if (record.id == 'scheduler') {
@@ -243,7 +261,9 @@ App.ApplicationSerializer = DS.RESTSerializer.extend({
       }
     }
 
-    return {properties : config};
+    this.set('store.configNote','');
+
+    return {properties : config, service_config_version_note: note};
 
   },
   normalizeConfig:function (store, payload) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/assets/fonts/FontAwesome.otf
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/assets/fonts/FontAwesome.otf b/contrib/views/capacity-scheduler/src/main/resources/ui/app/assets/fonts/FontAwesome.otf
new file mode 100644
index 0000000..3461e3f
Binary files /dev/null and b/contrib/views/capacity-scheduler/src/main/resources/ui/app/assets/fonts/FontAwesome.otf differ

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/assets/fonts/fontawesome-webfont.eot
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/assets/fonts/fontawesome-webfont.eot b/contrib/views/capacity-scheduler/src/main/resources/ui/app/assets/fonts/fontawesome-webfont.eot
new file mode 100644
index 0000000..6cfd566
Binary files /dev/null and b/contrib/views/capacity-scheduler/src/main/resources/ui/app/assets/fonts/fontawesome-webfont.eot differ

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/assets/fonts/fontawesome-webfont.ttf
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/assets/fonts/fontawesome-webfont.ttf b/contrib/views/capacity-scheduler/src/main/resources/ui/app/assets/fonts/fontawesome-webfont.ttf
new file mode 100644
index 0000000..5cd6cff
Binary files /dev/null and b/contrib/views/capacity-scheduler/src/main/resources/ui/app/assets/fonts/fontawesome-webfont.ttf differ

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/assets/fonts/fontawesome-webfont.woff
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/assets/fonts/fontawesome-webfont.woff b/contrib/views/capacity-scheduler/src/main/resources/ui/app/assets/fonts/fontawesome-webfont.woff
new file mode 100644
index 0000000..9eaecb3
Binary files /dev/null and b/contrib/views/capacity-scheduler/src/main/resources/ui/app/assets/fonts/fontawesome-webfont.woff differ

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/components.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components.js
index eb743c4..d1279d7 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components.js
@@ -16,6 +16,7 @@
  * limitations under the License.
  */
 
+require('components/clickElsewhere');
 require('components/capacityBar');
 require('components/capacityInput');
 require('components/totalCapacity');
@@ -25,3 +26,4 @@ require('components/radioButton');
 require('components/userGroupInput');
 require('components/escapeAcl');
 require('components/confirmDelete');
+require('components/dropdownConfirmation');

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/clickElsewhere.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/clickElsewhere.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/clickElsewhere.js
new file mode 100644
index 0000000..879319a
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/clickElsewhere.js
@@ -0,0 +1,49 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+var bound;
+
+bound = function(fnName) {
+  return Ember.computed(fnName,function() {
+    return this.get(fnName).bind(this);
+  });
+};
+
+App.ClickElsewhereMixin = Ember.Mixin.create({
+  onClickElsewhere: Ember.K,
+  clickHandler: bound("elsewhereHandler"),
+  elsewhereHandler: function(e) {
+    var $target, element, thisIsElement;
+    element = this.get("element");
+    $target = $(e.target);
+    thisIsElement = $target.closest(element).length === 1;
+    if (!thisIsElement) {
+      return this.onClickElsewhere(e);
+    }
+  },
+  didInsertElement: function() {
+    this._super.apply(this, arguments);
+    return $(window).on("click", this.get("clickHandler"));
+  },
+  willDestroyElement: function() {
+    $(window).off("click", this.get("clickHandler"));
+    return this._super.apply(this, arguments);
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/confirmDelete.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/confirmDelete.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/confirmDelete.js
index 8aaebf5..8b61ca3 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/confirmDelete.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/confirmDelete.js
@@ -18,36 +18,6 @@
 
 var App = require('app');
 
-var bound;
-
-bound = function(fnName) {
-  return Ember.computed(fnName,function() {
-    return this.get(fnName).bind(this);
-  });
-};
-
-App.ClickElsewhereMixin = Ember.Mixin.create({
-  onClickElsewhere: Ember.K,
-  clickHandler: bound("elsewhereHandler"),
-  elsewhereHandler: function(e) {
-    var $target, element, thisIsElement;
-    element = this.get("element");
-    $target = $(e.target);
-    thisIsElement = $target.closest(element).length === 1;
-    if (!thisIsElement) {
-      return this.onClickElsewhere(event);
-    }
-  },
-  didInsertElement: function() {
-    this._super.apply(this, arguments);
-    return $(window).on("click", this.get("clickHandler"));
-  },
-  willDestroyElement: function() {
-    $(window).off("click", this.get("clickHandler"));
-    return this._super.apply(this, arguments);
-  }
-});
-
 App.ConfirmDeleteComponent = Em.Component.extend(App.ClickElsewhereMixin,{
   confirm:false,
   onClickElsewhere:function () {
@@ -60,7 +30,7 @@ App.ConfirmDeleteComponent = Em.Component.extend(App.ClickElsewhereMixin,{
         this.sendAction('action', this.get('param'));
       } else {
         this.toggleProperty('confirm');
-      };
+      }
     }
   },
   tagName:'a',
@@ -73,7 +43,7 @@ App.ConfirmDeleteComponent = Em.Component.extend(App.ClickElsewhereMixin,{
       }).tooltip('show');
     } else {
       element.tooltip('destroy')
-    };
+    }
   }.observes('confirm'),
   click:function (e) {
     this.send('delete');

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/dropdownConfirmation.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/dropdownConfirmation.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/dropdownConfirmation.js
new file mode 100644
index 0000000..105d960
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/dropdownConfirmation.js
@@ -0,0 +1,55 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+
+App.DropdownConfirmationComponent = Em.Component.extend(App.ClickElsewhereMixin,{
+  tagName:'li',
+  restartConfirming:false,
+  actions:{
+    showRestartConfirmation: function() {
+      this.toggleProperty('restartConfirming');
+    },
+    confirm: function() {
+      this.set('restartConfirming',false);
+      this.sendAction('action','restart');
+    }
+  },
+  onClickElsewhere:function () {
+    this.set('restartConfirming',false);
+    this.$().parents('.dropdown-menu').parent().removeClass('open');
+  },
+  dropdownHideControl:function () {
+    var _this = this;
+    this.$().parents('.dropdown-menu').parent().on(
+      "hide.bs.dropdown", function() {
+        return !_this.get('restartConfirming');
+      });
+  }.on('didInsertElement'),
+  button:Em.Component.extend({
+    tagName:'a',
+    click:function (e) {
+      this.triggerAction({
+        action: 'showRestartConfirmation',
+        target: this.get('parentView'),
+        actionContext: this.get('context')
+      });
+    }
+  })
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/pathInput.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/pathInput.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/pathInput.js
index ccdd5f1..92bfb31 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/pathInput.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/pathInput.js
@@ -22,9 +22,12 @@ App.PathInputComponent = Em.Component.extend({
   layoutName:'components/pathInput',
   actions:{
     add:function () {
-      var path = this.get('path'),
-          basedir = path.substr(0,path.lastIndexOf('.'));
-
+      var currentBasedir = this.get('currentBasedir'),
+          path = this.get('path'),
+          basedir = path.substr(0,path.lastIndexOf('.')) || currentBasedir;
+      if (!path) {
+        return this.set('isError',true);
+      }
       if (this.get('pathMap').contains(path)) {
         this.sendAction('action',path);
         this.set('activeFlag',false);
@@ -40,22 +43,43 @@ App.PathInputComponent = Em.Component.extend({
   queues:[],
   activeFlag:false,
   pathMap:Em.computed.mapBy('queues','path'),
+  currentBasedir:Em.computed(function() {
+    return this.get('queues').filterBy('isCurrent',true).get('firstObject.path') || "root";
+  }),
   path:'',
+  isError:false,
+  didChangePath:function () {
+    return this.set('isError',false);
+  }.observes('path'),
   inputFieldView: Em.TextField.extend({
     classNames:['form-control newQPath'],
     action:'add',
     pathSource:[],
     placeholder:"Enter queue path...",
     typeaheadInit:function () {
-      $(this.get('element')).typeahead({
+      this.$().typeahead({
           source: this.get('pathSource'),
           matcher: function (item) {
             return ~item.toLowerCase().indexOf(this.query.toLowerCase())
           },
-          minLength:0,
+          minLength:2,
           items:100,
           scrollHeight:5
       }).focus();
     }.observes('pathSource').on('didInsertElement'),
+    tooltipInit:function () {
+      this.$().tooltip({
+        title:'Enter queue name.',
+        placement:'bottom',
+        trigger:'manual'
+      });
+    }.on('didInsertElement'),
+    tooltipToggle:function (e,o) {
+      this.$().tooltip((e.get(o)?'show':'hide'));
+    }.observes('parentView.isError'),
+    willClearRender:function () {
+      this.$().typeahead('destroy');
+      this.$().tooltip('destroy');
+    }
   })
 });
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/totalCapacity.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/totalCapacity.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/totalCapacity.js
index aad6682..5e35b30 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/totalCapacity.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/totalCapacity.js
@@ -33,7 +33,7 @@ App.TotalCapacityComponent = Ember.Component.extend({
     },
     deleteQueue:function (queue) {
       this.sendAction('deleteQueue',queue);
-    },
+    }
   },
 
   /**
@@ -70,8 +70,8 @@ App.TotalCapacityComponent = Ember.Component.extend({
   }.property('allQueues','currentPrPath'),
 
   currentInLeaf:function (argument) {
-    var leaf = this.get('leafQueues');
-    leaf.setEach('isCurrent',false);
+    var queues = this.get('allQueues');
+    queues.setEach('isCurrent',false);
     if(!this.get('currentQueue.currentState.stateName').match(/root.deleted/)) {
       this.get('currentQueue').set('isCurrent',true);
     }
@@ -90,7 +90,7 @@ App.CapacityEditFormView = Em.View.extend({
     this.addObserver('controller.target.isEdit',this,'slide');
     if (!this.get('controller.target.isEdit')) {
       this.$('.capacity-edit-form').hide();
-    };
+    }
   }.on('didInsertElement'),
   slide:function () {
     this.$('.capacity-edit-form').slideToggle(100);

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/userGroupInput.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/userGroupInput.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/userGroupInput.js
index ff0300d..513031c 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/userGroupInput.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/userGroupInput.js
@@ -21,24 +21,25 @@ var App = require('app');
 App.UserGroupInputComponent = Em.Component.extend({
   layoutName:'components/userGroupInput',
 
-  users:null,
-  groups:null,
+  ug:'',
 
-  splitter:function () {
-    if (this.ug == '*') return;
-    var ug = this.ug || '';
-    var spl = ug.split(' ');
-    this.setProperties({
-      users:spl[0],
-      groups:spl[1]
-    });
-  }.observes('ug').on('init'),
+  users:function (key, value, previousValue) {
+    if (value) {
+      this.set('ug',[value,this.get('groups')].join(' '));
+    }
+    var ug = this.get('ug');
+    return (ug == '*')?'*':(ug || '').split(' ')[0];
+  }.property('ug'),
 
-  setter:function () {
-    this.set('ug',[this.get('users'),this.get('groups')].join(' '));
-  }.observes('users','groups'),
+  groups:function (key, value, previousValue) {
+    if (value) {
+      this.set('ug',[this.get('users'),value].join(' '));
+    }
+    var ug = this.get('ug');
+    return (ug == '*')?'*':(ug || '').split(' ')[1] || '';
+  }.property('ug'),
 
   noSpace:function (e) {
-    return (e.keyCode==32)?false:true;
-  },
+    return (e.keyCode != 32);
+  }
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queue.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queue.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queue.js
index 91e3903..a0db1f1 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queue.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queue.js
@@ -23,10 +23,11 @@ var _stopState = 'STOPPED';
 
 App.QueueController = Ember.ObjectController.extend({
   needs:['queues'],
+  isOperator:Em.computed.alias('controllers.queues.isOperator'),
+  isNotOperator:Em.computed.alias('controllers.queues.isNotOperator'),
   actions:{
     setState:function (state) {
-      var state = (state === "running")?_runState:_stopState;
-      this.content.set('state',state);
+      this.content.set('state', (state === "running") ? _runState : _stopState );
     },
     createQ:function (record) {
       this.get('controllers.queues').send('createQ',this.get('content'));
@@ -42,7 +43,7 @@ App.QueueController = Ember.ObjectController.extend({
         this.content.addObserver('name',this,this.setQueuePath);
         this.toggleProperty('isRenaming');
         return;
-      };
+      }
       if (opt == 'cancel') {
         this.send('rollbackProp','name');
         this.send('rollbackProp','id');
@@ -50,7 +51,7 @@ App.QueueController = Ember.ObjectController.extend({
         this.content.removeObserver('name',this,this.setQueuePath);
         this.toggleProperty('isRenaming');
         return;
-      };
+      }
       if (opt) {
         var self = this;
         this.store.filter('queue',function (q) {
@@ -58,7 +59,7 @@ App.QueueController = Ember.ObjectController.extend({
         }).then(function(queues){
           if (queues.get('length') > 1) {
             return self.content.get('errors').add('path', 'Queue already exists');
-          };
+          }
           self.toggleProperty('isRenaming');
           self.content.removeObserver('name',self,self.setQueuePath);
           self.transitionToRoute('queue',self.content.id);
@@ -86,7 +87,7 @@ App.QueueController = Ember.ObjectController.extend({
     queue.setProperties({
       name:name.replace(/\s|\./g, ''),
       path:parentPath+'.'+name,
-      id:(parentPath+'.'+name).dasherize(),
+      id:(parentPath+'.'+name).dasherize()
     });
 
     if (name == '') {
@@ -108,58 +109,40 @@ App.QueueController = Ember.ObjectController.extend({
   isEditRA:false,
   isEditACL:false,
 
-  acl_administer_queue:null,
+  handleAcl:function (key,value) {
+    if (value) {
+      this.set(key,(value == '*')?'*':' ');
+    }
+    return (this.get(key) == '*')? '*':'custom';
+  },
+
+  acl_administer_queue: function (key, value, previousValue) {
+    return this.handleAcl('content.acl_administer_queue',value);
+  }.property('content.acl_administer_queue'),
   aaq_anyone:Ember.computed.equal('acl_administer_queue', '*'),
   aaq_dirty:function () {
     var attributes = this.content.changedAttributes();
     return attributes.hasOwnProperty('acl_administer_queue');
   }.property('content.acl_administer_queue'),
 
-  acl_administer_jobs:null,
+  acl_administer_jobs: function (key, value, previousValue) {
+    return this.handleAcl('content.acl_administer_jobs',value);
+  }.property('content.acl_administer_jobs'),
   aaj_anyone:Ember.computed.equal('acl_administer_jobs', '*'),
   aaj_dirty:function () {
     var attributes = this.content.changedAttributes();
     return attributes.hasOwnProperty('acl_administer_jobs');
   }.property('content.acl_administer_jobs'),
 
-  acl_submit_applications:null,
+  acl_submit_applications: function (key, value, previousValue) {
+    return this.handleAcl('content.acl_submit_applications',value);
+  }.property('content.acl_submit_applications'),
   asa_anyone:Ember.computed.equal('acl_submit_applications', '*'),
   asa_dirty:function () {
     var attributes = this.content.changedAttributes();
     return attributes.hasOwnProperty('acl_submit_applications');
   }.property('content.acl_submit_applications'),
 
-  aclSerializer:function (c,o) {
-    var acl = o.substr(o.indexOf('.')+1);
-    var aclProp = c.get(o);
-    var aclVal;
-    switch(aclProp) {
-      case '*': 
-        aclVal = '*'; 
-        break;
-      
-      default:
-        aclVal = 'custom'; 
-    }
-    c.set(acl,aclVal);
-  }.observes('content.acl_administer_queue','content.acl_administer_jobs','content.acl_submit_applications'),
-
-  aclDeserializer:function (c,o) {
-    var aclVal = c.get(o);
-    var aclProp;
-    switch(aclVal) {
-      case '*': 
-        aclProp = '*'; 
-        this.set('content.'+o,aclProp);
-        break;
-      
-      default:
-        if (this.get('content.'+o)=='*') {
-          this.set('content.'+o,' ');
-        }
-    }
-  }.observes('acl_administer_queue','acl_administer_jobs','acl_submit_applications'),
-
   capacityControl:function () {
     var leafQueues = this.get('leafQueues');
     var total = 0;
@@ -167,7 +150,7 @@ App.QueueController = Ember.ObjectController.extend({
     leafQueues.forEach(function (queue) {
       total+=Number(queue.get('capacity'));
     });
-    leafQueues.setEach('overCapacity',total>100)
+    leafQueues.setEach('overCapacity',total>100);
   }.observes('content.capacity','leafQueues.@each.capacity'),
   leafQueues:function () {
     return this.get('allQueues').filterBy('parentPath',this.get('content.parentPath'));
@@ -176,8 +159,8 @@ App.QueueController = Ember.ObjectController.extend({
   queueNamesControl:function (c,o) {
     var leaf = c.get('leafQueues');
     var parent = c.get('allQueues').filterBy('path',c.get('content.parentPath')).get('firstObject');
-    if (parent) parent.set('queueNames',leaf.mapBy('name').join());
-  }.observes('allQueues.length','allQueues.@each.name'),
+    if (parent) parent.set('queueNames',leaf.mapBy('name').join() || null);
+  }.observes('allQueues.length','allQueues.@each.name','content'),
 
   pathErrors:Ember.computed.mapBy('content.errors.path','message')
   

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queues.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queues.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queues.js
index cdbf41b..cc20706 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queues.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queues.js
@@ -33,7 +33,7 @@ App.QueuesController = Ember.ArrayController.extend({
     addQ:function (parentPath,name) {
       if (!parentPath || this.get('hasNewQueue')) {
         return;
-      };
+      }
       name = name || '';
       var newQueue = this.store.createRecord('queue',{
         name:name,
@@ -42,7 +42,12 @@ App.QueuesController = Ember.ArrayController.extend({
         isNewQueue:true
       });
       this.set('newQueue',newQueue);
-      this.send('goToQueue',newQueue);
+      if (name) {
+        this.send('goToQueue',newQueue);
+        this.send('createQ',newQueue);
+      } else {
+        this.send('goToQueue',newQueue);
+      }
     },
     createQ:function (record) {
       record.save().then(Em.run.bind(this,this.set,'newQueue',null));
@@ -50,13 +55,13 @@ App.QueuesController = Ember.ArrayController.extend({
     delQ:function (record) {
       if (record.get('isNew')) {
         this.set('newQueue',null);
-      };
+      }
       if (!record.get('isNewQueue')) {
         this.set('hasDeletedQueues',true);
-      };
+      }
       if (record.isCurrent) {
         this.transitionToRoute('queue',record.get('parentPath'));
-      };
+      }
       this.store.deleteRecord(record);
     },
     saveConfig:function (mark) {
@@ -64,9 +69,16 @@ App.QueuesController = Ember.ArrayController.extend({
         this.get('store').markForRestart();
       } else if (mark == 'refresh') {
         this.get('store').markForRefresh();
-      };
-      Em.RSVP.Promise.all([this.get('scheduler').save(),this.get('model').save()])
-        .catch(Em.run.bind(this,this.saveError));
+      }
+
+      var hadDeletedQueues = this.get('hasDeletedQueues'),
+          scheduler = this.get('scheduler').save(),
+          model = this.get('model').save(),
+          all = Em.RSVP.Promise.all([model,scheduler]);
+
+      all.catch(Em.run.bind(this,this.saveError,hadDeletedQueues));
+
+      this.set('hasDeletedQueues',false);
     },
     toggleEditScheduler:function () {
       this.toggleProperty('isEditScheduler');
@@ -77,11 +89,15 @@ App.QueuesController = Ember.ArrayController.extend({
   },
 
   alertMessage:null,
-  saveError:function (error) {
+  saveError:function (hadDeletedQueues,error) {
+    this.set('hasDeletedQueues',hadDeletedQueues);
     var response = JSON.parse(error.responseText);
     this.set('alertMessage',response);
   },
 
+  isOperator:false,
+  isNotOperator:cmp.not('isOperator'),
+
   isEditScheduler:false,
 
   isWaitingPath:false,
@@ -89,7 +105,7 @@ App.QueuesController = Ember.ArrayController.extend({
    * check if RM needs refresh
    * @type {bool}
    */
-  needRefresh: cmp.any('hasChanges', 'hasNewQueues','dirtyScheduler'),
+  needRefresh: cmp.and('needRefreshProps','noNeedRestart'),
 
   /**
    * props for 'needRefresh'
@@ -99,6 +115,9 @@ App.QueuesController = Ember.ArrayController.extend({
   newQueues: cmp.filterBy('content', 'isNewQueue', true),
   hasChanges: cmp.notEmpty('dirtyQueues.[]'),
   hasNewQueues: cmp.notEmpty('newQueues.[]'),
+
+  needRefreshProps: cmp.any('hasChanges', 'hasNewQueues','dirtyScheduler'),
+  noNeedRestart: cmp.not('needRestart'),
   
   /**
    * check if RM needs restart 
@@ -122,7 +141,7 @@ App.QueuesController = Ember.ArrayController.extend({
    * check if can save configs
    * @type {bool}
    */
-  canNotSave: cmp.any('hasOverCapacity', 'hasUncompetedAddings','hasNotValid'),
+  canNotSave: cmp.any('hasOverCapacity', 'hasUncompetedAddings','hasNotValid','isNotOperator'),
 
   /**
    * props for canNotSave
@@ -134,21 +153,34 @@ App.QueuesController = Ember.ArrayController.extend({
   hasOverCapacity:cmp.notEmpty('overCapacityQ.[]'),
   hasUncompetedAddings:cmp.notEmpty('uncompetedAddings.[]'),
 
+  /**
+   * check there is some changes for save
+   * @type {bool}
+   */
+  needSave: cmp.any('needRestart', 'needRefresh'),
+
   newQueue:null,
   hasNewQueue: cmp.bool('newQueue'),
   trackNewQueue:function () {
     var newQueue = this.get('newQueue');
     if (Em.isEmpty(newQueue)){
       return;
-    };
+    }
     var name = newQueue.get('name');
     var parentPath = newQueue.get('parentPath');
 
     this.get('newQueue').setProperties({
       name:name.replace(/\s/g, ''),
       path:parentPath+'.'+name,
-      id:(parentPath+'.'+name).dasherize(),
+      id:(parentPath+'.'+name).dasherize()
     });
 
-  }.observes('newQueue.name')
+  }.observes('newQueue.name'),
+
+  configNote:function (arg,val) {
+    if (arguments.length > 1) {
+      this.set('store.configNote',val);
+    }
+    return this.get('store.configNote');
+  }.property('store.configNote')
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/initialize.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/initialize.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/initialize.js
index ebea5ff..dda4c83 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/initialize.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/initialize.js
@@ -36,5 +36,8 @@ require('templates');
 // models
 require('models');
 
+//views
+require('views/queues');
+
 // routes
 require('router');

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/queue.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/queue.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/queue.js
index 4b951d3..3219660 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/queue.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/queue.js
@@ -47,8 +47,8 @@ App.Queue = DS.Model.extend({
   acl_administer_jobs: DS.attr('string', { defaultValue: '*' }),
   acl_submit_applications: DS.attr('string', { defaultValue: '*' }),
   
-  minimum_user_limit_percent: DS.attr('number', { defaultValue: 0 }),
-  user_limit_factor: DS.attr('number', { defaultValue: 0 }),
+  minimum_user_limit_percent: DS.attr('number', { defaultValue: 100 }),
+  user_limit_factor: DS.attr('number', { defaultValue: 1 }),
   
   queueNames: DS.attr('string'),
   queueNamesArray:function () {

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/router.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/router.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/router.js
index ceb4f86..33b3977 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/router.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/router.js
@@ -49,6 +49,9 @@ App.QueuesRoute = Ember.Route.extend({
     return this.store.find('queue');
   },
   setupController:function (c,model) {
+    this.store.checkOperator().then(function (isOperator) {
+      c.set('isOperator',isOperator);
+    });
     c.set('model',model);
     this.store.find('scheduler','scheduler').then(function (s) {
       c.set('scheduler',s);
@@ -80,7 +83,7 @@ App.QueueRoute = Ember.Route.extend({
     willTransition: function (tr) {
       if (this.get('controller.isRenaming')) {
         tr.abort();
-      };
+      }
     }
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/styles/application.less
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/styles/application.less b/contrib/views/capacity-scheduler/src/main/resources/ui/app/styles/application.less
index 2f13d09..8f394b8 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/styles/application.less
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/styles/application.less
@@ -20,6 +20,15 @@
   padding: 15px;
 }
 
+.add-queue {
+  .tooltip.bottom .tooltip-arrow {
+    border-bottom-color: #a94442;
+  }
+  .tooltip-inner {
+    background-color: #a94442;
+  }
+}
+
 .queue-label {
     float: left;
     padding-right: 10px;
@@ -39,23 +48,20 @@
     margin-top: 3px;
 }
 
-.form-horizontal .control-label {
-    padding-top: 0;
-    text-align: right;
-}
-
 .form-horizontal .control-value {
+  .btn-group{
     padding-top: 5px;
+  }
 }
 
 .edit-link {
     font-size: .75em;
     padding-top: 4px;
-    }
+}
 
 .control-label {
     font-size: .9em;
-    }
+}
     
 .well-queue {
     background-color: #ffffff;
@@ -175,6 +181,18 @@
 
 .btn-group-save {
   table-layout: auto;
+  & > .btn-group:last-child > .btn:first-child {
+    border-top-left-radius: 4px;
+    border-bottom-left-radius: 4px;
+  }
+  & > .btn-group:first-child > .dropdown-toggle {
+    border-top-right-radius: 4px;
+    border-bottom-right-radius: 4px;
+  }
+  .dropdown-menu .btn {
+    border-radius: 0;
+    text-align: left;
+  }
   .btn-group {
     width: 100%;
     .btn-save {
@@ -246,7 +264,6 @@
   }
   .panel-body.queues {
     border-top: 1px solid #dddddd;
-//    background-color: #f5f5f5;
   }
 
   .queue-capacity{
@@ -286,3 +303,13 @@
     margin-left: 0px;
   }
 }
+
+#noteModal {
+  .modal-body {
+    overflow-x: hidden;
+  }
+}
+
+.modal-backdrop.in {
+  opacity: 0;
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/pathInput.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/pathInput.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/pathInput.hbs
index ec4ec4c..d1bcd11 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/pathInput.hbs
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/pathInput.hbs
@@ -16,7 +16,7 @@
 * limitations under the License.
 }}
 
-<div class="input-group path-input">
+<div {{bind-attr class=":input-group :path-input isError:has-error" }} >
   {{view inputFieldView pathSource=pathMap value=path}}
   <span class="input-group-btn">
     <button {{action cancel}} class="btn btn-danger" type="button">

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/totalCapacity.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/totalCapacity.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/totalCapacity.hbs
index f6f3c64..e00c1cc 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/totalCapacity.hbs
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/totalCapacity.hbs
@@ -20,13 +20,15 @@
   <div class="panel-heading">
   <div class="panel-title">
     <strong>Capacity</strong>
-    <a href="#" {{action 'toggleEdit'}} class="text-right"> 
-      {{#if view.isEdit}}
-        <div class="edit-link">Hide Edit</div>
-      {{else}}
-        <div class="edit-link">Show Edit</div>
-      {{/if}}
-    </a>
+    {{#if isOperator}}
+      <a href="#" {{action 'toggleEdit'}} class="text-right">
+        {{#if view.isEdit}}
+          <div class="edit-link">Hide Edit</div>
+        {{else}}
+          <div class="edit-link">Show Edit</div>
+        {{/if}}
+      </a>
+    {{/if}}
   </div>
   </div>
   <div class="panel-body total">

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/queue.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/queue.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/queue.hbs
index 9a99b18..caf3dd1 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/queue.hbs
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/queue.hbs
@@ -17,60 +17,57 @@
 }}
 
 <div class="well-queue">
-  
   <div class="row queue-heading-row">
-      <div class="col-md-12">
-          {{#if content.isNew}}
-            <div class="input-group">
-            <h3>
-              {{focus-input value=content.name length="250" class="form-control" classBinding="content.isValid::input-error" action="createQ" revert="delQ" placeholder="Enter Queue Name"}}
-              <span class="input-group-btn">
-                <button {{action "delQ" content target="controllers.queues"}} {{bind-attr class=":btn :btn-danger"}} type="button">Cancel</button>
-                <button {{action "createQ" content target="controllers.queues"}} {{bind-attr class=":btn :btn-success content.isValid::disabled"}} type="button">Create</button>
-              </span>
-            </h3>
-            </div>
-            {{else}}
-              {{#unless isRenaming}}
-                <h3>
-                  {{content.name}}
-                  {{#unless isRoot}}
+    <div class="col-md-12">
+      <h3>
+        {{#if content.isNew}}
+          <div class="input-group col-md-8">
+            {{focus-input value=content.name length="250" class="form-control" classBinding="content.isValid::input-error" action="createQ" revert="delQ" placeholder="Enter Queue Name"}}
+            <span class="input-group-btn">
+              <button {{action "delQ" content target="controllers.queues"}} {{bind-attr class=":btn :btn-danger"}} type="button">Cancel</button>
+              <button {{action "createQ" content target="controllers.queues"}} {{bind-attr class=":btn :btn-success content.isValid::disabled"}} type="button">Create</button>
+            </span>
+          </div>
+        {{else}}
+          {{#unless isRenaming}}
+              {{content.name}}
+              {{#unless isRoot}}
+                {{#unless isNotOperator}}
                   <small>
-                    <a href="#" {{action "renameQ" 'ask'}} class="">
+                    <a href="#" {{action "renameQ" 'ask'}}>
                       <i class="fa fa-edit"></i>
                     </a>
                   </small>
                   <small>
                     {{confirm-delete action="delQ" param=content}}
                   </small>
-                  {{/unless}}
-                </h3>
-              {{else}}
-              <div class="input-group">
-                <h3>
-                {{focus-input value=content.name length="250" class="form-control" action="renameQ" revert="renameQ" classBinding="content.isValid::input-error" placeholder="Enter Queue Name"}}
-                <span class="input-group-btn">
-                  <button {{action "renameQ" 'cancel'}} {{bind-attr class=":btn :btn-danger"}} type="button">Cancel</button>
-                  <button {{action "renameQ" 'rename'}} {{bind-attr class=":btn :btn-success content.isValid::disabled"}} type="button">Rename</button>
-                </span>
-                </h3>
-              </div>
+                {{/unless}}
               {{/unless}}
-          {{/if}}
-            {{#each pathErrors}}
-                <p class="help-block red">{{this}}</p>
-            {{/each}}
-          <h4 ><small>{{content.path}}</small>
-            <div class="btn-group btn-group-xs" data-toggle="buttons" >
-              <label  {{action 'setState' 'running'}} {{bind-attr class=":btn isRunning:btn-success:btn-default isRunning:active" }}>
-                <input type="radio" name="options"> Running
-              </label>
-              <label  {{action 'setState' 'stopped'}} {{bind-attr class=":btn isRunning:btn-default:btn-danger isRunning::active" }}>
-                <input type="radio" name="options"> Stopped
-              </label>
+            {{else}}
+            <div class="input-group col-md-8">
+              {{focus-input value=content.name length="250" class="form-control" action="renameQ" revert="renameQ" classBinding="content.isValid::input-error" placeholder="Enter Queue Name"}}
+              <span class="input-group-btn">
+                <button {{action "renameQ" 'cancel'}} {{bind-attr class=":btn :btn-danger"}} type="button">Cancel</button>
+                <button {{action "renameQ" 'rename'}} {{bind-attr class=":btn :btn-success content.isValid::disabled"}} type="button">Rename</button>
+              </span>
             </div>
-          </h4>
-      </div>
+          {{/unless}}
+        {{/if}}
+      </h3>
+      {{#each pathErrors}}
+        <p class="help-block red">{{this}}</p>
+      {{/each}}
+      <h4 ><small>{{content.path}}</small>
+        <div class="btn-group btn-group-xs" data-toggle="buttons" >
+          <label  {{action 'setState' 'running'}} {{bind-attr class=":btn isRunning:btn-success:btn-default isRunning:active isNotOperator:disabled" }}>
+            <input type="radio" name="options"> Running
+          </label>
+          <label  {{action 'setState' 'stopped'}} {{bind-attr class=":btn isRunning:btn-default:btn-danger isRunning::active isNotOperator:disabled" }}>
+            <input type="radio" name="options"> Stopped
+          </label>
+        </div>
+      </h4>
+    </div>
   </div>
   <div class="row queue-capacity-row">
     <div class="col-md-12">
@@ -82,6 +79,7 @@
         createQueue="createQ" 
         deleteQueue="delQ" 
         hasNew=controllers.queues.hasNewQueue
+        isOperator=isOperator
       }}
     </div>
   </div>
@@ -91,13 +89,15 @@
         <div class="panel-heading">
           <div class="panel-title">
             <strong>Access Control</strong>
-            <a href="#" {{action 'toggleEditACL'}} class="text-right"> 
-              {{#if isEditACL}}
-                <div class="edit-link">Hide Edit</div>
-              {{else}}
-                <div class="edit-link">Show Edit</div>
-              {{/if}}
-            </a>
+            {{#if isOperator}}
+              <a href="#" {{action 'toggleEditACL'}} class="text-right">
+                {{#if isEditACL}}
+                  <div class="edit-link">Hide Edit</div>
+                {{else}}
+                  <div class="edit-link">Show Edit</div>
+                {{/if}}
+              </a>
+            {{/if}}
           </div>
         </div>
         <div class="panel-body">
@@ -191,13 +191,15 @@
         <div class="panel-heading">
           <div class="panel-title">
             <strong>Resource Allocation</strong>
-            <a href="#" {{action 'toggleEditRA'}} class="text-right"> 
-              {{#if isEditRA}}
-                <div class="edit-link">Hide Edit</div>
-              {{else}}
-                <div class="edit-link">Show Edit</div>
-              {{/if}}
-            </a>
+            {{#if isOperator}}
+              <a href="#" {{action 'toggleEditRA'}} class="text-right">
+                {{#if isEditRA}}
+                  <div class="edit-link">Hide Edit</div>
+                {{else}}
+                  <div class="edit-link">Show Edit</div>
+                {{/if}}
+              </a>
+            {{/if}}
           </div>
         </div>
         <div class="panel-body">

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/queues.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/queues.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/queues.hbs
index 9ad20cb..2c00541 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/queues.hbs
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/queues.hbs
@@ -24,30 +24,36 @@
           {{path-input queues=content action="addQ" activeFlag=isWaitingPath}}
         </div>
       {{else}}
-        <div {{bind-attr class=":add-queue needRefresh:col-md-5:col-md-6 :col-sm-6" }} >
-          <button {{action askPath}} {{bind-attr class=":btn :btn-default :btn-block hasNewQueue:disabled"}} ><i class="fa fa-plus"></i> Add Queue</button>
+        <div class="add-queue col-sm-6">
+          <button {{action askPath}} {{bind-attr class=":btn :btn-default :btn-block isNotOperator:disabled hasNewQueue:disabled"}} ><i class="fa fa-plus"></i> Add Queue</button>
         </div>
-        <div  {{bind-attr class=":add-queue needRefresh:col-md-7:col-md-6 :col-sm-6" }} >
+        <div class="add-queue col-sm-6">
           <div class="btn-group btn-group-justified btn-group-save">
             <div class="btn-group">
-            {{#if needRestart}}
-              <button {{action saveConfig 'restart'}} {{bind-attr class=":btn :btn-save :btn-success canNotSave:disabled"}} ><i class="fa fa-fw fa fa-cogs"></i> Save and Restart</button>
-              {{else}}
-              {{#if needRefresh}}
-              <button {{action saveConfig 'refresh'}} {{bind-attr class=":btn :btn-save :btn-success canNotSave:disabled"}} ><i class="fa fa-fw fa-refresh"></i> Save and Refresh</button>
-              {{else}}
-              <button {{action saveConfig}} {{bind-attr class=":btn :btn-save :btn-success canNotSave:disabled"}} ><i class="fa fa-save"></i> Save</button>
-              {{/if}}
-            {{/if}}
-            </div>
-            <div class="btn-group">
                 <button type="button" {{bind-attr class=":btn :btn-success canNotSave:disabled :dropdown-toggle"}} data-toggle="dropdown">
+                  Actions
                   <span class="caret"></span>
                 </button>
                 <ul class="dropdown-menu pull-right" role="menu">
-                  <li><a href="#" {{action saveConfig 'restart'}}><i class="fa fa-fw fa fa-cogs"></i> Save and Restart ResourceManager</a></li>
-                  <li><a href="#" {{action saveConfig 'refresh'}}><i class="fa fa-fw fa-refresh"></i> Save and Refresh Queues</a></li>
-                  <li><a href="#" {{action saveConfig}}><i class="fa fa-fw fa-save"></i> Save Only</a></li>
+                    {{#dropdown-confirmation action='saveModal' targetObject=view}}
+                      {{#view view.button action='showRestartConfirmation' classBinding=":btn needRestart::disabled"}}<i class="fa fa-fw fa fa-cogs"></i> Save and Restart ResourceManager{{/view}}
+                      {{#if view.restartConfirming}}
+                        <div class="btn-group btn-group-justified">
+                          <div class="btn-group">
+                            <a {{action showRestartConfirmation target="view"}} class="btn btn-sm btn-danger"><i class="fa fa-fw fa-lg fa-times"></i> Cancel</a>
+                          </div>
+                          <div class="btn-group">
+                            <a {{action confirm target="view"}} class="btn btn-sm btn-success"><i class="fa fa-fw fa-lg fa-check"></i> Restart</a>
+                          </div>
+                        </div>
+                      {{/if}}
+                    {{/dropdown-confirmation}}
+                  <li >
+                    <a href="#" {{action saveModal 'refresh' target="view"}} {{bind-attr class=":btn needRefresh::disabled"}}><i class="fa fa-fw fa-refresh"></i> Save and Refresh Queues</a>
+                  </li>
+                  <li>
+                    <a href="#" {{action saveModal target="view"}} {{bind-attr class=":btn needSave::disabled"}}><i class="fa fa-fw fa-save"></i> Save Only</a>
+                  </li>
                 </ul>
             </div>
           </div>
@@ -83,3 +89,21 @@
   {{partial "schedulerPanel"}}
 </div>
 
+{{!-- NOTE MODAL --}}
+<div class="modal fade" id="noteModal" tabindex="-1" role="dialog" aria-labelledby="noteModalLabel" aria-hidden="true">
+  <div class="modal-dialog">
+    <div class="modal-content">
+      <div class="modal-header">
+        <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
+        <h4 class="modal-title" id="noteModalLabel">Notes</h4>
+      </div>
+      <div class="modal-body">
+        {{textarea class="form-control" rows="3" style="max-width: 100%;" placeholder="What did you change?" value=configNote}}
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+        <button {{action saveConfig view.saveMode}} type="button" class="btn btn-success" data-dismiss="modal">Save changes</button>
+      </div>
+    </div>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/schedulerPanel.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/schedulerPanel.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/schedulerPanel.hbs
index 0a52ffa..7333006 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/schedulerPanel.hbs
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/schedulerPanel.hbs
@@ -20,13 +20,15 @@
   <div class="panel-heading">
     <div class="panel-title">
       <strong>Scheduler</strong>
-      <a href="#" {{action 'toggleEditScheduler'}} class="text-right"> 
-        {{#if isEditScheduler}}
-                <div class="edit-link">Hide Edit</div>
-        {{else}}
-                <div class="edit-link">Show Edit</div>
-        {{/if}}
-      </a>
+      {{#if isOperator}}
+          <a href="#" {{action 'toggleEditScheduler'}} class="text-right">
+          {{#if isEditScheduler}}
+                  <div class="edit-link">Hide Edit</div>
+          {{else}}
+                  <div class="edit-link">Show Edit</div>
+          {{/if}}
+        </a>
+      {{/if}}
     </div>
   </div>
   <div class="panel-body">

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/app/views/queues.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/views/queues.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/views/queues.js
new file mode 100644
index 0000000..ca98e43
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/views/queues.js
@@ -0,0 +1,34 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+App.QueuesView = Em.View.extend({
+  actions:{
+    saveModal:function (mode) {
+      this.set('saveMode',mode);
+      this.$('#noteModal').modal('show');
+    }
+  },
+  saveMode:'',
+  clearSaveMode:function () {
+    $('#noteModal').on('hidden.bs.modal', function (e) {
+      this.set('saveMode','');
+    }.bind(this));
+  }.on('didInsertElement')
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/793c8a2c/contrib/views/capacity-scheduler/src/main/resources/ui/config.coffee
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/config.coffee b/contrib/views/capacity-scheduler/src/main/resources/ui/config.coffee
index 7bd9fa5..2fe3325 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/config.coffee
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/config.coffee
@@ -17,6 +17,11 @@
 
 exports.config = 
 
+  watcher:
+    usePolling: true
+
+  fileListInterval: 512
+
   files: 
     
     javascripts: 
@@ -58,15 +63,8 @@ exports.config =
   modules:
     addSourceURLs: true
 
-  paths:
-    public: '/usr/lib/ambari-server/web/views-debug/CAPACITY-SCHEDULER/0.1.0/CS_1/'
-
   overrides:
-    production:
-        paths:
-          public: 'public'
+    development:
+      paths:
+        public: '/usr/lib/ambari-server/web/views-debug/CAPACITY-SCHEDULER/0.2.0/CS_1/'
 
-  server:
-    port: 3333
-    base: '/'
-    run: no