ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dbhowm...@apache.org
Subject [2/2] ambari git commit: AMBARI-15384. CapSched View: Revamping the old UI. (Akhil PB via dipayanb)
Date Thu, 28 Apr 2016 11:12:53 GMT
AMBARI-15384. CapSched View:  Revamping the old UI. (Akhil PB via dipayanb)


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

Branch: refs/heads/trunk
Commit: 79489a8f35a6b808277a91251beae704aaad982f
Parents: ac731f7
Author: Dipayan Bhowmick <dipayan.bhowmick@gmail.com>
Authored: Thu Apr 28 16:42:33 2016 +0530
Committer: Dipayan Bhowmick <dipayan.bhowmick@gmail.com>
Committed: Thu Apr 28 16:42:33 2016 +0530

----------------------------------------------------------------------
 .../src/main/resources/ui/app/components.js     |   3 +
 .../ui/app/components/queueHierarchy.js         |  46 +++
 .../resources/ui/app/components/queueMapping.js | 141 ++++++++
 .../resources/ui/app/components/queueSummary.js |  52 +++
 .../src/main/resources/ui/app/controllers.js    |   5 +
 .../resources/ui/app/controllers/advanced.js    |  55 +++
 .../resources/ui/app/controllers/capsched.js    |  39 +++
 .../resources/ui/app/controllers/editqueue.js   | 333 +++++++++++++++++++
 .../resources/ui/app/controllers/queuesconf.js  | 141 ++++++++
 .../resources/ui/app/controllers/scheduler.js   |  83 +++++
 .../src/main/resources/ui/app/helpers.js        |  22 ++
 .../ui/app/helpers/queueMappingParser.js        |  34 ++
 .../main/resources/ui/app/helpers/uppercase.js  |  21 ++
 .../src/main/resources/ui/app/initialize.js     |   6 +-
 .../src/main/resources/ui/app/router.js         |  87 ++++-
 .../resources/ui/app/styles/application.less    | 285 ++++++++++++++++
 .../src/main/resources/ui/app/templates.js      |  13 +
 .../resources/ui/app/templates/capsched.hbs     |  44 +++
 .../ui/app/templates/capsched/advanced.hbs      |  32 ++
 .../capsched/partials/accessControlList.hbs     | 154 +++++++++
 .../capsched/partials/editQueueCapacity.hbs     |  51 +++
 .../capsched/partials/queueCapacity.hbs         |  95 ++++++
 .../capsched/partials/queueResources.hbs        | 216 ++++++++++++
 .../ui/app/templates/capsched/queuesconf.hbs    | 104 ++++++
 .../templates/capsched/queuesconf/editqueue.hbs |  47 +++
 .../ui/app/templates/capsched/scheduler.hbs     | 135 ++++++++
 .../app/templates/components/queueHierarchy.hbs |  41 +++
 .../app/templates/components/queueMapping.hbs   | 154 +++++++++
 .../app/templates/components/queueSummary.hbs   |  66 ++++
 .../ui/app/templates/versionsPanel.hbs          |  49 +++
 .../resources/ui/app/views/editQueueCapacity.js |  29 ++
 .../main/resources/ui/app/views/editqueue.js    |  50 +++
 .../main/resources/ui/app/views/queuesconf.js   |  27 ++
 33 files changed, 2657 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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 ac679b7..7f7bc3b 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
@@ -30,3 +30,6 @@ require('components/dropdownButtons');
 require('components/queueBadge');
 require('components/diffTooltip');
 require('components/tooltipLabel');
+require('components/queueMapping');
+require('components/queueHierarchy');
+require('components/queueSummary');

