You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by an...@apache.org on 2015/07/31 04:28:34 UTC

[21/41] incubator-ignite git commit: IGNITE-843 Added support for ng-enter && ng-escape directives and use them in tables (commit edit by enter and cancel edit by esc).

IGNITE-843 Added support for ng-enter && ng-escape directives and use them in tables (commit edit by enter and cancel edit by esc).


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

Branch: refs/heads/ignite-1121
Commit: b90a6d73b91b4d7c36344f532caf74bf7ce336da
Parents: 9018cc4
Author: AKuznetsov <ak...@gridgain.com>
Authored: Tue Jul 28 22:40:42 2015 +0700
Committer: AKuznetsov <ak...@gridgain.com>
Committed: Tue Jul 28 22:40:42 2015 +0700

----------------------------------------------------------------------
 .../main/js/controllers/caches-controller.js    |  1 +
 .../main/js/controllers/clusters-controller.js  |  1 +
 .../src/main/js/controllers/common-module.js    | 30 ++++++++++++++++++++
 .../main/js/controllers/metadata-controller.js  |  1 +
 .../main/js/views/configuration/summary.jade    |  2 +-
 .../src/main/js/views/includes/controls.jade    | 28 +++++++++---------
 .../src/main/js/views/login.jade                | 14 ++++-----
 .../src/main/js/views/settings/profile.jade     |  4 +--
 .../src/main/js/views/templates/layout.jade     |  2 +-
 .../src/main/js/views/templates/select.jade     |  8 +++---
 .../src/main/js/views/templates/tab.jade        |  8 +++---
 11 files changed, 66 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b90a6d73/modules/web-control-center/src/main/js/controllers/caches-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/caches-controller.js b/modules/web-control-center/src/main/js/controllers/caches-controller.js
