Repository: ignite
Updated Branches:
  refs/heads/ignite-843-rc1 738b2b595 -> 3523917dd


IGNITE-1806 WIP rework UI and code generation to new queries API.


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

Branch: refs/heads/ignite-843-rc1
Commit: 3523917dd103535a44b24c2128b5893a0a7c2e39
Parents: 738b2b5
Author: vsisko <[email protected]>
Authored: Fri Oct 30 16:14:39 2015 +0700
Committer: Alexey Kuznetsov <[email protected]>
Committed: Fri Oct 30 16:14:39 2015 +0700

----------------------------------------------------------------------
 .../src/main/js/controllers/common-module.js    |  28 +-
 .../main/js/controllers/metadata-controller.js  | 264 +++++++++----------
 .../main/js/controllers/models/metadata.json    |  82 ++----
 modules/control-center-web/src/main/js/db.js    |   8 +-
 .../main/js/routes/generator/generator-java.js  | 111 +++++---
 .../main/js/routes/generator/generator-xml.js   | 100 +++++--
 .../src/main/js/views/includes/controls.jade    |  89 ++++---
 7 files changed, 358 insertions(+), 324 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/3523917d/modules/control-center-web/src/main/js/controllers/common-module.js
----------------------------------------------------------------------
diff --git 
a/modules/control-center-web/src/main/js/controllers/common-module.js 
b/modules/control-center-web/src/main/js/controllers/common-module.js
index 6038732..8c62ca2 100644
--- a/modules/control-center-web/src/main/js/controllers/common-module.js
+++ b/modules/control-center-web/src/main/js/controllers/common-module.js
@@ -671,11 +671,9 @@ consoleModule.service('$common', [
                 return true;
             },
             metadataForQueryConfigured: function (meta) {
-                var isEmpty = !isDefined(meta) || 
(isEmptyArray(meta.queryFields)
-                    && isEmptyArray(meta.ascendingFields)
-                    && isEmptyArray(meta.descendingFields)
-                    && isEmptyArray(meta.textFields)
-                    && isEmptyArray(meta.groups));
+                var isEmpty = !isDefined(meta) || (isEmptyArray(meta.fields)
+                    && isEmptyArray(meta.aliases)
+                    && isEmptyArray(meta.indexes));
 
                 return !isEmpty;
             },
@@ -1121,11 +1119,12 @@ consoleModule.service('$table', ['$common', '$focus', 
function ($common, $focus)
 
             _tableFocus('DatabaseName' + field.focusId, index);
         }
-        else if (ui == 'table-query-groups') {
-            field.curGroupName = val.name;
-            field.curFields = val.fields;
+        else if (ui == 'table-indexes') {
+            field.curIndexName = val.name;
+            field.curIndexType = val.type;
+            field.curIndexFields = val.fields;
 
-            _tableFocus('GroupName', index);
+            _tableFocus(field.focusId, index);
         }
     }
 
@@ -1153,13 +1152,14 @@ consoleModule.service('$table', ['$common', '$focus', 
function ($common, $focus)
 
             _tableFocus('DatabaseName' + field.focusId, -1);
         }
-        else if (ui == 'table-query-groups') {
-            field.newGroupName = null;
-            field.newFields = null;
+        else if (ui == 'table-indexes') {
+            field.newIndexName = null;
+            field.newIndexType = null;
+            field.newIndexFields = null;
 
-            _tableFocus('GroupName', -1);
+            _tableFocus(field.focusId, -1);
         }
-        else if (ui == 'table-query-group-fields') {
+        else if (ui == 'table-index-fields') {
             _tableFocus('FieldName', -1);
         }
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/3523917d/modules/control-center-web/src/main/js/controllers/metadata-controller.js
----------------------------------------------------------------------
diff --git 
a/modules/control-center-web/src/main/js/controllers/metadata-controller.js 
b/modules/control-center-web/src/main/js/controllers/metadata-controller.js
index 8768bfe..d0f3f92 100644
--- a/modules/control-center-web/src/main/js/controllers/metadata-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/metadata-controller.js
@@ -89,6 +89,8 @@ consoleModule.controller('metadataController', [
                 store: {xml: '', java: '', allDefaults: true}
             };
 
+            $scope.indexType = $common.mkOptions(['SORTED', 'FULLTEXT', 
'GEOSPATIAL']);
+
             var presets = [
                 {
                     db: 'oracle',
@@ -184,8 +186,8 @@ consoleModule.controller('metadataController', [
             $scope.supportedJavaTypes = 
$common.mkOptions($common.javaBuildInClasses);
 
             $scope.sortDirections = [
-                {value: false, label: 'ASC'},
-                {value: true, label: 'DESC'}
+                {value: true, label: 'ASC'},
+                {value: false, label: 'DESC'}
             ];
 
             $scope.panels = {activePanels: [0, 1]};
@@ -474,9 +476,7 @@ consoleModule.controller('metadataController', [
                 _.forEach($scope.loadMeta.tables, function (table) {
                     if (table.use) {
                         var qryFields = [];
-                        var ascFields = [];
-                        var descFields = [];
-                        var groups = [];
+                        var indexes = [];
                         var keyFields = [];
                         var valFields = [];
 
@@ -498,17 +498,6 @@ consoleModule.controller('metadataController', [
                                 javaName: toJavaName(name), javaType: 
jdbcType.javaType}
                         }
 
-                        function colType(colName) {
-                            var col = _.find(table.cols, function (col) {
-                                return col.name == colName;
-                            });
-
-                            if (col)
-                                return $common.findJdbcType(col.type).javaType;
-
-                            return 'Unknown';
-                        }
-
                         var _containKey = false;
 
                         _.forEach(table.cols, function (col) {
@@ -518,12 +507,6 @@ consoleModule.controller('metadataController', [
                             if (!fieldIndexed(colName, table))
                                 qryFields.push(queryField(colName, jdbcType));
 
-                            if (_.includes(table.ascCols, colName))
-                                ascFields.push(queryField(colName, jdbcType));
-
-                            if (_.includes(table.descCols, colName))
-                                descFields.push(queryField(colName, jdbcType));
-
                             if (col.key) {
                                 keyFields.push(dbField(colName, jdbcType));
 
@@ -538,22 +521,20 @@ consoleModule.controller('metadataController', [
                         var idxs = table.idxs;
 
                         if (table.idxs) {
-                            var indexes = Object.keys(idxs);
+                            var tblIndexes = Object.keys(idxs);
 
-                            _.forEach(indexes, function (indexName) {
+                            _.forEach(tblIndexes, function (indexName) {
                                 var index = idxs[indexName];
 
                                 var fields = Object.keys(index);
 
-                                if (fields.length > 1)
-                                    groups.push(
-                                        {name: indexName, fields: 
_.map(fields, function (fieldName) {
-                                            return {
-                                                name: toJavaName(fieldName),
-                                                className: colType(fieldName),
-                                                direction: index[fieldName]
-                                            };
-                                        })});
+                                indexes.push(
+                                    {name: indexName, type: 'SORTED', fields: 
_.map(fields, function (fieldName) {
+                                        return {
+                                            name: toJavaName(fieldName),
+                                            direction: !index[fieldName]
+                                        };
+                                    })});
                             });
                         }
 
@@ -580,10 +561,8 @@ consoleModule.controller('metadataController', [
                         meta.valueType = valType + dupSfx;
                         meta.databaseSchema = table.schema;
                         meta.databaseTable = tableName;
-                        meta.queryFields = qryFields;
-                        meta.ascendingFields = ascFields;
-                        meta.descendingFields = descFields;
-                        meta.groups = groups;
+                        meta.fields = qryFields;
+                        meta.indexes = indexes;
                         meta.keyFields = keyFields;
                         meta.valueFields = valFields;
 
@@ -848,20 +827,13 @@ consoleModule.controller('metadataController', [
                 var qry = $common.metadataForQueryConfigured(item);
 
                 if (qry) {
-                    var groups = item.groups;
-
-                    if (groups && groups.length > 0) {
-                        for (var i = 0; i < groups.length; i++) {
-                            var group = groups[i];
-                            var fields = group.fields;
-
-                            if ($common.isEmptyArray(fields))
-                                return showPopoverMessage($scope.panels, 
'query', 'groups' + i, 'Group fields are not specified');
+                    var indexes = item.indexes;
 
-                            if (fields.length == 1) {
-                                return showPopoverMessage($scope.panels, 
'query', 'groups' + i, 'Group has only one field. Consider to use ascending or 
descending fields.');
-                            }
-                        }
+                    if (indexes && indexes.length > 0) {
+                        _.forEach(indexes, function(index) {
+                            if ($common.isEmptyArray(index.fields))
+                                return showPopoverMessage($scope.panels, 
'query', 'indexes' + i, 'Group fields are not specified');
+                        });
                     }
                 }
 
@@ -1020,9 +992,8 @@ consoleModule.controller('metadataController', [
             };
 
             var pairFields = {
-                queryFields: {msg: 'Query field class', id: 'QryField'},
-                ascendingFields: {msg: 'Ascending field class', id: 
'AscField'},
-                descendingFields: {msg: 'Descending field class', id: 
'DescField'}
+                fields: {msg: 'Query field class', id: 'QryField', 
checkValidClass: true},
+                aliases: {msg: 'Ascending field class', id: 'Alias', keyCol: 
'field', valCol: 'alias', valColName: 'alias', checkEqualsSecondField: true}
             };
 
             $scope.tablePairValid = function (item, field, index) {
@@ -1031,20 +1002,30 @@ consoleModule.controller('metadataController', [
                 var pairValue = $table.tablePairValue(field, index);
 
                 if (pairField) {
-                    if (!$common.isValidJavaClass(pairField.msg, 
pairValue.value, true, $table.tableFieldId(index, 'Value' + pairField.id)))
-                        return $table.tableFocusInvalidField(index, 'Value' + 
pairField.id);
-
                     var model = item[field.model];
 
                     if ($common.isDefined(model)) {
                         var idx = _.findIndex(model, function (pair) {
-                            return pair.name == pairValue.key
+                            return pair[pairField.keyCol || 'name'] == 
pairValue.key;
                         });
 
-                        // Found duplicate.
+                        // Found duplicate by key.
                         if (idx >= 0 && idx != index)
                             return showPopoverMessage(null, null, 
$table.tableFieldId(index, 'Key' + pairField.id), 'Field with such name already 
exists!');
+
+                        if (pairField.checkEqualsSecondField) {
+                            idx = _.findIndex(model, function (pair) {
+                                return pair[pairField.valCol || 
'className'].toUpperCase() === pairValue.value.toUpperCase();
+                            });
+
+                            // Found duplicate by value.
+                            if (idx >= 0 && idx != index)
+                                return showPopoverMessage(null, null, 
$table.tableFieldId(index, 'Value' + pairField.id), 'Field with such ' + 
pairField.valColName + ' already exists!');
+                        }
                     }
+
+                    if (pairField.checkValidClass && 
!$common.isValidJavaClass(pairField.msg, pairValue.value, true, 
$table.tableFieldId(index, 'Value' + pairField.id)))
+                        return $table.tableFocusInvalidField(index, 'Value' + 
pairField.id);
                 }
 
                 return true;
@@ -1125,167 +1106,158 @@ consoleModule.controller('metadataController', [
                 }
             };
 
-            function tableGroupValue(field, index) {
-                return index < 0 ? field.newGroupName : field.curGroupName;
+            function tableIndexName(field, index) {
+                return index < 0 ? field.newIndexName : field.curIndexName;
             }
 
-            $scope.tableGroupSaveVisible = function (field, index) {
-                return !$common.isEmptyString(tableGroupValue(field, index));
+            function tableIndexType(field, index) {
+                return index < 0 ? field.newIndexType : field.curIndexType;
+            }
+
+            $scope.tableIndexSaveVisible = function (field, index) {
+                return !$common.isEmptyString(tableIndexName(field, index)) && 
$common.isDefined(tableIndexType(field, index));
             };
 
-            $scope.tableGroupSave = function (field, index) {
-                var groupName = tableGroupValue(field, index);
+            $scope.tableIndexSave = function (field, curIdx) {
+                var indexName = tableIndexName(field, curIdx);
+                var indexType = tableIndexType(field, curIdx);
+
+                var item = $scope.backupItem;
 
-                var groups = $scope.backupItem.groups;
+                var indexes = item.indexes;
 
-                if ($common.isDefined(groups)) {
-                    var idx = _.findIndex(groups, function (group) {
-                        return group.name == groupName;
+                if ($common.isDefined(indexes)) {
+                    var idx = _.findIndex(indexes, function (index) {
+                        return index.name == indexName;
                     });
 
                     // Found duplicate.
-                    if (idx >= 0 && idx != index)
-                        return showPopoverMessage(null, null, 
$table.tableFieldId(index, 'GroupName'), 'Group with such name already 
exists!');
+                    if (idx >= 0 && idx != curIdx)
+                        return showPopoverMessage(null, null, 
$table.tableFieldId(curIdx, 'IndexName'), 'Index with such name already 
exists!');
                 }
 
-                var item = $scope.backupItem;
+                if (curIdx < 0) {
+                    var newIndex = {name: indexName, type: indexType};
 
-                if (index < 0) {
-                    var newGroup = {name: groupName};
-
-                    if (item.groups)
-                        item.groups.push(newGroup);
+                    if (item.indexes)
+                        item.indexes.push(newIndex);
                     else
-                        item.groups = [newGroup];
+                        item.indexes = [newIndex];
+                }
+                else {
+                    item.indexes[curIdx].name = indexName;
+                    item.indexes[curIdx].type = indexType;
                 }
-                else
-                    item.groups[index].name = groupName;
 
-                if (index < 0)
-                    $scope.tableGroupNewItem(field, item.groups.length - 1);
+                if (curIdx < 0)
+                    $scope.tableIndexNewItem(field, item.indexes.length - 1);
                 else {
-                    var group = item.groups[index];
+                    var index = item.indexes[curIdx];
 
-                    if (group.fields || group.fields.length > 0)
-                        $scope.tableGroupItemStartEdit(field, index, 0);
+                    if (index.fields && index.fields.length > 0)
+                        $scope.tableIndexItemStartEdit(field, curIdx, 0);
                     else
-                        $scope.tableGroupNewItem(field, index);
+                        $scope.tableIndexNewItem(field, curIdx);
                 }
             };
 
-            $scope.tableGroupNewItem = function (field, groupIndex) {
-                var groupName = $scope.backupItem.groups[groupIndex].name;
+            $scope.tableIndexNewItem = function (field, indexIdx) {
+                var indexName = $scope.backupItem.indexes[indexIdx].name;
 
-                $table.tableNewItem({ui: 'table-query-group-fields', model: 
groupName});
+                $table.tableNewItem({ui: 'table-index-fields', model: 
indexName});
 
                 field.newFieldName = null;
-                field.newClassName = null;
-                field.newDirection = false;
+                field.newDirection = true;
             };
 
-            $scope.tableGroupNewItemActive = function (groupIndex) {
-                var groups = $scope.backupItem.groups;
-
-                if (groups) {
-                    var group = groups[groupIndex];
+            $scope.tableIndexNewItemActive = function (itemIndex) {
+                var indexes = $scope.backupItem.indexes;
 
-                    if (group) {
-                        var groupName = group.name;
+                if (indexes) {
+                    var index = indexes[itemIndex];
 
-                        return $table.tableNewItemActive({model: groupName});
-                    }
+                    if (index)
+                        return $table.tableNewItemActive({model: index.name});
                 }
 
                 return false;
             };
 
-            $scope.tableGroupItemEditing = function (groupIndex, index) {
-                var groups = $scope.backupItem.groups;
+            $scope.tableIndexItemEditing = function (itemIndex, curIdx) {
+                var indexes = $scope.backupItem.indexes;
 
-                if (groups) {
-                    var group = groups[groupIndex];
+                if (indexes) {
+                    var index = indexes[itemIndex];
 
-                    if (group)
-                        return $table.tableEditing({model: group.name}, index);
+                    if (index)
+                        return $table.tableEditing({model: index.name}, 
curIdx);
                 }
 
                 return false;
             };
 
-            function tableGroupItemValue(field, index) {
+            function tableIndexItemValue(field, index) {
                 return index < 0
-                    ? {name: field.newFieldName, className: 
field.newClassName, direction: field.newDirection}
-                    : {name: field.curFieldName, className: 
field.curClassName, direction: field.curDirection};
+                    ? {name: field.newFieldName, direction: field.newDirection}
+                    : {name: field.curFieldName, direction: 
field.curDirection};
             }
 
-            $scope.tableGroupItemStartEdit = function (field, groupIndex, 
index) {
-                var groups = $scope.backupItem.groups;
-
-                var group = groups[groupIndex];
+            $scope.tableIndexItemStartEdit = function (field, indexIdx, 
curIdx) {
+                var index = $scope.backupItem.indexes[indexIdx];
 
-                $table.tableState(group.name, index);
+                $table.tableState(index.name, curIdx);
 
-                var groupItem = group.fields[index];
+                var indexItem = index.fields[curIdx];
 
-                field.curFieldName = groupItem.name;
-                field.curClassName = groupItem.className;
-                field.curDirection = groupItem.direction;
+                field.curFieldName = indexItem.name;
+                field.curDirection = indexItem.direction;
 
                 $focus('curFieldName');
             };
 
-            $scope.tableGroupItemSaveVisible = function (field, index) {
-                var groupItemValue = tableGroupItemValue(field, index);
-
-                return !$common.isEmptyString(groupItemValue.name) && 
!$common.isEmptyString(groupItemValue.className);
+            $scope.tableIndexItemSaveVisible = function (field, index) {
+                return !$common.isEmptyString(tableIndexItemValue(field, 
index).name);
             };
 
-            $scope.tableGroupItemSave = function (field, groupIndex, index) {
-                var groupItemValue = tableGroupItemValue(field, index);
-
-                if (!$common.isValidJavaClass('Group field', 
groupItemValue.className, true, $table.tableFieldId(index, 'ClassName')))
-                    return $table.tableFocusInvalidField(index, 'ClassName');
+            $scope.tableIndexItemSave = function (field, indexIdx, curIdx) {
+                var indexItemValue = tableIndexItemValue(field, curIdx);
 
-                var fields = $scope.backupItem.groups[groupIndex].fields;
+                var fields = $scope.backupItem.indexes[indexIdx].fields;
 
                 if ($common.isDefined(fields)) {
                     var idx = _.findIndex(fields, function (field) {
-                        return field.name == groupItemValue.name;
+                        return field.name == indexItemValue.name;
                     });
 
                     // Found duplicate.
-                    if (idx >= 0 && idx != index)
-                        return showPopoverMessage(null, null, 
$table.tableFieldId(index, 'FieldName'), 'Field with such name already exists 
in group!');
+                    if (idx >= 0 && idx != curIdx)
+                        return showPopoverMessage(null, null, 
$table.tableFieldId(curIdx, 'FieldName'), 'Field with such name already exists 
in index!');
                 }
 
-                var group = $scope.backupItem.groups[groupIndex];
+                var index = $scope.backupItem.indexes[indexIdx];
 
-                if (index < 0) {
-                    if (group.fields)
-                        group.fields.push(groupItemValue);
+                if (curIdx < 0) {
+                    if (index.fields)
+                        index.fields.push(indexItemValue);
                     else
-                        group.fields = [groupItemValue];
+                        index.fields = [indexItemValue];
 
-                    $scope.tableGroupNewItem(field, groupIndex);
+                    $scope.tableIndexNewItem(field, indexIdx);
                 }
                 else {
-                    var groupItem = group.fields[index];
-
-                    groupItem.name = groupItemValue.name;
-                    groupItem.className = groupItemValue.className;
-                    groupItem.direction = groupItemValue.direction;
+                    index.fields[curIdx] = indexItemValue;
 
-                    if (index < group.fields.length - 1)
-                        $scope.tableGroupItemStartEdit(field, groupIndex, 
index + 1);
+                    if (curIdx < index.fields.length - 1)
+                        $scope.tableIndexItemStartEdit(field, indexIdx, curIdx 
+ 1);
                     else
-                        $scope.tableGroupNewItem(field, groupIndex);
+                        $scope.tableIndexNewItem(field, indexIdx);
                 }
             };
 
-            $scope.tableRemoveGroupItem = function (group, index) {
+            $scope.tableRemoveIndexItem = function (index, curIdx) {
                 $table.tableReset();
 
-                group.fields.splice(index, 1);
+                index.fields.splice(curIdx, 1);
             };
 
             $scope.resetItem = function (group) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/3523917d/modules/control-center-web/src/main/js/controllers/models/metadata.json
----------------------------------------------------------------------
diff --git 
a/modules/control-center-web/src/main/js/controllers/models/metadata.json 
b/modules/control-center-web/src/main/js/controllers/models/metadata.json
index f56af9b..0f38b9f 100644
--- a/modules/control-center-web/src/main/js/controllers/models/metadata.json
+++ b/modules/control-center-web/src/main/js/controllers/models/metadata.json
@@ -76,77 +76,49 @@
       ],
       "fields": [
         {
-          "label": "Not indexed fields",
-          "id": "queryFields",
+          "label": "Fields",
+          "id": "fields",
           "ui": "table-pair",
-          "type": "queryFieldsFirst",
-          "model": "queryFields",
+          "type": "fields",
+          "model": "fields",
           "keyName": "name",
           "valueName": "className",
           "focusId": "QryField",
-          "addTip": "Add not indexed field to query",
+          "addTip": "Add field to query",
           "removeTip": "Remove field",
           "tip": [
             "Collection of name-to-type mappings to be queried, in addition to 
indexed fields"
           ]
         },
         {
-          "label": "Ascending indexed fields",
-          "id": "ascendingFields",
+          "label": "Aliases",
+          "id": "aliases",
           "ui": "table-pair",
-          "type": "queryFields",
-          "model": "ascendingFields",
-          "keyName": "name",
-          "valueName": "className",
-          "focusId": "AscField",
-          "addTip": "Add field to index in ascending order",
-          "removeTip": "Remove field",
-          "tip": [
-            "Collection of name-to-type mappings to index in ascending order"
-          ]
-        },
-        {
-          "label": "Descending indexed fields",
-          "id": "descendingFields",
-          "ui": "table-pair",
-          "type": "queryFields",
-          "model": "descendingFields",
-          "keyName": "name",
-          "valueName": "className",
-          "focusId": "DescField",
-          "addTip": "Add field to index in descending order",
-          "removeTip": "Remove field",
-          "tip": [
-            "Collection of name-to-type mappings to index in descending order"
-          ]
-        },
-        {
-          "label": "Text indexed fields",
-          "id": "textFields",
-          "type": "table-simple",
-          "model": "textFields",
-          "placeholder": "Field name",
-          "focusId": "TextField",
-          "addTip": "Add field to index as text",
-          "removeTip": "Remove field",
-          "tableTip": [
-            "Fields to index as text"
-          ],
+          "type": "aliases",
+          "model": "aliases",
+          "keyName": "field",
+          "valueName": "alias",
+          "focusId": "Alias",
+          "addTip": "Add alias to query",
+          "removeTip": "Remove alias",
           "tip": [
-            "Field to index as text"
+            "Mapping from full property name in dot notation to an alias that 
will be used as SQL column name",
+            "For example: {\"parent.name\" -> \"parentName\"}"
           ]
         },
         {
-          "label": "Group indexes",
-          "id": "groups",
-          "type": "table-query-groups",
-          "model": "groups",
-          "addTip": "Add new group",
-          "removeTip": "Remove group",
-          "addItemTip": "Add new field to group",
-          "removeItemTip": "Remove field from group",
+          "label": "Indexes",
+          "id": "indexes",
+          "ui": "table-indexes",
+          "type": "indexes",
+          "model": "indexes",
+          "addTip": "Add new index",
+          "removeTip": "Remove index",
+          "addItemTip": "Add new field to index",
+          "removeItemTip": "Remove field from index",
+          "focusId": "IndexName",
           "tip": [
-            "Collection of group indexes"
+            "Collection of indexes"
           ]
         }
       ]

http://git-wip-us.apache.org/repos/asf/ignite/blob/3523917d/modules/control-center-web/src/main/js/db.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/db.js 
b/modules/control-center-web/src/main/js/db.js
index eecc34c..ff63d3b 100644
--- a/modules/control-center-web/src/main/js/db.js
+++ b/modules/control-center-web/src/main/js/db.js
@@ -80,11 +80,9 @@ var CacheTypeMetadataSchema = new Schema({
     valueType: String,
     keyFields: [{databaseName: String, databaseType: String, javaName: String, 
javaType: String}],
     valueFields: [{databaseName: String, databaseType: String, javaName: 
String, javaType: String}],
-    queryFields: [{name: String, className: String}],
-    ascendingFields: [{name: String, className: String}],
-    descendingFields:  [{name: String, className: String}],
-    textFields: [String],
-    groups: [{name: String, fields: [{name: String, className: String, 
direction: Boolean}]}]
+    fields: [{name: String, className: String}],
+    aliases: [{field: String, alias: String}],
+    indexes: [{name: String, type: {type: String, enum: ['SORTED', 'FULLTEXT', 
'GEOSPATIAL']}, fields: [{name: String, direction: Boolean}]}]
 });
 
 // Define Cache type metadata model.

http://git-wip-us.apache.org/repos/asf/ignite/blob/3523917d/modules/control-center-web/src/main/js/routes/generator/generator-java.js
----------------------------------------------------------------------
diff --git 
a/modules/control-center-web/src/main/js/routes/generator/generator-java.js 
b/modules/control-center-web/src/main/js/routes/generator/generator-java.js
index 5ff7537..656e7b1 100644
--- a/modules/control-center-web/src/main/js/routes/generator/generator-java.js
+++ b/modules/control-center-web/src/main/js/routes/generator/generator-java.js
@@ -992,73 +992,82 @@ $generatorJava.cacheStatistics = function (cache, 
varName, res) {
 };
 
 // Generate metadata query fields.
-$generatorJava.metadataQueryFields = function (res, meta, fieldProperty) {
-    var fields = meta[fieldProperty];
+$generatorJava.metadataQueryFields = function (res, meta) {
+    var fields = meta.fields;
 
     if (fields && fields.length > 0) {
-        $generatorJava.declareVariable(res, 
$generatorJava.needNewVariable(res, fieldProperty), fieldProperty, 
'java.util.Map', 'java.util.LinkedHashMap', 'java.lang.String', 
'java.lang.Class<?>');
+        $generatorJava.declareVariable(res, 
$generatorJava.needNewVariable(res, 'fields'), 'fields', 
'java.util.LinkedHashMap', 'java.util.LinkedHashMap', 'java.lang.String', 
'java.lang.String');
 
         _.forEach(fields, function (field) {
-            res.line(fieldProperty + '.put("' + field.name + '", ' + 
res.importClass(field.className) + '.class);');
+            res.line('fields.put("' + field.name + '", "' + 
$dataStructures.fullClassName(field.className) + '");');
         });
 
         res.needEmptyLine = true;
 
-        res.line('typeMeta.' + $commonUtils.toJavaName('set', fieldProperty) + 
'(' + fieldProperty + ');');
+        res.line('queryMeta.setFields(fields);');
 
         res.needEmptyLine = true;
     }
 };
 
-// Generate metadata groups.
-$generatorJava.metadataGroups = function (res, meta) {
-    var groups = meta.groups;
+// Generate metadata query aliases.
+$generatorJava.metadataQueryAliases = function (res, meta) {
+    var aliases = meta.aliases;
 
-    if (groups && groups.length > 0) {
-        _.forEach(groups, function (group) {
-            var fields = group.fields;
+    if (aliases && aliases.length > 0) {
+        $generatorJava.declareVariable(res, 
$generatorJava.needNewVariable(res, 'aliases'), 'aliases', 'java.util.Map', 
'java.util.HashMap', 'java.lang.String', 'java.lang.String');
 
-            if (fields && fields.length > 0) {
-                res.importClass('java.util.Map');
-                res.importClass('java.util.LinkedHashMap');
-                res.importClass('org.apache.ignite.lang.IgniteBiTuple');
+        _.forEach(aliases, function (alias) {
+            res.line('aliases.put("' + alias.field + '", "' + alias.alias + 
'");');
+        });
 
-                var varNew = !res.groups;
+        res.needEmptyLine = true;
 
-                res.needEmptyLine = true;
+        res.line('queryMeta.setAliases(aliases);');
 
-                res.line((varNew ? 'Map<String, LinkedHashMap<String, 
IgniteBiTuple<Class<?>, Boolean>>> ' : '') +
-                    "groups = new LinkedHashMap<>();");
+        res.needEmptyLine = true;
+    }
+};
 
-                res.needEmptyLine = true;
+// Generate metadata indexes.
+$generatorJava.metadataQueryIndexes = function (res, meta) {
+    var indexes = meta.indexes;
 
-                if (varNew)
-                    res.groups = true;
+    if (indexes && indexes.length > 0) {
+        res.needEmptyLine = true;
 
-                varNew = !res.groupItems;
+        $generatorJava.declareVariable(res, 
$generatorJava.needNewVariable(res, 'indexes'), 'indexes', 'java.util.Map', 
'java.util.LinkedHashMap', 'String', 
'org.apache.ignite.cache.store.QueryEntityIndex');
 
-                res.line((varNew ? 'LinkedHashMap<String, 
IgniteBiTuple<Class<?>, Boolean>> ' : '') +
-                    'groupItems = new LinkedHashMap<>();');
+        _.forEach(indexes, function (index) {
+            res.needEmptyLine = true;
 
-                res.needEmptyLine = true;
+            $generatorJava.declareVariable(res, 
$generatorJava.needNewVariable(res, 'index'), 'index', 
'org.apache.ignite.cache.store.QueryEntityIndex');
+
+            $generatorJava.property(res, 'index', index, 'name');
+            $generatorJava.property(res, 'index', index, 'type', 
'org.apache.ignite.cache.store.QueryEntityIndex.Type');
 
-                if (varNew)
-                    res.groupItems = true;
+            var fields = index.fields;
+
+            if (fields && fields.length > 0) {
+                $generatorJava.declareVariable(res, 
$generatorJava.needNewVariable(res, 'indFlds'), 'indFlds', 
'java.util.LinkedHashMap', 'java.util.LinkedHashMap', 'String', 'Boolean');
 
-                _.forEach(fields, function (field) {
-                    res.line('groupItems.put("' + field.name + '", ' +
-                        'new IgniteBiTuple<Class<?>, Boolean>(' + 
res.importClass(field.className) + '.class, ' + field.direction + '));');
+                _.forEach(fields, function(field) {
+                    res.line('indFlds.put("' + field.name + '", ' + 
field.direction + ');');
                 });
 
                 res.needEmptyLine = true;
 
-                res.line('groups.put("' + group.name + '", groupItems);');
+                res.line('index.setFields(indFlds);');
+
+                res.needEmptyLine = true;
             }
+
+            res.line('indexes.add(index);');
         });
 
         res.needEmptyLine = true;
 
-        res.line('typeMeta.setGroups(groups);');
+        res.line('queryMeta.setIndexes(indexes);');
 
         res.needEmptyLine = true;
     }
@@ -1106,13 +1115,11 @@ $generatorJava.metadataQuery = function (meta, res) {
     if (!res)
         res = $generatorCommon.builder();
 
-    $generatorJava.metadataQueryFields(res, meta, 'queryFields');
-    $generatorJava.metadataQueryFields(res, meta, 'ascendingFields');
-    $generatorJava.metadataQueryFields(res, meta, 'descendingFields');
+    $generatorJava.metadataQueryFields(res, meta);
 
-    $generatorJava.listProperty(res, 'typeMeta', meta, 'textFields');
+    $generatorJava.metadataQueryAliases(res, meta);
 
-    $generatorJava.metadataGroups(res, meta);
+    $generatorJava.metadataQueryIndexes(res, meta);
 
     res.needEmptyLine = true;
 
@@ -1142,7 +1149,6 @@ $generatorJava.cacheMetadata = function(meta, res) {
     $generatorJava.declareVariable(res, $generatorJava.needNewVariable(res, 
'typeMeta'), 'typeMeta', 'org.apache.ignite.cache.CacheTypeMetadata');
 
     $generatorJava.metadataGeneral(meta, res);
-    $generatorJava.metadataQuery(meta, res);
     $generatorJava.metadataStore(meta, res);
 
     res.emptyLineIfNeeded();
@@ -1151,6 +1157,23 @@ $generatorJava.cacheMetadata = function(meta, res) {
     res.needEmptyLine = true;
 };
 
+// Generate cache type metadata config.
+$generatorJava.cacheQueryMetadata = function(meta, res) {
+    $generatorJava.declareVariable(res, $generatorJava.needNewVariable(res, 
'queryMeta'), 'queryMeta', 'org.apache.ignite.cache.store.QueryEntity');
+
+    $generatorJava.classNameProperty(res, 'queryMeta', meta, 'keyType');
+    $generatorJava.classNameProperty(res, 'queryMeta', meta, 'valueType');
+
+    res.needEmptyLine = true;
+
+    $generatorJava.metadataQuery(meta, res);
+
+    res.emptyLineIfNeeded();
+    res.line('queryEntities.add(queryMeta);');
+
+    res.needEmptyLine = true;
+};
+
 // Generate cache type metadata configs.
 $generatorJava.cacheMetadatas = function (metadatas, varName, res) {
     if (!res)
@@ -1167,6 +1190,16 @@ $generatorJava.cacheMetadatas = function (metadatas, 
varName, res) {
         res.line(varName + '.setTypeMetadata(types);');
 
         res.needEmptyLine = true;
+
+        $generatorJava.declareVariable(res, 
$generatorJava.needNewVariable(res, 'queryEntities'), 'queryEntities', 
'java.util.Collection', 'java.util.ArrayList', 
'org.apache.ignite.cache.store.QueryEntity');
+
+        _.forEach(metadatas, function (meta) {
+            $generatorJava.cacheQueryMetadata(meta, res);
+        });
+
+        res.line(varName + '.setQueryEntities(queryEntities);');
+
+        res.needEmptyLine = true;
     }
 
     return res;

http://git-wip-us.apache.org/repos/asf/ignite/blob/3523917d/modules/control-center-web/src/main/js/routes/generator/generator-xml.js
----------------------------------------------------------------------
diff --git 
a/modules/control-center-web/src/main/js/routes/generator/generator-xml.js 
b/modules/control-center-web/src/main/js/routes/generator/generator-xml.js
index 127e551..7c39150 100644
--- a/modules/control-center-web/src/main/js/routes/generator/generator-xml.js
+++ b/modules/control-center-web/src/main/js/routes/generator/generator-xml.js
@@ -846,13 +846,13 @@ $generatorXml.cacheStatistics = function(cache, res) {
 };
 
 // Generate metadata query fields.
-$generatorXml.metadataQueryFields = function (res, meta, fieldProp) {
-    var fields = meta[fieldProp];
+$generatorXml.metadataQueryFields = function (res, meta) {
+    var fields = meta.fields;
 
     if (fields && fields.length > 0) {
         res.emptyLineIfNeeded();
 
-        res.startBlock('<property name="' + fieldProp + '">');
+        res.startBlock('<property name="fields">');
         res.startBlock('<map>');
 
         _.forEach(fields, function (field) {
@@ -866,40 +866,61 @@ $generatorXml.metadataQueryFields = function (res, meta, 
fieldProp) {
     }
 };
 
-// Generate metadata groups.
-$generatorXml.metadataGroups = function (res, meta) {
-    var groups = meta.groups;
+// Generate metadata query fields.
+$generatorXml.metadataQueryAliases = function (res, meta) {
+    var aliases = meta.aliases;
 
-    if (groups && groups.length > 0) {
+    if (aliases && aliases.length > 0) {
         res.emptyLineIfNeeded();
 
-        res.startBlock('<property name="groups">');
+        res.startBlock('<property name="aliases">');
         res.startBlock('<map>');
 
-        _.forEach(groups, function (group) {
-            var fields = group.fields;
+        _.forEach(aliases, function (alias) {
+            $generatorXml.element(res, 'entry', 'key', alias.field, 'value', 
alias.alias);
+        });
+
+        res.endBlock('</map>');
+        res.endBlock('</property>');
+
+        res.needEmptyLine = true;
+    }
+};
+
+// Generate metadata indexes.
+$generatorXml.metadataQueryIndexes = function (res, meta) {
+    var indexes = meta.indexes;
+
+    if (indexes && indexes.length > 0) {
+        res.emptyLineIfNeeded();
+
+        res.startBlock('<property name="indexes">');
+        res.startBlock('<list>');
+
+        _.forEach(indexes, function (index) {
+            res.startBlock('<bean 
class="org.apache.ignite.cache.store.QueryEntityIndex">');
+
+            $generatorXml.property(res, index, 'name');
+            $generatorXml.property(res, index, 'type');
+
+            var fields = index.fields;
 
             if (fields && fields.length > 0) {
-                res.startBlock('<entry key="' + group.name + '">');
+                res.startBlock('<property name="fields">');
                 res.startBlock('<map>');
 
                 _.forEach(fields, function (field) {
-                    res.startBlock('<entry key="' + field.name.toUpperCase() + 
'">');
-
-                    res.startBlock('<bean 
class="org.apache.ignite.lang.IgniteBiTuple">');
-                    res.line('<constructor-arg value="' + 
$dataStructures.fullClassName(field.className) + '"/>');
-                    res.line('<constructor-arg value="' + field.direction + 
'"/>');
-                    res.endBlock('</bean>');
-
-                    res.endBlock('</entry>');
+                    $generatorXml.element(res, 'entry', 'key', field.name, 
'value', field.direction);
                 });
 
                 res.endBlock('</map>');
-                res.endBlock('</entry>');
+                res.endBlock('</property>');
             }
+
+            res.endBlock('</bean>');
         });
 
-        res.endBlock('</map>');
+        res.endBlock('</list>');
         res.endBlock('</property>');
 
         res.needEmptyLine = true;
@@ -958,13 +979,11 @@ $generatorXml.metadataQuery = function(meta, res) {
     if (!res)
         res = $generatorCommon.builder();
 
-    $generatorXml.metadataQueryFields(res, meta, 'queryFields');
-    $generatorXml.metadataQueryFields(res, meta, 'ascendingFields');
-    $generatorXml.metadataQueryFields(res, meta, 'descendingFields');
+    $generatorXml.metadataQueryFields(res, meta);
 
-    $generatorXml.listProperty(res, meta, 'textFields');
+    $generatorXml.metadataQueryAliases(res, meta);
 
-    $generatorXml.metadataGroups(res, meta);
+    $generatorXml.metadataQueryIndexes(res, meta);
 
     res.needEmptyLine = true;
 
@@ -1001,7 +1020,6 @@ $generatorXml.cacheMetadata = function(meta, res) {
     res.startBlock('<bean class="org.apache.ignite.cache.CacheTypeMetadata">');
 
     $generatorXml.metadataGeneral(meta, res);
-    $generatorXml.metadataQuery(meta, res);
     $generatorXml.metadataStore(meta, res);
 
     res.endBlock('</bean>');
@@ -1011,6 +1029,24 @@ $generatorXml.cacheMetadata = function(meta, res) {
     return res;
 };
 
+$generatorXml.cacheQueryMetadata = function(meta, res) {
+    if (!res)
+        res = $generatorCommon.builder();
+
+    res.startBlock('<bean class="org.apache.ignite.cache.store.QueryEntity">');
+
+    $generatorXml.classNameProperty(res, meta, 'keyType');
+    $generatorXml.property(res, meta, 'valueType');
+
+    $generatorXml.metadataQuery(meta, res);
+
+    res.endBlock('</bean>');
+
+    res.needEmptyLine = true;
+
+    return res;
+};
+
 // Generate cache type metadata configs.
 $generatorXml.cacheMetadatas = function(metadatas, res) {
     if (!res)
@@ -1030,6 +1066,16 @@ $generatorXml.cacheMetadatas = function(metadatas, res) {
         res.endBlock('</property>');
 
         res.needEmptyLine = true;
+
+        res.startBlock('<property name="queryEntities">');
+        res.startBlock('<list>');
+
+        _.forEach(metadatas, function (meta) {
+            $generatorXml.cacheQueryMetadata(meta, res);
+        });
+
+        res.endBlock('</list>');
+        res.endBlock('</property>');
     }
 
     return res;

http://git-wip-us.apache.org/repos/asf/ignite/blob/3523917d/modules/control-center-web/src/main/js/views/includes/controls.jade
----------------------------------------------------------------------
diff --git 
a/modules/control-center-web/src/main/js/views/includes/controls.jade 
b/modules/control-center-web/src/main/js/views/includes/controls.jade
index 68fdd7a..9c7af9b 100644
--- a/modules/control-center-web/src/main/js/views/includes/controls.jade
+++ b/modules/control-center-web/src/main/js/views/includes/controls.jade
@@ -277,34 +277,32 @@ mixin table-db-field-edit(prefix, focusId, index)
         .input-tip
             button.form-control(id=javaTypeId ng-model=javaTypeModel 
data-placeholder='Java type' ng-class='{placeholder: !#{javaTypeModel}}' 
bs-select bs-options='item.value as item.label for item in 
{{supportedJavaTypes}}' on-enter=btnVisibleAndSave on-escape='tableReset()' 
tabindex='0')
 
-mixin table-group-item-edit(prefix, index)
+mixin table-index-item-edit(prefix, index, sortAvailable)
     -var fieldName = prefix + 'FieldName'
-    -var className = prefix + 'ClassName'
     -var direction = prefix + 'Direction'
 
     -var fieldNameModel = 'field.' + fieldName
-    -var classNameModel = 'field.' + className
     -var directionModel = 'field.' + direction
 
-    -var btnVisible = 'tableGroupItemSaveVisible(field, ' + index + ')'
-    -var btnSave = 'tableGroupItemSave(field, groupIndex, ' + index + ')'
+    -var btnVisible = 'tableIndexItemSaveVisible(field, ' + index + ')'
+    -var btnSave = 'tableIndexItemSave(field, itemIndex, ' + index + ')'
     -var btnVisibleAndSave = btnVisible + ' && ' + btnSave
 
-    .col-xs-4.col-sm-4.col-md-4
+    .col-xs-8.col-sm-8.col-md-8(ng-show=sortAvailable)
         label.placeholder Field name
         label.fieldSep /
         .input-tip
-            input.form-control(id=fieldName enter-focus-next=className 
type='text' ng-model=fieldNameModel placeholder='Field name' 
on-escape='tableReset()')
-    .col-xs-5.col-sm-5.col-md-5
-        label.placeholder Class name
-        label.fieldSep /
-        .input-tip
-            input.form-control(id=className enter-focus-next=direction 
type='text' ng-model=classNameModel placeholder='Class name' bs-typeahead 
container='body' retain-selection data-min-length='1' bs-options='javaClass for 
javaClass in javaBuildInClasses' on-escape='tableReset()')
-    .col-xs-3.col-sm-3.col-md-3
+            input.form-control(id=fieldName enter-focus-next=direction 
type='text' ng-model=fieldNameModel placeholder='Field name' 
on-escape='tableReset()')
+    .col-xs-4.col-sm-4.col-md-4(ng-show=sortAvailable)
         label.placeholder Sort order
         +btn-save(btnVisible, btnSave)
         .input-tip
             button.form-control(id=direction ng-model=directionModel bs-select 
bs-options='item.value as item.label for item in {{sortDirections}}' 
on-enter=btnVisibleAndSave on-escape='tableReset()' tabindex='0')
+    .col-xs-12(ng-show='!(#{sortAvailable})')
+        label.placeholder Field name
+        +btn-save(btnVisible, btnSave)
+        .input-tip
+            input.form-control(id=fieldName enter-focus-next=direction 
type='text' ng-model=fieldNameModel placeholder='Field name' 
on-escape='tableReset()')
 
 mixin form-row(dataSource)
     +form-row-custom(['col-xs-4 col-sm-4 col-md-4'], ['col-xs-8 col-sm-8 
col-md-8'], dataSource)
@@ -417,10 +415,10 @@ mixin form-row-custom(lblClasses, fieldClasses, 
dataSource)
                                         
input.form-control(id='new{{::field.focusId}}' type='text' 
ng-model='field.newValue' placeholder='{{::field.placeholder}}' 
on-enter='tableSimpleSaveVisible(field, -1) && 
tableSimpleSave(tableSimpleValid, backupItem, field, -1)' 
on-escape='tableReset()')
         .group-section(ng-switch-when='indexedTypes')
             +table-pair('Index key-value type pairs', fieldMdl, 'keyClass', 
'valueClass', 'Key full class name', 'Value class full name', true, true)
-        div(ng-switch-when='queryFieldsFirst' ng-hide=fieldHide)
-            +table-pair('{{::field.label}}', fieldMdl, 'name', 'className', 
'Field name', 'Field full class name', false, true)
-        .group-section(ng-switch-when='queryFields' ng-hide=fieldHide)
+        div(ng-switch-when='fields' ng-hide=fieldHide)
             +table-pair('{{::field.label}}', fieldMdl, 'name', 'className', 
'Field name', 'Field full class name', false, true)
+        .group-section(ng-switch-when='aliases' ng-hide=fieldHide)
+            +table-pair('{{::field.label}}', fieldMdl, 'field', 'alias', 
'Field name', 'Field Alias', false, false)
         .group-section(ng-switch-when='pathModes' ng-hide=fieldHide)
             +table-igfs-path-mode('{{::field.label}}', fieldMdl, 'path', 
'mode', 'Path', 'Mode')
         .group-section(ng-switch-when='table-db-fields' ng-hide=fieldHide)
@@ -444,7 +442,7 @@ mixin form-row-custom(lblClasses, fieldClasses, dataSource)
                             tr
                                 td
                                     +table-db-field-edit('new', 
'{{::field.focusId}}', '-1')
-        .group-section(ng-switch-when='table-query-groups' ng-hide=fieldHide)
+        .group-section(ng-switch-when='indexes' ng-hide=fieldHide)
             .col-sm-12.group
                 .group-legend
                     label {{::field.label}}
@@ -452,40 +450,55 @@ mixin form-row-custom(lblClasses, fieldClasses, 
dataSource)
                     +group-btn-add('tableNewItem(field)', 'field.addTip')
                 .group-content-empty(id='{{::field.id + "-add"}}' 
ng-show='!((#{fieldMdl} && #{fieldMdl}.length > 0) || 
tableNewItemActive(field))') Not defined
                 .group-content(ng-show='(#{fieldMdl} && #{fieldMdl}.length > 
0) || tableNewItemActive(field)')
+                    -var btnVisibleAndSave = 'tableIndexSaveVisible(field, 
$index) && tableIndexSave(field, $index)'
+
                     table.links-edit(st-table=fieldMdl ng-init='newDirection = 
false')
                         tbody
-                            tr(ng-repeat='group in #{fieldMdl}')
+                            tr(ng-repeat='item in #{fieldMdl}')
                                 td
                                     .col-sm-12(ng-show='!tableEditing(field, 
$index)')
-                                        a.labelFormField(id='{{field.id + 
$index}}' ng-click='tableStartEdit(backupItem, field, $index)') {{$index + 1}}) 
{{group.name}}
+                                        a.labelFormField(id='{{field.id + 
$index}}' ng-click='tableStartEdit(backupItem, field, $index)') {{$index + 1}}) 
{{item.name}} [{{item.type}}]
                                         +btn-remove('tableRemove(backupItem, 
field, $index)', 'field.removeTip')
-                                        +btn-add('tableGroupNewItem(field, 
$index)', 'field.addItemTip')
-                                    div(ng-if='tableEditing(field, $index)')
-                                        label.labelField {{$index + 1}})
-                                        
+btn-save('tableGroupSaveVisible(field, $index)', 'tableGroupSave(field, 
$index)')
-                                        .input-tip
-                                            
input#curGroupName.form-control(type='text' ng-model='field.curGroupName' 
placeholder='Index name' on-enter='tableGroupSaveVisible(field, $index) && 
tableGroupSave(field, $index)' on-escape='tableReset()')
+                                        +btn-add('tableIndexNewItem(field, 
$index)', 'field.addItemTip')
+                                    div(ng-show='tableEditing(field, $index)')
+                                        .col-sm-7
+                                            label.placeholder Index name
+                                            label.fieldSep /
+                                            .input-tip
+                                                
input#curIndexName.form-control(type='text' enter-focus-next="curIndexType" 
ng-model='field.curIndexName' placeholder='Index name' 
on-enter=btnVisibleAndSave on-escape='tableReset()')
+                                        .col-sm-5
+                                            label.placeholder Index type
+                                            
+btn-save('tableIndexSaveVisible(field, $index)', 'tableIndexSave(field, 
$index)')
+                                            .input-tip
+                                                
button#curIndexType.form-control(bs-select ng-model='field.curIndexType' 
data-placeholder='Select index type' bs-options="item.value as item.label for 
item in indexType" tabindex='0' on-enter=btnVisibleAndSave 
on-escape='tableReset()')
                                     .margin-left-dflt
-                                        
table.links-edit-sub(st-table='group.fields' ng-init='groupIndex = $index')
+                                        
table.links-edit-sub(st-table='item.fields' ng-init='itemIndex = $index')
                                             tbody
-                                                tr(ng-repeat='groupItem in 
group.fields')
+                                                tr(ng-repeat='itemItem in 
item.fields')
                                                     td
-                                                        
div(ng-show='!tableGroupItemEditing(groupIndex, $index)')
-                                                            
a.labelFormField(ng-click='tableGroupItemStartEdit(field, groupIndex, $index)') 
{{$index + 1}}) {{groupItem.name}} / {{groupItem.className}} / 
{{groupItem.direction ? "DESC" : "ASC"}}
-                                                            
+btn-remove('tableRemoveGroupItem(group, $index)', 'field.removeItemTip')
-                                                        
div(ng-if='tableGroupItemEditing(groupIndex, $index)')
-                                                            
+table-group-item-edit('cur', '$index')
-                                            
tfoot(ng-if='tableGroupNewItemActive(groupIndex)')
+                                                        
div(ng-show='!tableIndexItemEditing(itemIndex, $index)')
+                                                            
a.labelFormField(ng-if='item.type == "SORTED"' 
ng-click='tableIndexItemStartEdit(field, itemIndex, $index)') {{$index + 1}}) 
{{itemItem.name}} / {{itemItem.direction ? "ASC" : "DESC"}}
+                                                            
a.labelFormField(ng-if='item.type != "SORTED"' 
ng-click='tableIndexItemStartEdit(field, itemIndex, $index)') {{$index + 1}}) 
{{itemItem.name}}
+                                                            
+btn-remove('tableRemoveIndexItem(item, $index)', 'field.removeItemTip')
+                                                        
div(ng-show='tableIndexItemEditing(itemIndex, $index)')
+                                                            
+table-index-item-edit('cur', '$index', '{{item.type == "SORTED"}}')
+                                            
tfoot(ng-show='tableIndexNewItemActive(itemIndex)')
                                                 tr(style='padding-left: 18px')
                                                     td
-                                                        
+table-group-item-edit('new', '-1')
+                                                        
+table-index-item-edit('new', '-1', '{{item.type == "SORTED"}}')
                         tfoot(ng-show='tableNewItemActive(field)')
                             tr
                                 td
-                                    label.placeholder Group name
-                                    +btn-save('tableGroupSaveVisible(field, 
-1)', 'tableGroupSave(field, -1)')
-                                    .input-tip
-                                        
input#newGroupName.form-control(type='text' ng-model='field.newGroupName' 
placeholder='Group name' on-enter='tableGroupSaveVisible(field, -1) && 
tableGroupSave(field, -1)' on-escape='tableReset()')
+                                    .col-sm-7
+                                        label.placeholder Index name
+                                        label.fieldSep /
+                                        .input-tip
+                                            
input#newIndexName.form-control(type='text' enter-focus-next="newIndexType" 
ng-model='field.newIndexName' placeholder='Index name' 
on-enter='tableIndexSaveVisible(field, -1) && tableIndexSave(field, -1)' 
on-escape='tableReset()')
+                                    .col-sm-5
+                                        label.placeholder Index type
+                                        
+btn-save('tableIndexSaveVisible(field, -1)', 'tableIndexSave(field, -1)')
+                                        .input-tip
+                                            
button#newIndexType.form-control(bs-select ng-model='field.newIndexType' 
data-placeholder='Select index type' bs-options="item.value as item.label for 
item in indexType" tabindex='0' on-enter=btnVisibleAndSave 
on-escape='tableReset()')
 
 mixin main-table(title, rows, focusId, click, rowTemplate)
     .padding-bottom-dflt(ng-show='#{rows} && #{rows}.length > 0')

Reply via email to