http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueHierarchy.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueHierarchy.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueHierarchy.js
new file mode 100644
index 0000000..64a28343
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueHierarchy.js
@@ -0,0 +1,46 @@
+/**
+ * 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.QueueHierarchyComponent = Ember.Component.extend({
+   layoutName: 'components/queueHierarchy',
+   depth:0,
+   parent:'',
+
+   leafQs: function () {
+     return this.get('queues')
+       .filterBy('depth', this.get('depth'))
+       .filterBy('parentPath', this.get('parent'));
+   }.property('depth', 'parent', 'queues.length', 'queues.@each.name'),
+
+   childDepth: function () {
+     return this.get('leafQs.firstObject.depth') + 1;
+   }.property('depth'),
+
+   didInsertElement: function () {
+     Ember.run.scheduleOnce('afterRender', null, this.setFirstAndLast, this);
+   },
+
+   setFirstAndLast: function (item) {
+     var items = item.$().parents('.queue-hierarchy').find('.list-group-item');
+     items.first().addClass('first');
+     items.last().addClass('last');
+   }
+
+ });

http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueMapping.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueMapping.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueMapping.js
new file mode 100644
index 0000000..02062a6
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueMapping.js
@@ -0,0 +1,141 @@
+/**
+ * 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.QueueMappingComponent = Em.Component.extend({
+   layoutName: 'components/queueMapping',
+
+   queues: null,
+   mappings: '',
+   mappingsOverrideEnable: false,
+
+   isShowing: false,
+   queueMappings: [],
+   leafQueueNames: [],
+   selectedMapping: '',
+   customUserMappings: '',
+   customGroupMappings: '',
+   selectedLeafQueueNameForUsers: null,
+   selectedLeafQueueNameForGroups: null,
+
+   actions: {
+     showMappingOptions: function(){
+       this.resetMappingOptions();
+       this.set('isShowing', true);
+     },
+     hideMappingOptions: function(){
+       this.set('isShowing', false);
+     },
+     addQueueMapping: function(){
+       this.addQueueMapping();
+     },
+     removeQueueMapping: function(qm){
+       this.get('queueMappings').removeObject(qm);
+     }
+   },
+
+   resetMappingOptions: function(){
+     this.set('selectedMapping', '');
+     this.set('customUserMappings', '');
+     this.set('customGroupMappings', '');
+   },
+
+   parseMappings: function(){
+     var mappings = this.get('mappings') || '';
+     this.set('queueMappings', mappings.split(',').filter(function(mapping){
+       return mapping !== "";
+     }) || []);
+   }.observes('mappings').on('init'),
+
+   extractLeafQueueNames: function(){
+     var that = this;
+     var queues = this.get('queues') || [];
+     var leafQs = queues.filterBy('queues', null);
+     leafQs.forEach(function(q){
+       that.get('leafQueueNames').pushObject(q.get('name'));
+     });
+   }.observes('queues.length').on('init'),
+
+   addQueueMapping: function(){
+     var that = this;
+     if(this.get('selectedMapping') !== ''){
+       if(this.get('selectedMapping') !== 'u:%name:%qname' && this.get('selectedMapping') !== 'g:%name:%qname'){
+         this.get('queueMappings').pushObject(this.get('selectedMapping'));
+       }else{
+         if(this.get('selectedMapping') === 'u:%name:%qname' && this.get('customUserMappings').trim() !== ''
+          && this.get('selectedLeafQueueNameForUsers') !== null){
+           this.addCustomQueueMappings(this.get('customUserMappings'), this.get('selectedLeafQueueNameForUsers'));
+         }else if(this.get('selectedMapping') === 'g:%name:%qname' && this.get('customGroupMappings').trim() !== ''
+          && this.get('selectedLeafQueueNameForGroups') !== null){
+           this.addCustomQueueMappings(this.get('customGroupMappings'), this.get('selectedLeafQueueNameForGroups'));
+         }
+       }
+       this.resetMappingOptions();
+     }
+   },
+
+   queueMappingsDidChange: function(){
+     var csMappings = this.get('queueMappings').join(',') || '';
+     this.set('mappings', csMappings);
+   }.observes('queueMappings', 'queueMappings.length', 'queueMappings.@each'),
+
+   addCustomQueueMappings: function(csValues, selectedLeafQName){
+     var that = this;
+     csValues = csValues.trim() || '',
+     userOrGroupNames = csValues.split(',') || [],
+     mappingPattern = this.get('selectedMapping');
+     userOrGroupNames.forEach(function(ugname){
+       that.get('queueMappings').pushObject(mappingPattern.replace('%name', ugname).replace('%qname', selectedLeafQName));
+     });
+   },
+
+   isCustomUserMapping: function(){
+     return this.get('selectedMapping').trim() === 'u:%name:%qname';
+   }.property('selectedMapping'),
+
+   isCustomGroupMapping: function(){
+     return this.get('selectedMapping').trim() === 'g:%name:%qname';
+   }.property('selectedMapping'),
+
+   radioButton: Em.View.extend({
+     tagName: 'input',
+     type: 'radio',
+     attributeBindings: ['type', 'name', 'value', 'checked:checked:'],
+     click: function(){
+       this.set("selection", this.$().val());
+     },
+     checked: function(){
+       return this.get("value") === this.get("selection");
+     }.property('selection')
+   }),
+
+   isCollapsed: true,
+   doExpandCollapse: function(){
+     var that = this;
+     this.$('#collapseQueueMappingsBtn').on('click', function(e){
+       Ember.run.next(that, function(){
+         this.toggleProperty('isCollapsed');
+       });
+     });
+   }.on('didInsertElement'),
+
+   destroyEventListeners: function() {
+     this.$('#collapseQueueMappingsBtn').off('click');
+   }.on('willDestroyElement')
+ });

http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueSummary.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueSummary.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueSummary.js
new file mode 100644
index 0000000..3d4f7be
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueSummary.js
@@ -0,0 +1,52 @@
+/**
+ * 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 _runState = 'RUNNING';
+ var _stopState = 'STOPPED';
+
+ App.QueueSummaryComponent = Ember.Component.extend({
+   layoutName: 'components/queueSummary',
+   queue: null,
+   allQueues: null,
+
+   isRunningState: function() {
+     return this.get('queue.state') === _runState || this.get('queue.state') === null;
+   }.property('queue.state'),
+
+   queueState: function() {
+     if (this.get('isRunningState')) {
+       return _runState;
+     } else {
+       return _stopState;
+     }
+   }.property('queue.state'),
+
+   effectiveCapacity: function() {
+     var currentQ = this.get('queue'),
+     allQueues = this.get('allQueues'),
+     effectiveCapacityRatio = 1;
+     while (currentQ !== null) {
+       effectiveCapacityRatio *= (currentQ.get('capacity') / 100);
+       currentQ = allQueues.findBy('id', currentQ.get('parentPath').toLowerCase()) || null;
+     }
+     var effectiveCapacityPercent = Math.round(effectiveCapacityRatio * 100);
+     return effectiveCapacityPercent;
+   }.property('queue.capacity', 'allQueues.@each.capacity', 'allQueues.length')
+ });

http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers.js
index 16b7d0a..5cd31ed 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers.js
@@ -20,3 +20,8 @@ require('controllers/queue');
 require('controllers/queues');
 require('controllers/trace');
 require('controllers/configs');
+require('controllers/capsched');
+require('controllers/advanced');
+require('controllers/scheduler');
+require('controllers/queuesconf');
+require('controllers/editqueue');

http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/advanced.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/advanced.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/advanced.js
new file mode 100644
index 0000000..7af45bb
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/advanced.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');
+
+var cmp = Ember.computed;
+
+App.CapschedAdvancedController = Ember.Controller.extend({
+  needs: ['capsched'],
+
+  actions: {
+    rollbackQueueMappingProps: function() {
+      var sched = this.get('scheduler'),
+      attributes = sched.changedAttributes(),
+      props = this.queueMappingProps;
+      props.forEach(function(prop) {
+        if (attributes.hasOwnProperty(prop)) {
+          sched.set(prop, attributes[prop][0]);
+        }
+      });
+    }
+  },
+
+  isOperator: cmp.alias('controllers.capsched.isOperator'),
+  scheduler: cmp.alias('controllers.capsched.content'),
+  queues: cmp.alias('controllers.capsched.queues'),
+  isQueueMappingsDirty: false,
+  queueMappingProps: ['queue_mappings', 'queue_mappings_override_enable'],
+
+  queueMappingsDidChange: function() {
+    var sched = this.get('scheduler'),
+    attributes = sched.changedAttributes(),
+    props = this.queueMappingProps;
+    var isDirty = props.any(function(prop){
+      return attributes.hasOwnProperty(prop);
+    });
+    this.set('isQueueMappingsDirty', isDirty);
+  }.observes('scheduler.queue_mappings', 'scheduler.queue_mappings_override_enable')
+
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/capsched.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/capsched.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/capsched.js
new file mode 100644
index 0000000..1ee7a6b
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/capsched.js
@@ -0,0 +1,39 @@
+/**
+ * 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 cmp = Ember.computed;
+
+App.CapschedController = Ember.Controller.extend({
+  actions: {
+
+  },
+
+  /**
+   * User admin status.
+   * @type {Boolean}
+   */
+  isOperator: false,
+
+  /**
+   * Inverted isOperator value.
+   * @type {Boolean}
+   */
+  isNotOperator: cmp.not('isOperator')
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/editqueue.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/editqueue.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/editqueue.js
new file mode 100644
index 0000000..69be18c
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/editqueue.js
@@ -0,0 +1,333 @@
+/**
+ * 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 _runState = 'RUNNING';
+var _stopState = 'STOPPED';
+
+App.CapschedQueuesconfEditqueueController = Ember.Controller.extend({
+  needs: ['capsched'],
+  isOperator: Ember.computed.alias('controllers.capsched.isOperator'),
+  isNotOperator: Ember.computed.not('isOperator'),
+  scheduler: Ember.computed.alias('controllers.capsched.content'),
+  allQueues: Ember.computed.alias('controllers.capsched.queues'),
+
+  isRangerEnabledForYarn: function() {
+    var isRanger = this.get('controllers.capsched.isRangerEnabledForYarn');
+    if (isRanger == null || typeof isRanger == 'undefined') {
+      return false;
+    }
+    isRanger = isRanger.toLowerCase();
+    if (isRanger == 'yes' || isRanger == 'true') {
+      return true;
+    }
+    return false;
+  }.property('controllers.capsched.isRangerEnabledForYarn'),
+
+  actions: {
+    toggleProperty: function (property, target) {
+      target = target || this;
+      target.toggleProperty(property);
+    },
+    mouseUp: function(){
+      return false;
+    }
+  },
+
+  /**
+   * Collection of modified fields in queue.
+   * @type {Object} - { [fileldName] : {Boolean} }
+   */
+  queueDirtyFields: {},
+
+  isQueueDirty: Ember.computed.bool('content.isDirty'),
+
+  /**
+   * Possible values for ordering policy
+   * @type {Array}
+   */
+  orderingPolicyValues: [
+    {label: 'FIFO', value: 'fifo'},
+    {label: 'Fair', value: 'fair'}
+  ],
+
+  /**
+   * Returns true if queue is root.
+   * @type {Boolean}
+   */
+   isRoot: Ember.computed.match('content.id', /^(root)$/),
+
+   /**
+    * Returns true if queue is default.
+    * @type {Boolean}
+    */
+   isDefaultQ: Ember.computed.match('content.id', /^(root.default)$/),
+
+   /**
+    * Represents queue run state. Returns true if state is null.
+    * @return {Boolean}
+    */
+   isRunning: function() {
+     return this.get('content.state') == _runState || this.get('content.state') == null;
+   }.property('content.state'),
+
+   /**
+    * Current ordering policy value of queue.
+    * @param  {String} key
+    * @param  {String} value
+    * @return {String}
+    */
+   currentOP: function (key, val) {
+     if (arguments.length > 1) {
+       if (!this.get('isFairOP')) {
+         this.send('rollbackProp', 'enable_size_based_weight', this.get('content'));
+       }
+       this.set('content.ordering_policy', val || null);
+     }
+     return this.get('content.ordering_policy') || 'fifo';
+   }.property('content.ordering_policy'),
+
+   /**
+    * Does ordering policy is equal to 'fair'
+    * @type {Boolean}
+    */
+   isFairOP: Ember.computed.equal('content.ordering_policy', 'fair'),
+
+   /**
+    * Returns maximum applications for a queue if defined,
+    * else the inherited value (for all queues)
+    */
+   maximumApplications: function(key, val) {
+     if (arguments.length > 1) {
+       if (val !== this.get('scheduler.maximum_applications')) {
+         this.set('content.maximum_applications', val);
+       } else {
+         this.set('content.maximum_applications', null);
+       }
+     }
+     return this.get('content.maximum_applications') || this.get('scheduler.maximum_applications');
+   }.property('content.maximum_applications', 'scheduler.maximum_applications'),
+
+   /**
+    * Returns maximum AM resource percent for a queue if defined,
+    * else the inherited value (for all queues)
+    */
+   maximumAMResourcePercent: function(key, val) {
+     if (arguments.length > 1) {
+       if (val !== this.get('scheduler.maximum_am_resource_percent')) {
+         this.set('content.maximum_am_resource_percent', val);
+       } else {
+         this.set('content.maximum_am_resource_percent', null);
+       }
+     }
+     return this.get('content.maximum_am_resource_percent') || this.get('scheduler.maximum_am_resource_percent');
+   }.property('content.maximum_am_resource_percent', 'scheduler.maximum_am_resource_percent'),
+
+   /**
+    * Sets ACL value to '*' or ' ' and returns '*' and 'custom' respectively.
+    * @param  {String} key   - ACL attribute
+    * @param  {String} value - ACL value
+    * @return {String}
+    */
+   handleAcl: function (key, value) {
+     if (value) {
+       this.set(key, (value === '*')? '*' : ' ');
+     }
+     return (this.get(key) === '*' || this.get(key) == null) ? '*' : 'custom';
+   },
+
+   /**
+    * Queue's acl_administer_queue property can be set to '*' (everyone) or ' ' (nobody) thru this property.
+    *
+    * @param  {String} key
+    * @param  {String} value
+    * @return {String} - '*' if equal to '*' or 'custom' in other case.
+    */
+   acl_administer_queue: function (key, value) {
+     return this.handleAcl('content.acl_administer_queue', value);
+   }.property('content.acl_administer_queue'),
+
+   /**
+    * Returns true if acl_administer_queue is set to '*'
+    * @type {Boolean}
+    */
+   aaq_anyone: Ember.computed.equal('acl_administer_queue', '*'),
+
+   /**
+    * Returns effective permission of the current queue to perform administrative functions on this queue.
+    */
+    aaq_effective_permission: function(key, value){
+      return this.getEffectivePermission('acl_administer_queue');
+    }.property('content.acl_administer_queue'),
+
+    /**
+     * Queue's acl_submit_applications property can be set to '*' (everyone) or ' ' (nobody) thru this property.
+     *
+     * @param  {String} key
+     * @param  {String} value
+     * @return {String} - '*' if equal to '*' or 'custom' in other case.
+     */
+    acl_submit_applications: function (key, value) {
+      return this.handleAcl('content.acl_submit_applications', value);
+    }.property('content.acl_submit_applications'),
+
+    /**
+     * Returns true if acl_submit_applications is set to '*'
+     * @type {Boolean}
+     */
+    asa_anyone:Ember.computed.equal('acl_submit_applications', '*'),
+
+    /**
+     * Returns effective permission of the current queue to submit application.
+     */
+    asa_effective_permission: function(key, value){
+      return this.getEffectivePermission('acl_submit_applications');
+    }.property('content.acl_submit_applications'),
+
+    /**
+     * Returns effective permission of the current queue.
+     */
+    getEffectivePermission: function(permissionType){
+      var effectivePermission,
+      users = [],
+      groups = [],
+      currentPermissions = this.getPermissions(permissionType);
+      for(var i = 0; i < currentPermissions.length; i++){
+        var permission = currentPermissions[i];
+        if (permission === '*') {
+          return '*';
+        } else if (permission.trim() === '') {
+          effectivePermission = '';
+        } else {
+          var usersAndGroups = permission.split(' ');
+          this.fillUsersAndGroups(users, usersAndGroups[0]);
+          if (usersAndGroups.length === 2) {
+            this.fillUsersAndGroups(groups, usersAndGroups[1]);
+          }
+        }
+      }
+      if(users.length > 0 || groups.length > 0){
+        effectivePermission = users.join(',') + ' ' + groups.join(',');
+      }
+      return effectivePermission;
+    },
+
+    /**
+     * Removes duplicate users or groups.
+     */
+    fillUsersAndGroups: function(usersOrGroups, list){
+      var splitted = list.split(',');
+      splitted.forEach(function(item){
+        if(usersOrGroups.indexOf(item) === -1){
+          usersOrGroups.push(item);
+        }
+      });
+    },
+
+    /**
+     * Returns array of permissions from root to leaf.
+     */
+    getPermissions: function(permissionType){
+      var currentQ = this.get('content'),
+      permissions = [];
+      while (currentQ !== null) {
+        if (currentQ.get(permissionType) !== null) {
+          permissions.push(currentQ.get(permissionType));
+        } else {
+          permissions.push('*');
+        }
+        currentQ = this.store.getById('queue', currentQ.get('parentPath').toLowerCase());
+      }
+      permissions.reverse();//root permission at the 0th position.
+      return permissions;
+    },
+
+    /**
+     * Array of leaf queues.
+     * @return {Array}
+     */
+    childrenQueues: function () {
+      return this.get('allQueues')
+        .filterBy('depth', this.get('content.depth') + 1)
+        .filterBy('parentPath', this.get('content.path'));
+    }.property('allQueues.length', 'content.path', 'content.parentPath'),
+
+    /**
+     * Parent of current queue.
+     * @return {App.Queue}
+     */
+    parentQueue: function () {
+      return this.store.getById('queue', this.get('content.parentPath').toLowerCase());
+    }.property('content.parentPath'),
+
+    /*
+     * Returns true if the current queue is a leaf queue
+     */
+    isLeafQ: function() {
+      return this.get('content.queues') == null;
+    }.property('allQueues.length', 'content.queues'),
+
+    childrenQueuesTotalCapacity: function() {
+      var childrenQs = this.get('childrenQueues'),
+      totalCapacity = 0;
+      childrenQs.forEach(function(currentQ){
+        totalCapacity += currentQ.get('capacity');
+      });
+      return totalCapacity;
+    }.property('childrenQueues.length', 'childrenQueues.@each.capacity'),
+
+    pattern: 'width: %@%',
+
+    warnInvalidCapacity: function() {
+      var totalCap = this.get('childrenQueuesTotalCapacity');
+      if (totalCap > 100 || totalCap < 100) {
+        return true;
+      }
+      return false;
+    }.property('childrenQueuesTotalCapacity'),
+
+    totalCapacityBarWidth: function() {
+      var totalCap = this.get('childrenQueuesTotalCapacity');
+      if (totalCap > 100) {
+        totalCap = 100;
+      }
+      return this.get('pattern').fmt(totalCap);
+    }.property('childrenQueuesTotalCapacity'),
+
+   /**
+    * Adds observers for each queue attribute.
+    * @method dirtyObserver
+    */
+   dirtyObserver: function () {
+     this.get('content.constructor.transformedAttributes.keys.list').forEach(function(item) {
+       this.addObserver('content.' + item, this, 'propertyBecomeDirty');
+     }.bind(this));
+   }.observes('content'),
+
+   /**
+    * Adds modified queue fileds to q queueDirtyFields collection.
+    * @param  {String} controller
+    * @param  {String} property
+    * @method propertyBecomeDirty
+    */
+   propertyBecomeDirty: function (controller, property) {
+     var queueProp = property.split('.').objectAt(1);
+     this.set('queueDirtyFields.' + queueProp, this.get('content').changedAttributes().hasOwnProperty(queueProp));
+   }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queuesconf.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queuesconf.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queuesconf.js
new file mode 100644
index 0000000..0f4d038
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queuesconf.js
@@ -0,0 +1,141 @@
+/**
+ * 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 _runState = 'RUNNING';
+var _stopState = 'STOPPED';
+
+App.CapschedQueuesconfController = Ember.Controller.extend({
+  needs: ['capsched', 'loading'],
+  queues: Ember.computed.alias('controllers.capsched.queues'),
+  isOperator: Ember.computed.alias('controllers.capsched.isOperator'),
+
+  actions: {
+    addNewQueue: function() {
+      this.set('newQueueName', '');
+      this.set('showQueueNameInput', true);
+    },
+    createNewQueue: function() {
+      var store = this.get('store'),
+      queueName = this.get('newQueueName'),
+      parentPath = this.get('selectedQueue.path'),
+      queuePath = parentPath + "." + queueName,
+      depth = parentPath.split('.').length,
+      leafQueueNames = store.getById('queue', parentPath.toLowerCase()).get('queuesArray'),
+      newInLeaf = Em.isEmpty(leafQueueNames),
+      existed = store.get('deletedQueues').findBy('path', [parentPath, queueName].join('.')),
+      totalLeafCapacity,
+      freeLeafCapacity,
+      newQueue;
+
+      this.send('cancelCreateQueue');
+
+      if (existed) {
+        newQueue = store.createFromDeleted(existed);
+      } else {
+        if (!newInLeaf) {
+          totalLeafCapacity = leafQueueNames.reduce(function (capacity, qName) {
+            return store.getById('queue', [parentPath, qName].join('.').toLowerCase()).get('capacity') + capacity;
+          }, 0);
+
+          freeLeafCapacity = (totalLeafCapacity < 100) ? 100 - totalLeafCapacity : 0;
+        }
+        var qCapacity = (newInLeaf) ? 100 : freeLeafCapacity;
+
+        newQueue = store.createRecord('queue', {
+          id: queuePath,
+          name: queueName,
+          path: queuePath,
+          parentPath: parentPath,
+          depth: depth,
+          isNewQueue: true,
+          capacity: qCapacity,
+          maximum_capacity: qCapacity
+        });
+
+        this.set('newQueue', newQueue);
+      }
+
+      store.saveAndUpdateQueue(newQueue).then(function() {
+        Em.run.bind(this, 'set', 'newQueue', null);
+      }).catch(Em.run.bind(this, 'saveQueuesConfigError', 'createQueue'));
+    },
+    saveQueuesConfig: function() {
+      var store = this.get('store'),
+      opt = 'saveAndRefresh',
+      saveQs = this.get('queues').save();
+
+      Ember.RSVP.Promise.all([saveQs]).then(
+        Em.run.bind(this, 'saveQueuesConfigSuccess'),
+        Em.run.bind(this, 'saveQueuesConfigError', opt)
+      ).then(function() {
+        return store.relaunchCapSched(opt);
+      }).catch(Em.run.bind(this, 'saveQueuesConfigError', opt));
+
+    },
+    cancelCreateQueue: function() {
+      this.set('newQueueName', '');
+      this.set('showQueueNameInput', false);
+    },
+    clearAlert:function () {
+      this.set('alertMessage', null);
+    }
+  },
+
+  selectedQueue: null,
+  newQueue: null,
+  newQueueName: '',
+  showQueueNameInput: false,
+
+  /**
+   * True if newQueue is not empty.
+   * @type {Boolean}
+   */
+  hasNewQueue: Ember.computed.bool('newQueue'),
+
+  /**
+   * Represents queue run state. Returns true if state is null.
+   * @return {Boolean}
+   */
+  isSelectedQRunning: function() {
+    return this.get('selectedQueue.state') == _runState || this.get('selectedQueue.state') == null;
+  }.property('selectedQueue.state'),
+
+  /**
+   * Returns true if queue is root.
+   * @type {Boolean}
+   */
+   isRootQSelected: Ember.computed.match('selectedQueue.id', /^(root)$/),
+
+   /**
+    * Property for error message which may appear when saving queue.
+    * @type {Object}
+    */
+   alertMessage: null,
+
+   configNote: Ember.computed.alias('store.configNote'),
+
+   saveQueuesConfigSuccess: function() {
+     this.set('store.deletedQueues', []);
+   },
+   saveQueuesConfigError: function(operation, error) {
+     var response = (error && error.responseJSON)? error.responseJSON : {};
+     response.simpleMessage = operation.capitalize() + ' failed!';
+     this.set('alertMessage', response);
+   }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/scheduler.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/scheduler.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/scheduler.js
new file mode 100644
index 0000000..c0c56b6
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/scheduler.js
@@ -0,0 +1,83 @@
+/**
+ * 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 cmp = Ember.computed;
+
+App.CapschedSchedulerController = Ember.Controller.extend({
+  needs: ['capsched'],
+  schedulerProps: ['maximum_am_resource_percent', 'maximum_applications', 'node_locality_delay', 'resource_calculator'],
+
+  actions: {
+    rollbackSchedulerProps: function() {
+      var sched = this.get('scheduler'),
+      attributes = sched.changedAttributes(),
+      props = this.schedulerProps;
+      props.forEach(function(prop) {
+        if (attributes.hasOwnProperty(prop)) {
+          sched.set(prop, attributes[prop][0]);
+        }
+      });
+    }
+  },
+
+  isOperator: cmp.alias('controllers.capsched.isOperator'),
+
+  /**
+   * Scheduler record
+   * @type {App.Scheduler}
+   */
+  scheduler: cmp.alias('controllers.capsched.content'),
+  isSchedulerDirty: false,
+
+  schedulerBecomeDirty: function() {
+    var sched = this.get('scheduler'),
+    attributes = sched.changedAttributes(),
+    props = this.schedulerProps;
+    var isDirty = props.any(function(prop){
+      return attributes.hasOwnProperty(prop);
+    });
+    this.set('isSchedulerDirty', isDirty);
+  }.observes('scheduler.maximum_am_resource_percent', 'scheduler.maximum_applications', 'scheduler.node_locality_delay', 'scheduler.resource_calculator'),
+
+  /**
+   * Collection of modified fields in Scheduler.
+   * @type {Object} - { [fileldName] : {Boolean} }
+   */
+  schedulerDirtyFilelds: {},
+
+  dirtyObserver:function () {
+    this.get('scheduler.constructor.transformedAttributes.keys.list').forEach(function(item) {
+      this.addObserver('scheduler.' + item, this, 'propertyBecomeDirty');
+    }.bind(this));
+  }.observes('scheduler').on('init'),
+
+  propertyBecomeDirty:function (controller, property) {
+    var schedProp = property.split('.').objectAt(1);
+    this.set('schedulerDirtyFilelds.' + schedProp, this.get('scheduler').changedAttributes().hasOwnProperty(schedProp));
+  },
+
+  resourceCalculatorValues: [{
+    label: 'Default Resource Calculator',
+    value: 'org.apache.hadoop.yarn.util.resource.DefaultResourceCalculator'
+  }, {
+    label: 'Dominant Resource Calculator',
+    value: 'org.apache.hadoop.yarn.util.resource.DominantResourceCalculator'
+  }]
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers.js
new file mode 100644
index 0000000..95f301d
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers.js
@@ -0,0 +1,22 @@
+/**
+ * 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.
+ */
+
+require('helpers/timeAgo');
+require('helpers/escapeAcl');
+require('helpers/queueMappingParser');
+require('helpers/uppercase');