index 0cebc16..e995233 100644
--- a/modules/web-control-center/src/main/js/controllers/caches-controller.js
+++ b/modules/web-control-center/src/main/js/controllers/caches-controller.js
@@ -20,6 +20,7 @@ controlCenterModule.controller('cachesController', ['$scope', '$http', '$common'
         $scope.getModel = $common.getModel;
         $scope.javaBuildInTypes = $common.javaBuildInTypes;
 
+        $scope.tableReset = $table.tableReset;
         $scope.tableNewItem = $table.tableNewItem;
         $scope.tableNewItemActive = $table.tableNewItemActive;
         $scope.tableEditing = $table.tableEditing;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b90a6d73/modules/web-control-center/src/main/js/controllers/clusters-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/clusters-controller.js b/modules/web-control-center/src/main/js/controllers/clusters-controller.js
index 41215b0..0b18868 100644
--- a/modules/web-control-center/src/main/js/controllers/clusters-controller.js
+++ b/modules/web-control-center/src/main/js/controllers/clusters-controller.js
@@ -19,6 +19,7 @@ controlCenterModule.controller('clustersController', ['$scope', '$http', '$commo
         $scope.joinTip = $common.joinTip;
         $scope.getModel = $common.getModel;
 
+        $scope.tableReset = $table.tableReset;
         $scope.tableNewItem = $table.tableNewItem;
         $scope.tableNewItemActive = $table.tableNewItemActive;
         $scope.tableEditing = $table.tableEditing;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b90a6d73/modules/web-control-center/src/main/js/controllers/common-module.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/common-module.js b/modules/web-control-center/src/main/js/controllers/common-module.js
index d44b895..8f31397 100644
--- a/modules/web-control-center/src/main/js/controllers/common-module.js
+++ b/modules/web-control-center/src/main/js/controllers/common-module.js
@@ -376,6 +376,36 @@ controlCenterModule.directive('match', function ($parse) {
     };
 });
 
+// Directive to bind ENTER key press with some user action.
+controlCenterModule.directive('ngEnter', function() {
+    return function(scope, element, attrs) {
+        element.bind('keydown keypress', function(event) {
+            if (event.which === 13) {
+                scope.$apply(function() {
+                    scope.$eval(attrs.ngEnter);
+                });
+
+                event.preventDefault();
+            }
+        });
+    };
+});
+
+// Directive to bind ESC key press with some user action.
+controlCenterModule.directive('ngEscape', function() {
+    return function(scope, element, attrs) {
+        element.bind('keydown keyup', function(event) {
+            if (event.which === 27) {
+                scope.$apply(function() {
+                    scope.$eval(attrs.ngEscape);
+                });
+
+                event.preventDefault();
+            }
+        });
+    };
+});
+
 // Navigation bar controller.
 controlCenterModule.controller('activeLink', [
     '$scope', function ($scope) {

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b90a6d73/modules/web-control-center/src/main/js/controllers/metadata-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/metadata-controller.js b/modules/web-control-center/src/main/js/controllers/metadata-controller.js
index db10ddc..c8fad8d 100644
--- a/modules/web-control-center/src/main/js/controllers/metadata-controller.js
+++ b/modules/web-control-center/src/main/js/controllers/metadata-controller.js
@@ -20,6 +20,7 @@ controlCenterModule.controller('metadataController', ['$scope', '$http', '$commo
         $scope.getModel = $common.getModel;
         $scope.javaBuildInTypes = $common.javaBuildInTypes;
 
+        $scope.tableReset = $table.tableReset;
         $scope.tableNewItem = $table.tableNewItem;
         $scope.tableNewItemActive = $table.tableNewItemActive;
         $scope.tableEditing = $table.tableEditing;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b90a6d73/modules/web-control-center/src/main/js/views/configuration/summary.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/configuration/summary.jade b/modules/web-control-center/src/main/js/views/configuration/summary.jade
index be1cf77..ba63343 100644
--- a/modules/web-control-center/src/main/js/views/configuration/summary.jade
+++ b/modules/web-control-center/src/main/js/views/configuration/summary.jade
@@ -86,7 +86,7 @@ block content
                                     .col-sm-2
                                         label(for='os') Operation System:
                                     .col-sm-4
-                                        input#os.form-control(type='text', ng-model='configServer.os' placeholder='debian:8' data-min-length='0' data-html='1' data-auto-select='true' data-animation='am-flip-x' bs-typeahead bs-options='os for os in oss')
+                                        input#os.form-control(type='text' ng-model='configServer.os' placeholder='debian:8' data-min-length='0' data-html='1' data-auto-select='true' data-animation='am-flip-x' bs-typeahead bs-options='os for os in oss')
                                 div(ui-ace='{ onLoad: aceInit, mode: "dockerfile" }' ng-model='dockerServer')
             .padding-dflt(bs-collapse data-start-collapsed='false')
                 .panel.panel-default

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b90a6d73/modules/web-control-center/src/main/js/views/includes/controls.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/includes/controls.jade b/modules/web-control-center/src/main/js/views/includes/controls.jade
index 5bca8fc..94cdda4 100644
--- a/modules/web-control-center/src/main/js/views/includes/controls.jade
+++ b/modules/web-control-center/src/main/js/views/includes/controls.jade
@@ -55,15 +55,15 @@ mixin btn-down(show, click)
 mixin table-pair-edit(keyModel, valModel, keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes)
     .col-sm-6(style='float: right')
         if valueJavaBuildInTypes
-            input.form-control(type='text' ng-model=valModel placeholder=valPlaceholder bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes')
+            input.form-control(type='text' ng-model=valModel placeholder=valPlaceholder bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes' ng-escape='tableReset()')
         else
-            input.form-control(type='text' ng-model=valModel placeholder=valPlaceholder)
+            input.form-control(type='text' ng-model=valModel placeholder=valPlaceholder ng-escape='tableReset()')
     label.fieldSep /
     .input-tip
         if keyJavaBuildInTypes
-            input.form-control(type='text' ng-model=keyModel placeholder=keyPlaceholder bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes')
+            input.form-control(type='text' ng-model=keyModel placeholder=keyPlaceholder bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes' ng-escape='tableReset()')
         else
-            input.form-control(type='text' ng-model=keyModel placeholder=keyPlaceholder)
+            input.form-control(type='text' ng-model=keyModel placeholder=keyPlaceholder ng-escape='tableReset()')
 
 mixin table-pair(header, tblMdl, keyFld, valFld, keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes)
     .col-sm-6
@@ -147,7 +147,7 @@ mixin details-row
                                 label.labelField {{$index + 1}})
                                 +btn-save('tableSimpleSaveVisible(curValue)', 'tableSimpleSave(tableSimpleValid, backupItem, detail, curValue, $index)')
                                 .input-tip.form-group.has-feedback
-                                    input.form-control(name='{{detail.model}}.edit' type='text' ng-model='curValue' placeholder='{{::detail.placeholder}}')&attributes(customValidators)
+                                    input.form-control(name='{{detail.model}}.edit' type='text' ng-model='curValue' placeholder='{{::detail.placeholder}}' ng-escape='tableReset()')&attributes(customValidators)
                                     +ico-exclamation('{{detail.model}}.edit', 'ipaddress', 'Invalid address, see help for format description.')
             button.btn.btn-primary.fieldButton(ng-disabled='!newValue' ng-click='tableSimpleSave(tableSimpleValid, backupItem, detail, newValue, -1)') Add
             +tipField('detail.tip')
@@ -160,23 +160,23 @@ mixin table-db-field-edit(databaseName, databaseType, javaName, javaType)
         button.form-control(ng-model=javaType bs-select data-placeholder='Java type' bs-options='item.value as item.label for item in {{javaTypes}}')
     label.fieldSep /
     div(style='width: 20%; float: right')
-        input.form-control(type='text' ng-model=javaName placeholder='Java name')
+        input.form-control(type='text' ng-model=javaName placeholder='Java name' ng-escape='tableReset()')
     label.fieldSep /
     div(style='width: 22%; float: right')
         button.form-control(ng-model=databaseType bs-select data-placeholder='JDBC type' bs-options='item.value as item.label for item in {{jdbcTypes}}')
     label.fieldSep /
     .input-tip
-        input.form-control(type='text' ng-model=databaseName placeholder='DB name')
+        input.form-control(type='text' ng-model=databaseName placeholder='DB name' ng-escape='tableReset()')
 
 mixin table-group-item-edit(fieldName, className, direction)
     div(style='width: 15%; float: right')
         button.form-control(ng-model=direction bs-select data-placeholder='Sort' bs-options='item.value as item.label for item in {{sortDirections}}')
     label.fieldSep /
     div(style='width: 38%; float: right')
-        input.form-control(type='text' ng-model=className placeholder='Class name' bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes')
+        input.form-control(type='text' ng-model=className placeholder='Class name' bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes' ng-escape='tableReset()')
     label.fieldSep /
     .input-tip
-        input.form-control(type='text' ng-model=fieldName placeholder='Field name')
+        input.form-control(type='text' ng-model=fieldName placeholder='Field name' ng-escape='tableReset()')
 
 mixin form-row
     +form-row-custom(['col-sm-2'], ['col-sm-4'])
@@ -268,13 +268,13 @@ mixin form-row-custom(lblClasses, fieldClasses)
                                             label.labelField {{$index + 1}})
                                             +btn-save('tableSimpleSaveVisible(curValue)', 'tableSimpleSave(tableSimpleValid, backupItem, field, curValue, $index)')
                                             .input-tip
-                                                input.form-control(type='text' ng-model='curValue' placeholder='{{::field.placeholder}}')
+                                                input.form-control(type='text' ng-model='curValue' placeholder='{{::field.placeholder}}' ng-enter='tableSimpleSaveVisible(curValue) && tableSimpleSave(tableSimpleValid, backupItem, field, curValue, $index)' ng-escape='tableReset()')
                             tfoot(ng-show='tableNewItemActive(field)')
                                 tr
                                     td.col-sm-12
                                         +btn-save('tableSimpleSaveVisible(newValue)', 'tableSimpleSave(tableSimpleValid, backupItem, field, newValue, -1)')
                                         .input-tip
-                                            input.form-control(type='text' ng-model='newValue' placeholder='{{::field.placeholder}}')
+                                            input.form-control(type='text' ng-model='newValue' placeholder='{{::field.placeholder}}' ng-enter='tableSimpleSaveVisible(newValue) && tableSimpleSave(tableSimpleValid, backupItem, field, newValue, -1)' ng-escape='tableReset()')
         div(ng-switch-when='indexedTypes')
             +table-pair('Index key-value type pairs', fieldMdl, 'keyClass', 'valueClass', 'Key class full name', 'Value class full name', true, false)
         div(ng-switch-when='queryFields' ng-hide=fieldHide)
@@ -311,7 +311,7 @@ mixin form-row-custom(lblClasses, fieldClasses)
             .col-sm-12(ng-show='(#{fieldMdl} && #{fieldMdl}.length > 0) || tableNewItemActive(field)')
                 .col-sm-6
                     .table-details
-                        table.links-edit.col-sm-12(st-table=fieldMdl ng-init='newDirection = "ASC"')
+                        table.links-edit.col-sm-12(st-table=fieldMdl ng-init='newDirection = false')
                             tbody
                                 tr(ng-repeat='group in #{fieldMdl}')
                                     td.col-sm-12
@@ -324,7 +324,7 @@ mixin form-row-custom(lblClasses, fieldClasses)
                                                 label.labelField {{$index + 1}})
                                                 +btn-save('tableGroupSaveVisible(curGroupName)', 'tableGroupSave(curGroupName, $index)')
                                                 .input-tip
-                                                    input.form-control(type='text' ng-model='curGroupName' placeholder='Index name')
+                                                    input.form-control(type='text' ng-model='curGroupName' placeholder='Index name' ng-enter='tableGroupSaveVisible(curGroupName) && tableGroupSave(curGroupName, $index)' ng-escape='tableReset()')
                                             div
                                                 table.links-edit.col-sm-12(st-table='group.fields' ng-init='groupIndex = $index')
                                                     tr(ng-repeat='groupItem in group.fields')
@@ -345,4 +345,4 @@ mixin form-row-custom(lblClasses, fieldClasses)
                                     td.col-sm-12
                                         +btn-save('tableGroupSaveVisible(newGroupName)', 'tableGroupSave(newGroupName, -1)')
                                         .input-tip
-                                            input.form-control(type='text' ng-model='newGroupName' placeholder='Group name')
\ No newline at end of file
+                                            input.form-control(type='text' ng-model='newGroupName' placeholder='Group name' ng-enter='tableGroupSaveVisible(newGroupName) && tableGroupSave(newGroupName, -1)' ng-escape='tableReset()')
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b90a6d73/modules/web-control-center/src/main/js/views/login.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/login.jade b/modules/web-control-center/src/main/js/views/login.jade
index 6b8646f..a580c01 100644
--- a/modules/web-control-center/src/main/js/views/login.jade
+++ b/modules/web-control-center/src/main/js/views/login.jade
@@ -22,7 +22,7 @@ mixin lbl(txt)
         .modal-content
             .modal-header.header
                 div(id='errors-container')
-                button.close(type='button', ng-click='$hide()', aria-hidden='true') &times;
+                button.close(type='button' ng-click='$hide()' aria-hidden='true') &times;
                 h1.navbar-brand
                     a(href='/') Apache Ignite Web Configurator
                 h4.modal-title(style='padding-right: 55px') Authentication
@@ -33,23 +33,23 @@ mixin lbl(txt)
                         .details-row(ng-show='action == "register"')
                             +lbl('Full Name:')
                             .col-sm-9
-                                input.form-control(type='text', ng-model='user_info.username', placeholder='John Smith', focus-me='action=="register"', ng-required='action=="register"')
+                                input.form-control(type='text' ng-model='user_info.username' placeholder='John Smith' focus-me='action=="register"' ng-required='action=="register"')
                         .details-row
                             +lbl('Email:')
                             .col-sm-9
-                                input.form-control(type='email', ng-model='user_info.email', placeholder='you@domain.com', focus-me='action=="login"', required)
+                                input.form-control(type='email' ng-model='user_info.email' placeholder='you@domain.com' focus-me='action=="login"' required)
                         .details-row
                             +lbl('Password:')
                             .col-sm-9
-                                input.form-control(type='password', ng-model='user_info.password', placeholder='Password', required, ng-keyup='action == "login" && $event.keyCode == 13 ? auth(action, user_info) : null')
+                                input.form-control(type='password' ng-model='user_info.password' placeholder='Password' required ng-enter='action == "login" && auth(action, user_info)')
                         .details-row(ng-show='action == "register"')
                             +lbl('Confirm:')
                             .col-sm-9.input-tip.has-feedback
-                                input.form-control(type='password', ng-model='user_info.confirm', match='user_info.password' placeholder='Confirm password', required, ng-keyup='$event.keyCode == 13 ? auth(action, user_info) : null')
+                                input.form-control(type='password' ng-model='user_info.confirm' match='user_info.password' placeholder='Confirm password' required ng-enter='auth(action, user_info)')
 
             .modal-footer
-                a.show-signup.ng-hide(ng-show='action != "login"', ng-click='action = "login";') log in
-                a.show-signup(ng-show='action != "register"', ng-click='action = "register"') sign up
+                a.show-signup.ng-hide(ng-show='action != "login"' ng-click='action = "login";') log in
+                a.show-signup(ng-show='action != "register"' ng-click='action = "register"') sign up
                 | &nbsp;or&nbsp;
                 button.btn.btn-primary(ng-show='action == "login"' ng-click='auth(action, user_info)') Log In
                 button.btn.btn-primary(ng-show='action == "register"' ng-disabled='loginForm.$invalid || user_info.password != user_info.confirm' ng-click='auth(action, user_info)') Sign Up

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b90a6d73/modules/web-control-center/src/main/js/views/settings/profile.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/settings/profile.jade b/modules/web-control-center/src/main/js/views/settings/profile.jade
index 96f06c5..6ddcafa 100644
--- a/modules/web-control-center/src/main/js/views/settings/profile.jade
+++ b/modules/web-control-center/src/main/js/views/settings/profile.jade
@@ -48,11 +48,11 @@ block container
                             .details-row
                                 +lbl('New password:')
                                 .col-sm-4
-                                    input.form-control(type='password', ng-model='profileUser.newPassword' placeholder='New password' ng-required='profileUser.changePassword')
+                                    input.form-control(type='password' ng-model='profileUser.newPassword' placeholder='New password' ng-required='profileUser.changePassword')
                             .details-row
                                 +lbl('Confirm:')
                                 .col-sm-4
-                                    input.form-control(type='password', ng-model='profileUser.confirmPassword' match='profileUser.newPassword' placeholder='Confirm new password' ng-required='profileUser.changePassword')
+                                    input.form-control(type='password' ng-model='profileUser.confirmPassword' match='profileUser.newPassword' placeholder='Confirm new password' ng-required='profileUser.changePassword')
                     .col-sm-12.details-row
                         button.btn.btn-primary(ng-disabled='profileForm.$invalid' ng-click='saveUser()') Save
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b90a6d73/modules/web-control-center/src/main/js/views/templates/layout.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/templates/layout.jade b/modules/web-control-center/src/main/js/views/templates/layout.jade
index 8fbcd7e..71d8936 100644
--- a/modules/web-control-center/src/main/js/views/templates/layout.jade
+++ b/modules/web-control-center/src/main/js/views/templates/layout.jade
@@ -15,7 +15,7 @@
     limitations under the License.
 
 doctype html
-html(ng-app='ignite-web-control-center', ng-init='user = #{JSON.stringify(user)}; becomeUsed = #{becomeUsed}')
+html(ng-app='ignite-web-control-center' ng-init='user = #{JSON.stringify(user)}; becomeUsed = #{becomeUsed}')
     head
         title= title
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b90a6d73/modules/web-control-center/src/main/js/views/templates/select.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/templates/select.jade b/modules/web-control-center/src/main/js/views/templates/select.jade
index 10c1946..b219f13 100644
--- a/modules/web-control-center/src/main/js/views/templates/select.jade
+++ b/modules/web-control-center/src/main/js/views/templates/select.jade
@@ -14,11 +14,11 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-ul.select.dropdown-menu(tabindex='-1', ng-show='$isVisible()', role='select')
-    li(role='presentation', ng-repeat='match in $matches')
+ul.select.dropdown-menu(tabindex='-1' ng-show='$isVisible()' role='select')
+    li(role='presentation' ng-repeat='match in $matches')
         hr(ng-if='match.value == undefined' style='margin: 5px 0')
-        a(style='cursor: default; padding: 3px 6px;', role='menuitem', tabindex='-1', ng-class='{active: $isActive($index)}' ng-click='$select($index, $event)')
-            i(class='{{$iconCheckmark}}', ng-if='$isActive($index)' ng-class='{active: $isActive($index)}' style='color: #ec1c24; margin-left: 15px; line-height: 20px; float: right;background-color: transparent;')
+        a(style='cursor: default; padding: 3px 6px;' role='menuitem' tabindex='-1' ng-class='{active: $isActive($index)}' ng-click='$select($index, $event)')
+            i(class='{{$iconCheckmark}}' ng-if='$isActive($index)' ng-class='{active: $isActive($index)}' style='color: #ec1c24; margin-left: 15px; line-height: 20px; float: right;background-color: transparent;')
             span(ng-bind='match.label')
     li(ng-if='$showAllNoneButtons || ($isMultiple && $matches.length > 5)')
         hr(style='margin: 5px 0')

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b90a6d73/modules/web-control-center/src/main/js/views/templates/tab.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/templates/tab.jade b/modules/web-control-center/src/main/js/views/templates/tab.jade
index 9bf8c1d..6c7afc5 100644
--- a/modules/web-control-center/src/main/js/views/templates/tab.jade
+++ b/modules/web-control-center/src/main/js/views/templates/tab.jade
@@ -15,12 +15,12 @@
     limitations under the License.
 
 ul.nav(ng-class='$navClass', role='tablist')
-    li(role='presentation', ng-repeat='$pane in $panes track by $index', ng-class='[ $isActive($pane, $index) ? $activeClass : "", $pane.disabled ? "disabled" : "" ]')
-        a(ng-if='$index == 0' role='tab', data-toggle='tab', ng-click='!$pane.disabled && $setActive($pane.name || $index)', data-index='{{ $index }}', aria-controls='$pane.title') {{$pane.title}}
+    li(role='presentation' ng-repeat='$pane in $panes track by $index' ng-class='[ $isActive($pane, $index) ? $activeClass : "", $pane.disabled ? "disabled" : "" ]')
+        a(ng-if='$index == 0' role='tab' data-toggle='tab' ng-click='!$pane.disabled && $setActive($pane.name || $index)' data-index='{{ $index }}' aria-controls='$pane.title') {{$pane.title}}
             i.fa.fa-remove(ng-click='removeTab($index)' ng-if='$index > 0' style='margin-left: 5px')
-        a(ng-if='$index > 0' role='tab', data-toggle='tab', ng-click='!$pane.disabled && $setActive($pane.name || $index)', data-index='{{ $index }}', aria-controls='$pane.title') {{$pane.title}}: {{$index}}
+        a(ng-if='$index > 0' role='tab' data-toggle='tab' ng-click='!$pane.disabled && $setActive($pane.name || $index)' data-index='{{ $index }}' aria-controls='$pane.title') {{$pane.title}}: {{$index}}
             i.fa.fa-remove(ng-click='removeTab($index)' style='margin-left: 5px')
     li.pull-right(bs-tooltip data-title='Add new query')
-        a(role='tab', data-toggle='tab' ng-click='addTab()')
+        a(role='tab' data-toggle='tab' ng-click='addTab()')
             i.fa.fa-plus
 .tab-content(ng-transclude)