http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers/queueMappingParser.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers/queueMappingParser.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers/queueMappingParser.js
new file mode 100644
index 0000000..319b3bc
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers/queueMappingParser.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.
+ */
+
+ Ember.Handlebars.helper('queueMappingParser', function(mapping){
+   var output = '';
+   var parts = mapping.split(':');
+   if(parts[0] === 'u'){
+     if(parts[1] === '%user' && parts[2] === '%user'){
+       output = 'User %user -> queue %user';
+     }else if(parts[1] === '%user' && parts[2] === '%primary_group'){
+       output = 'User %user -> queue %primary_group';
+     }else{
+       output = 'User ' + parts[1] + ' -> queue ' + parts[2];
+     }
+   }else if(parts[0] === 'g'){
+     output = 'Group ' + parts[1] + ' -> queue ' + parts[2];
+   }
+   return output;
+ });

http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers/uppercase.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers/uppercase.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers/uppercase.js
new file mode 100644
index 0000000..222af54
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/helpers/uppercase.js
@@ -0,0 +1,21 @@
+/**
+ * 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.
+ */
+
+ Ember.Handlebars.helper('uppercase', function(value) {
+   return value.toUpperCase();
+ });

http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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 05bb64c..3dfe363 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
@@ -31,8 +31,7 @@ require('serializers');
 require('store');
 
 //helpers
-require('helpers/timeAgo');
-require('helpers/escapeAcl');
+require('helpers');
 
 //components
 require('components');
@@ -48,6 +47,9 @@ require('models');
 
 //views
 require('views/queues');
+require('views/editqueue');
+require('views/editQueueCapacity');
+require('views/queuesconf');
 
 // routes
 require('router');

http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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 a2d50b9..a32e02c 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
@@ -23,6 +23,14 @@ App.Router.map(function() {
     this.resource('queue', { path: '/:queue_id' });
     this.resource('trace', { path: '/log' });
   });
+  this.resource('capsched', {path: '/capacity-scheduler'}, function() {
+    this.route('scheduler', {path: '/scheduler'});
+    this.route('advanced', {path: '/advanced'});
+    this.route('trace', {path: '/log'});
+    this.route('queuesconf', {path: '/queues'}, function() {
+      this.route('editqueue', {path: '/:queue_id'});
+    });
+  });
   this.route('refuse');
 });
 
@@ -63,7 +71,6 @@ App.QueuesRoute = Ember.Route.extend({
         return store.findQuery( 'config', {siteName : RANGER_SITE, configName : RANGER_YARN_ENABLED}).then(function(){
           return store.find( 'config', "siteName_" + RANGER_SITE + "_configName_" + RANGER_YARN_ENABLED)
               .then(function(data){
-                console.log("router.queuesRoute : data.configValue isRangerEnabled : " + data.get('configValue'));
                 _this.controllerFor('configs').set('isRangerEnabledForYarn', data.get('configValue'));
               });
         })
@@ -189,3 +196,81 @@ App.ErrorRoute = Ember.Route.extend({
   }
 });
 
+App.CapschedRoute = Ember.Route.extend({
+  actions: {
+    rollbackProp: function(prop, item) {
+      var attributes = item.changedAttributes();
+      if (attributes.hasOwnProperty(prop)) {
+        item.set(prop, attributes[prop][0]);
+      }
+    }
+  },
+  beforeModel: function(transition) {
+    var controller = this.container.lookup('controller:loading') || this.generateController('loading');
+    controller.set('model', {
+      message: 'cluster check'
+    });
+    return this.get('store').checkCluster().catch(Em.run.bind(this, 'loadingError', transition));
+  },
+  model: function() {
+    var store = this.get('store'),
+      _this = this,
+      controller = this.controllerFor("capsched"),
+      loadingController = this.container.lookup('controller:loading');
+
+    return new Ember.RSVP.Promise(function(resolve, reject) {
+      loadingController.set('model', {
+        message: 'access check'
+      });
+      store.checkOperator().then(function(isOperator) {
+        controller.set('isOperator', isOperator);
+        loadingController.set('model', {
+          message: 'loading node labels'
+        });
+        return store.get('nodeLabels');
+      }).then(function() {
+        return store.findQuery('config', {
+          siteName: RANGER_SITE,
+          configName: RANGER_YARN_ENABLED
+        }).then(function() {
+          return store.find('config', "siteName_" + RANGER_SITE + "_configName_" + RANGER_YARN_ENABLED)
+            .then(function(data) {
+              controller.set('isRangerEnabledForYarn', data.get('configValue'));
+            });
+        });
+      }).then(function() {
+        loadingController.set('model', {
+          message: 'loading queues'
+        });
+        return store.find('queue');
+      }).then(function(queues) {
+        controller.set('queues', queues);
+        return store.find('scheduler', 'scheduler');
+      }).then(function(scheduler){
+        resolve(scheduler);
+      }).catch(function(e) {
+        reject(e);
+      });
+    }, 'App: CapschedRoute#model');
+  }
+});
+
+App.CapschedIndexRoute = Ember.Route.extend({
+  redirect: function() {
+    this.transitionTo('capsched.scheduler');
+  }
+});
+
+App.CapschedQueuesconfIndexRoute = Ember.Route.extend({
+  beforeModel: function(transition) {
+    var rootQ = this.store.getById('queue', 'root');
+    this.transitionTo('capsched.queuesconf.editqueue', rootQ);
+  }
+});
+
+App.CapschedQueuesconfEditqueueRoute = Ember.Route.extend({
+  setupController: function(controller, model) {
+    controller.set('model', model);
+    this.controllerFor('capsched.queuesconf').set('selectedQueue', model);
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/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 be79229..a60d39d 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
@@ -880,3 +880,288 @@
 .tooltip-label span:first-child {
   cursor: help;
 }
+
+.panel-queue-mapping {
+  .queue-mapping-options {
+    padding: 10px;
+    border: 1px solid #ddd;
+    border-radius: 4px;
+    margin-left: -15px;
+    margin-right: -15px;
+    .row {
+      margin: 0px;
+    }
+  }
+  .list-group {
+    .list-group-item {
+      margin-bottom: 3px;
+      background-color: #f5f5f5;
+      border-radius: 4px;
+      padding: 5px 15px;
+    }
+  }
+  .remove-mapping-icon {
+    cursor: pointer;
+    &:hover {
+      color: #d9534f;
+    }
+  }
+}
+
+.scheduler-panel {
+  .input-control {
+    width: 75%;
+    display: inline-block;
+  }
+  .input-resource-percent {
+    width: 75%;
+    float: left;
+  }
+  .rollback-resource-percent {
+    margin: 4px;
+  }
+  .resource-calc-control {
+    width: 88%;
+    display: inline-block;
+  }
+}
+
+.queue-config-container {
+  .queue-actions-wrapper {
+    .btn {
+      padding: 1px 5px;
+    }
+  }
+  .add-newqueuename-wrapper {
+    padding-top: 30px;
+    .new-queue-name {
+      width: 100%;
+      display: inline-block;
+    }
+  }
+  hr {
+    margin-top: 5px;
+    margin-bottom: 10px;
+  }
+  .queue-hierarchy.list-group {
+    margin-bottom: 5px;
+    .list-group-item {
+      border: 1px solid #efefef;
+      padding: 5px 10px;
+      &.first {
+        border-top-left-radius: 4px;
+        border-top-right-radius: 4px;
+      }
+      &.last {
+        border-bottom-left-radius: 4px;
+        border-bottom-right-radius: 4px;
+      }
+      .badge {
+        background-color: #fff;
+        padding: 2px 3px;
+      }
+    }
+  }
+}
+
+.queue-resources-container {
+  .input-width-control {
+    width: 75%;
+    display: inline-block;
+  }
+  .input-percent-wrap {
+    .input-percent {
+      width: 75%;
+      float: left;
+    }
+    .btn-group.btn-group-xs {
+      margin: 4px;
+    }
+  }
+  .input-toggle-wrap {
+    .btn-group.btn-group-sm {
+      width: 20px;
+      .btn.btn-default {
+        width: 20px;
+        padding: 0;
+        border: none;
+        margin: 0;
+        &:hover, &:active, &:focus {
+          background-color: #fff;
+        }
+        .fa {
+          font-size: 18px
+        }
+        .fa-square-o {
+          margin-left: -6px;
+        }
+        .fa-check-square-o {
+          margin-left: -4px;
+        }
+      }
+    }
+  }
+  .inherited-value {
+    margin: 4px 0px 4px -40px;
+  }
+}
+
+.queue-acl-container {
+  .user-group-input {
+    .col-sm-4 {
+      padding: 15px;
+    }
+    .col-sm-8 {
+      width: 35%;
+      padding: 10px;
+    }
+    .fa-user,.fa-users {
+      top: 8px;
+      right: 7px;
+      opacity: 0.4;
+    }
+    .help-block {
+      float: left !important;
+    }
+  }
+}
+
+.capsched-container {
+  .nav-tabs {
+    border-bottom: none;
+  }
+  .panel-heading {
+    padding: 4px 14px;
+    .panel-title {
+      font-size: 14px;
+    }
+  }
+  .input-group-addon {
+    padding: 7px 6px;
+    width: 26px;
+  }
+}
+
+.queue-summary {
+  .panel-default {
+    border-color: #f5f5f5;
+  }
+}
+
+.queue-capacity-container {
+  .form-inline {
+    margin-bottom: 20px;
+    .queue-name {
+      margin-top: 5px;
+    }
+    .capacity-input-percent {
+      width: 30%;
+      float: left;
+      display: inline-block;
+      input {
+        width: 60%;
+      }
+    }
+    .capacity-input-slider {
+      width: 60%;
+      display: inline-block;
+    }
+  }
+  .progress {
+    display: inline-block;
+    vertical-align: middle;
+    margin-bottom: 0;
+    .progress-bar {
+      color: #000;
+    }
+  }
+  .total-capacity-progress {
+    width: 100%;
+  }
+  input[type=range] {
+    -webkit-appearance: none;
+    width: 100%;
+    background-color: #fefefe;
+    &:focus {
+      outline: none;
+    }
+    &::-webkit-slider-runnable-track {
+      width: 100%;
+      height: 2px;
+      cursor: pointer;
+      background: #555;
+      border-radius: 1.3px;
+      border: 0.2px solid #010101;
+      &:focus {
+        background: #555;
+      }
+    }
+    &::-webkit-slider-thumb {
+      border: 1.8px solid #00001e;
+      height: 15px;
+      width: 20px;
+      border-radius: 15px;
+      background: #ffffff;
+      cursor: pointer;
+      -webkit-appearance: none;
+      margin-top: -7px;
+    }
+    &::-moz-range-track {
+      width: 100%;
+      height: 2px;
+      cursor: pointer;
+      background: #555;
+      border-radius: 1.3px;
+      border: 0.2px solid #010101;
+    }
+    &::-moz-range-thumb {
+      border: 1.8px solid #00001e;
+      height: 15px;
+      width: 20px;
+      border-radius: 15px;
+      background: #ffffff;
+      cursor: pointer;
+    }
+    &::-ms-track {
+      width: 100%;
+      height: 2px;
+      cursor: pointer;
+      background: transparent;
+      border-color: transparent;
+      color: transparent;
+    }
+    &::-ms-thumb {
+      border: 1.8px solid #00001e;
+      width: 20px;
+      border-radius: 15px;
+      background: #ffffff;
+      cursor: pointer;
+      height: 11.4px;
+    }
+    &::-ms-fill-lower {
+      background: rgba(42, 100, 149, 0.78);
+      border: 0.2px solid #010101;
+      border-radius: 2.6px;
+      &:focus {
+        background: #555;
+      }
+    }
+    &::-ms-fill-upper {
+      background: #555;
+      border: 0.2px solid #010101;
+      border-radius: 2.6px;
+      &:focus {
+        background: #555;
+      }
+    }
+  }
+}
+
+.edit-queuename-wrapper {
+  margin-top: 10px;
+  margin-bottom: 20px;
+  .input-queue-name {
+    width: 69%;
+    display: inline-block;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates.js
index 25e2aa9..17b279a 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates.js
@@ -39,3 +39,16 @@ require('templates/components/queueContainer');
 require('templates/components/dropdownConfirmation');
 require('templates/components/dropdownDownload');
 require('templates/components/queueBadge');
+require('templates/components/queueMapping');
+require('templates/capsched');
+require('templates/capsched/scheduler');
+require('templates/capsched/advanced');
+require('templates/capsched/queuesconf');
+require('templates/versionsPanel');
+require('templates/components/queueHierarchy');
+require('templates/capsched/queuesconf/editqueue');
+require('templates/components/queueSummary');
+require('templates/capsched/partials/queueResources');
+require('templates/capsched/partials/accessControlList');
+require('templates/capsched/partials/queueCapacity');
+require('templates/capsched/partials/editQueueCapacity');

http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched.hbs
new file mode 100644
index 0000000..1eead4b
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched.hbs
@@ -0,0 +1,44 @@
+{{!
+* 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.
+}}
+
+<nav class="navbar navbar-default navbar-static-top">
+  <div class="navbar-header">
+    <span class="navbar-brand">Capacity Scheduler</span>
+  </div>
+</nav>
+<div class="col-lg-12 capsched-container">
+  <div class="col-lg-8">
+    <ul class="nav nav-tabs">
+      {{#link-to "capsched.scheduler" tagName="li"}}
+        <a href="#">Scheduler</a>
+      {{/link-to}}
+      {{#link-to "capsched.queuesconf" tagName="li"}}
+        <a href="#">Queues</a>
+      {{/link-to}}
+      {{#link-to "capsched.advanced" tagName="li"}}
+        <a href="#">Advanced</a>
+      {{/link-to}}
+    </ul>
+    <div class="tab-content">
+      {{outlet}}
+    </div>
+  </div>
+  <div class="col-lg-4">
+    {{partial "versionsPanel"}}
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/advanced.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/advanced.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/advanced.hbs
new file mode 100644
index 0000000..e54e14b
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/advanced.hbs
@@ -0,0 +1,32 @@
+{{!
+* 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.
+}}
+
+<div class="capshed-advanced-container">
+  {{!-- QUEUE MAPPING --}}
+  {{#if isOperator}}
+    <div class="hidden-sm hidden-xs">
+      {{queue-mapping mappings=scheduler.queue_mappings mappingsOverrideEnable=scheduler.queue_mappings_override_enable queues=queues}}
+    </div>
+  {{/if}}
+</div>
+<div class="row">
+  <div class="btn btn-group-md col-md-offset-5">
+    <button type="button" {{bind-attr class=":btn :btn-default :btn-success isQueueMappingsDirty::disabled"}} name="saveAdvanced">Save</button>
+    <button type="button" {{bind-attr class=":btn :btn-default :btn-danger isQueueMappingsDirty::disabled"}} name="cancelAdvanced" {{action "rollbackQueueMappingProps"}}>Cancel</button>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/accessControlList.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/accessControlList.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/accessControlList.hbs
new file mode 100644
index 0000000..1f6fbda
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/accessControlList.hbs
@@ -0,0 +1,154 @@
+{{!
+* 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.
+}}
+
+<div class="queue-acl-container">
+  <div class="panel panel-default">
+    <div class="panel-heading">
+      <div class="panel-title">
+        Access Control List <a id="collapseQueueAclPanelBtn" href="#collapsibleQueueAclPanel" data-toggle="collapse" {{bind-attr class=":pull-right view.isAclPanelCollapsed:collapsed"}}><i {{bind-attr class=":fa view.isAclPanelCollapsed:fa-plus:fa-minus"}}></i></a>
+      </div>
+    </div>
+    <div id="collapsibleQueueAclPanel" {{bind-attr class=":panel-collapse :collapse view.isAclPanelCollapsed::in"}}>
+      <div class="panel-body">
+        {{#unless isRangerEnabledForYarn}}
+          {{#if isOperator}}
+            <div class="row form-group">
+              {{tooltip-label
+                class="col-sm-4 col-md-4 control-label"
+                label='Administer Queue'
+                message='The access control list of users and groups that have authorization to perform administrative functions on this queue.'
+              }}
+              <div class="col-md-6 col-sm-6 control-value">
+                <div class="btn-group btn-group-xs" data-toggle="buttons">
+                  {{radio-button label="Anyone" selectionBinding="acl_administer_queue" value="*"}}
+                  {{radio-button label="Custom" selectionBinding="acl_administer_queue" value="custom"}}
+                </div>
+                {{#if queueDirtyFields.acl_administer_queue}}
+                <div class="btn-group btn-group-xs">
+                  <a {{action 'rollbackProp' 'acl_administer_queue' content}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+                </div>
+                {{/if}}
+              </div>
+            </div>
+            {{#unless aaq_anyone}}
+              {{user-group-input ug=content.acl_administer_queue disabled=aaq_anyone}}
+            {{/unless}}
+            <div class="form-group row">
+              {{tooltip-label
+                tagName='small'
+                class="col-sm-4 col-md-4 control-label"
+                label='Effective Administraters'
+                message='The effective permissions to perform administrative functions on this queue.'
+              }}
+              <div class="col-md-6 col-sm-6 control-value">
+                <label>{{escapeACL aaq_effective_permission}}</label>
+              </div>
+           </div>
+           <hr/>
+           <div class="row form-group">
+             {{tooltip-label
+               class="col-sm-4 col-md-4 control-label"
+               label='Submit Applications'
+               message='The access control list of users and groups that have authorization to submit applications to this queue.'
+             }}
+             <div class="col-sm-6 col-md-6 control-value">
+               <div class="btn-group btn-group-xs" data-toggle="buttons">
+                 {{radio-button label="Anyone" selectionBinding="acl_submit_applications" value="*"}}
+                 {{radio-button label="Custom" selectionBinding="acl_submit_applications" value="custom"}}
+               </div>
+               {{#if queueDirtyFields.acl_submit_applications}}
+               <div class="btn-group btn-group-xs" >
+                   <a {{action 'rollbackProp' 'acl_submit_applications' content}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+               </div>
+               {{/if}}
+             </div>
+           </div>
+           {{#unless asa_anyone}}
+             {{user-group-input ug=content.acl_submit_applications disabled=asa_anyone}}
+           {{/unless}}
+           <div class="form-group row">
+              {{tooltip-label
+                tagName='small'
+                class="col-md-4 col-sm-4 control-label"
+                label='Effective Users'
+                message='The effective permissions to submit applications to this queue.'
+              }}
+              <div class="col-sm-6 col-md-6 control-value">
+                <label>{{escapeACL asa_effective_permission}}</label>
+              </div>
+           </div>
+          {{else}}
+            <div class="form-group row">
+              {{tooltip-label
+                class="col-sm-4 col-md-4 control-label"
+                label='Administer Queue'
+                message='The access control list of users and groups that have authorization to perform administrative functions on this queue.'
+              }}
+              <div class="col-sm-6 col-md-6 control-value">
+               <p class="form-control-static">
+                {{escapeACL content.acl_administer_queue}}
+               </p>
+              </div>
+            </div>
+            <div class="form-group row">
+               {{tooltip-label
+                 tagName='small'
+                 class="col-sm-4 col-md-4 control-label"
+                 label='Effective Administraters'
+                 message='The effective permissions to perform administrative functions on this queue.'
+               }}
+               <div class="col-sm-6 col-md-6 control-value">
+                 <p class="form-control-static">
+                   {{escapeACL aaq_effective_permission}}
+                 </p>
+               </div>
+            </div>
+            <hr/>
+            <div class="form-group row">
+              {{tooltip-label
+                class="col-sm-4 col-md-4 control-label"
+                label='Submit Applications'
+                message='The access control list of users and groups that have authorization to submit applications to this queue.'
+              }}
+              <div class="col-sm-6 col-md-6 control-value">
+               <p class="form-control-static">
+                {{escapeACL content.acl_submit_applications}}
+               </p>
+              </div>
+            </div>
+            <div class="form-group row">
+               {{tooltip-label
+                 tagName='small'
+                 class="col-sm-4 col-md-4 control-label"
+                 label='Effective Users'
+                 message='The effective permissions to submit applications to this queue.'
+               }}
+               <div class="col-sm-6 col-md-6 control-valu">
+                 <p class="form-control-static">
+                   {{escapeACL asa_effective_permission}}
+                 </p>
+               </div>
+            </div>
+          {{/if}}
+        {{else}}
+          <div>Permissions are managed by Ranger</div>
+        {{/unless}}
+      </div>
+    </div>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/editQueueCapacity.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/editQueueCapacity.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/editQueueCapacity.hbs
new file mode 100644
index 0000000..753fa9b
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/editQueueCapacity.hbs
@@ -0,0 +1,51 @@
+{{!
+* 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.
+}}
+
+<div class="row form-inline">
+  <div class="col-md-2 col-sm-2">
+    <span class="queue-name">{{this.name}}</span>
+  </div>
+  <div class="col-md-5 col-md-5">
+    <div class="form-group input-group capacity-input-percent">
+      {{capacity-input class='input-sm' value=this.capacity queue=this maxVal=100}}
+      <span class="input-group-addon">%</span>
+    </div>
+    <div class="form-group capacity-input-slider">
+      {{input-range min="0" max="100" step="1" value=this.capacity class="input-sm"}}
+    </div>
+    {{#if view.isQueueCapacityDirty}}
+      <div class="btn-group btn-group-xs">
+        <a {{action 'rollbackProp' 'capacity' this}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+      </div>
+    {{/if}}
+  </div>
+  <div class="col-md-5 col-sm-5">
+    <div class="form-group input-group capacity-input-percent">
+      {{max-capacity-input class='input-sm' value=this.maximum_capacity queue=this maxVal=100}}
+      <span class="input-group-addon">%</span>
+    </div>
+    <div class="form-group capacity-input-slider">
+      {{input-range min="0" max="100" step="1" value=this.maximum_capacity class="input-sm"}}
+    </div>
+    {{#if view.isQueueMaximumCapacityDirty}}
+      <div class="btn-group btn-group-xs">
+        <a {{action 'rollbackProp' 'maximum_capacity' this}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+      </div>
+    {{/if}}
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueCapacity.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueCapacity.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueCapacity.hbs
new file mode 100644
index 0000000..8e278f0
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueCapacity.hbs
@@ -0,0 +1,95 @@
+{{!
+* 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.
+}}
+
+<div class="queue-capacity-container">
+  <div class="panel panel-default">
+    <div class="panel-heading">
+      <div class="panel-title">
+        Capacity <a id="collapseQueueCapacityPanelBtn" href="#collapsibleQueueCapacityPanel" data-toggle="collapse" {{bind-attr class=":pull-right view.isCapacityPanelCollapsed:collapsed"}}><i {{bind-attr class=":fa view.isCapacityPanelCollapsed:fa-plus:fa-minus"}}></i></a>
+      </div>
+    </div>
+    <div id="collapsibleQueueCapacityPanel" {{bind-attr class=":panel-collapse :collapse view.isCapacityPanelCollapsed::in"}}>
+      <div class="panel-body">
+        {{#if isOperator}}
+          {{#unless isLeafQ}}
+            <div class="row">
+              <div class="col-md-2 col-sm-2">
+                <label>Children</label>
+              </div>
+              <div class="col-md-5 col-sm-5">
+                {{tooltip-label
+                  label='Capacity'
+                  message= 'The minimum guaranteed capacity as a percentage of total capacity that is allocated to the queue.'
+                }}
+              </div>
+              <div class="col-md-5 col-sm-5">
+                {{tooltip-label
+                  label='Max Capacity'
+                  message= 'The cap (maximum capacity) as a percentage of total capacity that this queue can utilize.'
+                }}
+              </div>
+            </div>
+            {{#each childQ in childrenQueues}}
+              {{render "capsched/partials/editQueueCapacity" childQ}}
+            {{/each}}
+            <div class="row">
+              <div class="col-md-2 col-sm-2">
+                <label>Total Capacity</label>
+              </div>
+              <div class="col-sm-5 col-md-5">
+                <div class="progress total-capacity-progress">
+                  <div role="progressbar" {{bind-attr class=":progress-bar warnInvalidCapacity:progress-bar-danger:progress-bar-success" style="totalCapacityBarWidth"}}>
+                    Used:{{childrenQueuesTotalCapacity}}%
+                  </div>
+                </div>
+              </div>
+          </div>
+          {{else}}
+            <div class="row">
+              <div class="col-md-6 col-md-6">
+                <label>Capacity: </label>
+                <span>{{content.capacity}}%</span>
+              </div>
+              <div class="col-md-5 col-md-5">
+                <label>Maximum Capacity: </label>
+                <span>{{content.maximum_capacity}}%</span>
+              </div>
+            </div>
+            <div class="row">
+              <div class="col-md-10 col-sm-10">
+                <span>To edit capacity and maximum capacity at parent queue level</span>
+                <span>{{#link-to 'capsched.queuesconf.editqueue' parentQueue}}Click Here{{/link-to}}</span>
+              </div>
+            </div>
+          {{/unless}}
+        {{else}}
+          <div class="row">
+            <div class="col-md-6 col-md-6">
+              <label>Capacity: </label>
+              <span>{{content.capacity}}%</span>
+            </div>
+            <div class="col-md-5 col-sm-5">
+              <label>Maximum Capacity: </label>
+              <span>{{content.maximum_capacity}}%</span>
+            </div>
+          </div>
+        {{/if}}
+      </div>
+    </div>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/79489a8f/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueResources.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueResources.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueResources.hbs
new file mode 100644
index 0000000..f25180f
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueResources.hbs
@@ -0,0 +1,216 @@
+{{!
+* 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.
+}}
+
+<div class="queue-resources-container">
+  <div class="panel panel-default">
+    <div class="panel-heading">
+      <div class="panel-title">
+        Resources <a id="collapseResourcesPanelBtn" href="#collapsibleQueueResourcesPanel" data-toggle="collapse" {{bind-attr class=":pull-right view.isResourcesPanelCollapsed:collapsed"}}><i {{bind-attr class=":fa view.isResourcesPanelCollapsed:fa-plus:fa-minus"}}></i></a>
+      </div>
+    </div>
+    <div id="collapsibleQueueResourcesPanel" {{bind-attr class=":panel-collapse :collapse view.isResourcesPanelCollapsed::in"}}>
+      <div class="panel-body">
+
+        <div class="row form-group">
+          {{tooltip-label
+            class="col-sm-4 control-label"
+            label='User Limit Factor'
+            message='The upper limit multiple of the queue’s configured minimum capacity that one user’s applications can utilize.'
+          }}
+          {{#if isOperator}}
+            <div class="col-sm-3">
+              {{int-input value=content.user_limit_factor maxlength=10 class="input-sm input-int input-width-control" defaultVal=1 placeholder=1}}
+              {{#if queueDirtyFields.user_limit_factor}}
+              <div class="btn-group btn-group-xs">
+                <a {{action 'rollbackProp' 'user_limit_factor' content}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+              </div>
+              {{/if}}
+            </div>
+          {{else}}
+            <div class="col-sm-2">
+              {{#if content.user_limit_factor}}
+                <p class="form-control-static">{{content.user_limit_factor}}</p>
+              {{else}}
+                <p class="form-control-static">1</p>
+              {{/if}}
+            </div>
+          {{/if}}
+        </div>
+
+        <div class="row form-group">
+          {{tooltip-label
+            class="col-sm-4 control-label"
+            label='Minimum User Limit'
+            message='The minimum guaranteed percentage of queue capacity allocated for a user\'s applications.'
+          }}
+          {{#if isOperator}}
+            <div class="col-sm-3 control-value input-percent-wrap">
+              <div class="input-group input-percent">
+                {{int-input value=content.minimum_user_limit_percent class="input-sm" maxVal=100 placeholder=100}}
+                <span class="input-group-addon">%</span>
+              </div>
+              {{#if queueDirtyFields.minimum_user_limit_percent}}
+                <div class="btn-group btn-group-xs input-percent-rollback">
+                    <a {{action 'rollbackProp' 'minimum_user_limit_percent' content}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+                </div>
+              {{/if}}
+            </div>
+          {{else}}
+            <div class="col-sm-2">
+              {{#if content.minimum_user_limit_percent}}
+                <p class="form-control-static">{{content.minimum_user_limit_percent}}%</p>
+              {{else}}
+                <p class="form-control-static">100%</p>
+              {{/if}}
+            </div>
+          {{/if}}
+        </div>
+
+        <div class="row form-group">
+          {{tooltip-label
+            class="col-sm-4 control-label"
+            label='Maximum Applications'
+            message='The maximum number of applications that can be running or pending in this specific queue at any point of time.'
+          }}
+          {{#if isOperator}}
+            <div class="col-sm-3 control-value">
+              {{int-input placeholder="Inherited" maxlength=15 value=maximumApplications class="input-sm input-int input-width-control"}}
+              {{#if queueDirtyFields.maximum_applications}}
+                <div class="btn-group btn-group-xs" >
+                  <a {{action 'rollbackProp' 'maximum_applications' content}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+                </div>
+              {{/if}}
+            </div>
+            <div class="col-sm-2 inherited-value">
+              <span>(Inherited)</span>
+            </div>
+          {{else}}
+            <div class="col-sm-3">
+            {{#if maximumApplications}}
+              <p class="form-control-static">{{maximumApplications}} (Inherited)</p>
+            {{else}}
+              <p class="form-control-static">Inherited</p>
+            {{/if}}
+          </div>
+          {{/if}}
+        </div>
+
+        <div class="row form-group">
+          {{tooltip-label
+            class="col-sm-4 control-label"
+            label='Maximum AM Resource'
+            message='The maximum percentage of total capacity of this specific queue that can be utilized by application masters at any point in time.'
+          }}
+          {{#if isOperator}}
+          <div class="col-sm-3 control-value input-percent-wrap">
+            <div class="input-group input-percent">
+              {{int-input placeholder="Inherited" value=maximumAMResourcePercent class="input-sm" maxVal=100}}
+              <span class="input-group-addon">%</span>
+            </div>
+            {{#if queueDirtyFields.maximum_am_resource_percent}}
+              <div class="btn-group btn-group-xs">
+                <a {{action 'rollbackProp' 'maximum_am_resource_percent' content}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+              </div>
+            {{/if}}
+          </div>
+          <div class="col-sm-2 inherited-value">
+            <span>(Inherited)</span>
+          </div>
+          {{else}}
+          <div class="col-sm-2">
+            {{#if maximumAMResourcePercent}}
+              <p class="form-control-static">{{maximumAMResourcePercent}}% (Inherited)</p>
+            {{else}}
+              <p class="form-control-static">Inherited</p>
+            {{/if}}
+          </div>
+          {{/if}}
+        </div>
+
+        <div class="row form-group">
+          {{tooltip-label
+            class="col-sm-4 control-label"
+            label='Ordering policy'
+            message='The ordering policy to use for applications scheduled to this queue. <br/> FIFO: Applications get available capacity based on order they are submitted <br/> Fair: Applications will get fair share of capacity, regardless of order submitted'}}
+          {{#if isOperator}}
+          <div class="col-sm-3 control-value input-percent-wrap">
+            <div class="input-percent">
+              {{view Ember.Select
+                class="form-control input-sm"
+                content=orderingPolicyValues
+                optionLabelPath="content.label"
+                optionValuePath="content.value"
+                value=currentOP}}
+            </div>
+            {{#if queueDirtyFields.ordering_policy}}
+              <div class="btn-group btn-group-xs" >
+                <a {{action 'rollbackProp' 'ordering_policy' content}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+              </div>
+            {{/if}}
+          </div>
+          {{else}}
+          <div class="col-sm-2">
+            {{#if content.ordering_policy}}
+              <p class="form-control-static">{{uppercase content.ordering_policy}}</p>
+            {{else}}
+              <p class="form-control-static">FIFO</p>
+            {{/if}}
+          </div>
+          {{/if}}
+        </div>
+
+        <div class="row">
+          {{#if isFairOP}}
+            <div class="form-group">
+              {{tooltip-label
+                class="col-sm-4 control-label"
+                label='Enable Size Based Weight Ordering'
+                message='If true, then Fair Ordering Policy will use resource needs of an application as way to prioritize capacity allocation - larger applications will get higher priority'
+              }}
+              {{#if isOperator}}
+              <div class="col-sm-3 control-value input-toggle-wrap">
+                <div class="btn-group btn-group-sm">
+                  <a href="#" {{action 'toggleProperty' 'enable_size_based_weight' content}} class="btn btn-default">
+                    <i {{bind-attr class=":fa content.enable_size_based_weight:fa-check-square-o:fa-square-o"}}></i>
+                  </a>
+                </div>
+                {{#if queueDirtyFields.enable_size_based_weight}}
+                  <div class="btn-group btn-group-xs" >
+                    <a {{action 'rollbackProp' 'enable_size_based_weight' content}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+                  </div>
+                {{/if}}
+              </div>
+              {{else}}
+              <div class="col-sm-2">
+                <p class="form-control-static">
+                  {{#if content.enable_size_based_weight}}
+                    Enabled
+                  {{else}}
+                    Disabled
+                  {{/if}}
+                </p>
+              </div>
+              {{/if}}
+            </div>
+          {{/if}}
+        </div>
+
+      </div>
+    </div>
+  </div>
+</div>


Mime
View raw message