You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2017/03/13 08:45:36 UTC

[15/50] [abbrv] ignite git commit: IGNITE-4659 Migration to Webpack 2. Upgrade template engine from jade to pug.

http://git-wip-us.apache.org/repos/asf/ignite/blob/1080e686/modules/web-console/frontend/app/modules/states/configuration/domains/query.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/domains/query.pug b/modules/web-console/frontend/app/modules/states/configuration/domains/query.pug
new file mode 100644
index 0000000..a057f59
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/domains/query.pug
@@ -0,0 +1,172 @@
+//-
+    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.
+
+include /app/helpers/jade/mixins
+
+-var form = 'query'
+-var model = 'backupItem'
+-var queryFields = `${model}.fields`
+-var queryAliases = `${model}.aliases`
+-var queryIndexes = `${model}.indexes`
+-var queryFieldsForm = 'queryFields'
+-var queryAliasesForm = 'queryAliases'
+-var queryIndexesForm = 'queryIndexes'
+
+// LEGACY mixin for LEGACY index fields table.
+mixin table-index-item-edit(prefix, index, sortAvailable, idAddition)
+    -var fieldName = `${prefix}FieldName`
+    -var direction = `${prefix}Direction`
+
+    -var fieldNameModel = `indexesTbl.${fieldName}`
+    -var directionModel = `indexesTbl.${direction}`
+
+    -var btnVisible = `tableIndexItemSaveVisible(indexesTbl, ${index})`
+    -var btnSave = `tableIndexItemSave(indexesTbl, itemIndex, ${index})`
+    -var btnVisibleAndSave = `${btnVisible} && ${btnSave}`
+
+    div(ng-if=sortAvailable)
+        .col-xs-8.col-sm-8.col-md-8
+            label.fieldSep /
+            .input-tip
+                button.select-toggle.form-control(id=`{{::'${fieldName}' + ${idAddition}}}` ignite-on-enter-focus-move=`{{::'${direction}S' + ${idAddition}}}` ng-model=fieldNameModel placeholder=`{{fields('${prefix}', ${fieldNameModel}).length > 0 ? 'Choose field' : 'No fields configured'}}` bs-select bs-options=`item.value as item.label for item in fields('${prefix}', ${fieldNameModel})` ng-disabled=`fields('${prefix}', ${fieldNameModel}).length === 0` ignite-on-escape='tableReset(false)' tabindex='0')
+        .col-xs-4.col-sm-4.col-md-4
+            +btn-save(btnVisible, btnSave)
+            .input-tip
+                button.select-toggle.form-control(id=`{{::'${direction}' + ${idAddition}}}` ng-model=directionModel bs-select bs-options='item.value as item.label for item in {{sortDirections}}' ignite-on-enter=btnVisibleAndSave ignite-on-escape='tableReset(false)' tabindex='0')
+    .col-xs-12(ng-if=`!(${sortAvailable})`)
+        +btn-save(btnVisible, btnSave)
+        .input-tip
+            button.select-toggle.form-control(id=`{{::'${fieldName}' + ${idAddition}}}` ng-model=fieldNameModel placeholder=`{{fields('${prefix}', ${fieldNameModel}).length > 0 ? 'Choose index field' : 'No fields configured'}}` bs-select bs-options=`item.value as item.label for item in fields('${prefix}', ${fieldNameModel})` ng-disabled=`fields('${prefix}', ${fieldNameModel}).length === 0` ignite-on-escape='tableReset(false)' tabindex='0')
+
+.panel.panel-default(ng-form=form novalidate)
+    .panel-heading(bs-collapse-toggle)
+        ignite-form-panel-chevron
+        label(id='query-title') Domain model for SQL query
+        ignite-form-field-tooltip.tipLabel
+            | Domain model properties for fields queries#[br]
+            | #[a(href='https://apacheignite.readme.io/docs/cache-queries' target='_blank') More info]
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id='query')
+        .panel-body
+            .col-sm-6
+                .content-not-available(ng-if=`${model}.queryMetadata === 'Annotations'`)
+                    label Not available for annotated types
+                div(ng-if=`${model}.queryMetadata === 'Configuration'`)
+                    .settings-row
+                        +ignite-form-group(ng-model=queryFields ng-form=queryFieldsForm)
+                            ignite-form-field-label(id='queryFields')
+                                | Fields
+                            ignite-form-group-tooltip
+                                | Collection of name-to-type mappings to be queried, in addition to indexed fields
+                            ignite-form-group-add(ng-click='tableNewItem(queryFieldsTbl)')
+                                | Add field to query
+                            .group-content-empty(ng-if=`!((${queryFields} && ${queryFields}.length > 0) || tableNewItemActive(queryFieldsTbl))`)
+                                | Not defined
+                            .group-content(ng-show=`(${queryFields} && ${queryFields}.length > 0) || tableNewItemActive(queryFieldsTbl)`)
+                                table.links-edit(id='fields' st-table=queryFields)
+                                    tbody
+                                        tr(ng-repeat=`item in ${queryFields} track by $index`)
+                                            td.col-sm-12(ng-hide='tableEditing(queryFieldsTbl, $index)')
+                                                a.labelFormField(ng-click='tableStartEdit(backupItem, queryFieldsTbl, $index)') {{item.name}}  / {{item.className}}
+                                                +btn-remove('tableRemove(backupItem, queryFieldsTbl, $index)', '"Remove path"')
+                                            td.col-sm-12(ng-show='tableEditing(queryFieldsTbl, $index)')
+                                                +table-pair-edit('queryFieldsTbl', 'cur', 'Field name', 'Field full class name', false, true, '{{::queryFieldsTbl.focusId + $index}}', '$index', '/')
+                                    tfoot(ng-show='tableNewItemActive(queryFieldsTbl)')
+                                        tr
+                                            td.col-sm-12
+                                                +table-pair-edit('queryFieldsTbl', 'new', 'Field name', 'Field full class name', false, true, '{{::queryFieldsTbl.focusId + $index}}', '-1', '/')
+                    .settings-row
+                        +ignite-form-group(ng-model=queryAliases ng-form=queryAliasesForm)
+                            ignite-form-field-label
+                                | Aliases
+                            ignite-form-group-tooltip
+                                | Mapping from full property name in dot notation to an alias that will be used as SQL column name
+                                | For example: "parent.name" as "parentName"
+                            ignite-form-group-add(ng-click='tableNewItem(aliasesTbl)')
+                                | Add alias to query
+                            .group-content-empty(ng-if=`!((${queryAliases} && ${queryAliases}.length > 0) || tableNewItemActive(aliasesTbl))`)
+                                | Not defined
+                            .group-content(ng-show=`(${queryAliases} && ${queryAliases}.length > 0) || tableNewItemActive(aliasesTbl)`)
+                                table.links-edit(id='aliases' st-table=queryAliases)
+                                    tbody
+                                        tr(ng-repeat=`item in ${queryAliases} track by $index`)
+                                            td.col-sm-12(ng-hide='tableEditing(aliasesTbl, $index)')
+                                                a.labelFormField(ng-click='tableStartEdit(backupItem, aliasesTbl, $index)') {{item.field}} → {{item.alias}}
+                                                +btn-remove('tableRemove(backupItem, aliasesTbl, $index)', '"Remove alias"')
+                                            td.col-sm-12(ng-show='tableEditing(aliasesTbl, $index)')
+                                                +table-pair-edit('aliasesTbl', 'cur', 'Field name', 'Field Alias', false, false, '{{::aliasesTbl.focusId + $index}}', '$index', '→')
+                                    tfoot(ng-show='tableNewItemActive(aliasesTbl)')
+                                        tr
+                                            td.col-sm-12
+                                                +table-pair-edit('aliasesTbl', 'new', 'Field name', 'Field Alias', false, false, '{{::aliasesTbl.focusId + $index}}', '-1', '→')
+                    .settings-row(ng-init='indexesTbl={type: "table-indexes", model: "indexes", focusId: "IndexName", ui: "table-indexes"}')
+                        +ignite-form-group(ng-model=queryIndexes ng-form=queryIndexesForm)
+                            ignite-form-field-label
+                                | Indexes
+                            ignite-form-group-tooltip
+                                | Collection of indexes
+                            ignite-form-group-add(ng-click='tableNewItem(indexesTbl)')
+                                | Add new index
+                            .group-content-empty(id='indexes-add' ng-show=`!((${queryIndexes} && ${queryIndexes}.length > 0) || tableNewItemActive(indexesTbl))`)
+                                | Not defined
+                            .group-content(ng-show=`(${queryIndexes} && ${queryIndexes}.length > 0) || tableNewItemActive(indexesTbl)`)
+                                -var btnVisibleAndSave = 'tableIndexSaveVisible(indexesTbl, $index) && tableIndexSave(indexesTbl, $index)'
+
+                                table.links-edit(st-table=queryIndexes ng-init='newDirection = false')
+                                    tbody
+                                        tr(ng-repeat=`item in ${queryIndexes} track by $index`)
+                                            td
+                                                .col-sm-12(ng-hide='tableEditing(indexesTbl, $index)')
+                                                    a.labelFormField(id='indexes{{$index}}' ng-click='tableStartEdit(backupItem, indexesTbl, $index)') {{$index + 1}}) {{item.name}} [{{item.indexType}}]
+                                                    +btn-remove('tableRemove(backupItem, indexesTbl, $index)', '"Remove index"')
+                                                    +btn-add('tableIndexNewItem(indexesTbl, $index)', '"Add new field to index"')
+                                                div(ng-show='tableEditing(indexesTbl, $index)')
+                                                    .col-sm-7
+                                                        label.fieldSep /
+                                                        .input-tip
+                                                            input.form-control(id='curIndexName{{$index}}' type='text' ignite-on-enter-focus-move='curIndexType{{$index}}' ng-model='indexesTbl.curIndexName' placeholder='Index name' ignite-on-enter=btnVisibleAndSave ignite-on-escape='tableReset(false)')
+                                                    .col-sm-5
+                                                        +btn-save('tableIndexSaveVisible(indexesTbl, $index)', 'tableIndexSave(indexesTbl, $index)')
+                                                        .input-tip
+                                                            button.select-toggle.form-control(id='curIndexType{{$index}}' bs-select ng-model='indexesTbl.curIndexType' data-placeholder='Select index type' bs-options='item.value as item.label for item in indexType' tabindex='0' ignite-on-enter=btnVisibleAndSave ignite-on-escape='tableReset(false)')
+                                                .margin-left-dflt
+                                                    table.links-edit-sub(st-table='item.fields' ng-init='itemIndex = $index')
+                                                        tbody
+                                                            tr(ng-repeat='itemItem in item.fields track by $index')
+                                                                td
+                                                                    div(ng-hide='tableIndexItemEditing(indexesTbl, itemIndex, $index)')
+                                                                        a.labelFormField(ng-if='item.indexType == "SORTED"' ng-click='tableIndexItemStartEdit(indexesTbl, itemIndex, $index)') {{$index + 1}}) {{itemItem.name}} / {{itemItem.direction ? "ASC" : "DESC"}}
+                                                                        a.labelFormField(ng-if='item.indexType != "SORTED"' ng-click='tableIndexItemStartEdit(indexesTbl, itemIndex, $index)') {{$index + 1}}) {{itemItem.name}}
+                                                                        +btn-remove('tableRemoveIndexItem(item, $index)', '"Remove field from index"')
+                                                                    div(ng-show='tableIndexItemEditing(indexesTbl, itemIndex, $index)')
+                                                                        +table-index-item-edit('cur', '$index', 'item.indexType == "SORTED"', 'itemIndex + "-" + $index')
+                                                        tfoot(ng-show='tableIndexNewItemActive(indexesTbl, itemIndex)')
+                                                            tr(style='padding-left: 18px')
+                                                                td
+                                                                    +table-index-item-edit('new', '-1', 'item.indexType == "SORTED"', 'itemIndex')
+                                    tfoot(ng-show='tableNewItemActive(indexesTbl)')
+                                        tr
+                                            td
+                                                .col-sm-7
+                                                    .fieldSep /
+                                                    .input-tip
+                                                        input#newIndexName.form-control(type='text' ignite-on-enter-focus-move='newIndexType' ng-model='indexesTbl.newIndexName' placeholder='Index name' ignite-on-enter='tableIndexSaveVisible(indexesTbl, -1) && tableIndexSave(indexesTbl, -1)' ignite-on-escape='tableReset(false)')
+                                                .col-sm-5
+                                                    +btn-save('tableIndexSaveVisible(indexesTbl, -1)', 'tableIndexSave(indexesTbl, -1)')
+                                                    .input-tip
+                                                        button#newIndexType.select-toggle.form-control(bs-select ng-model='indexesTbl.newIndexType' data-placeholder='Select index type' bs-options='item.value as item.label for item in indexType' tabindex='0' ignite-on-enter=btnVisibleAndSave ignite-on-escape='tableReset(false)')
+            .col-sm-6
+                +preview-xml-java(model, 'domainModelQuery')

http://git-wip-us.apache.org/repos/asf/ignite/blob/1080e686/modules/web-console/frontend/app/modules/states/configuration/domains/store.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/domains/store.jade b/modules/web-console/frontend/app/modules/states/configuration/domains/store.jade
deleted file mode 100644
index f5d6b7d..0000000
--- a/modules/web-console/frontend/app/modules/states/configuration/domains/store.jade
+++ /dev/null
@@ -1,127 +0,0 @@
-//-
-    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.
-
-include /app/helpers/jade/mixins.jade
-
--var form = 'store'
--var model = 'backupItem'
--var keyFields = model + '.keyFields'
--var valueFields = model + '.valueFields'
--var keyFieldsForm = 'storeKeyFields'
--var valueFieldsForm = 'storeValueFields'
-
-//- LEGACY mixin for LEGACY db fields tables.
-mixin table-db-field-edit(tbl, prefix, focusId, index)
-    -var databaseName = prefix + 'DatabaseFieldName'
-    -var databaseType = prefix + 'DatabaseFieldType'
-    -var javaName = prefix + 'JavaFieldName'
-    -var javaType = prefix + 'JavaFieldType'
-
-    -var databaseNameModel = tbl + '.' + databaseName
-    -var databaseTypeModel = tbl + '.' + databaseType
-    -var javaNameModel = tbl + '.' + javaName
-    -var javaTypeModel = tbl + '.' + javaType
-
-    -var databaseNameId = databaseName + focusId
-    -var databaseTypeId = databaseType + focusId
-    -var javaNameId = javaName + focusId
-    -var javaTypeId = javaType + focusId
-
-    .col-xs-3.col-sm-3.col-md-3
-        .fieldSep /
-        .input-tip
-            input.form-control(id=databaseNameId ignite-on-enter-focus-move=databaseTypeId type='text' ng-model=databaseNameModel placeholder='DB name' ignite-on-enter='#{javaNameModel} = #{javaNameModel} ? #{javaNameModel} : #{databaseNameModel}' ignite-on-escape='tableReset(false)')
-    .col-xs-3.col-sm-3.col-md-3
-        .fieldSep /
-        .input-tip
-            button.select-toggle.form-control(id=databaseTypeId ignite-on-enter-focus-move=javaNameId ng-model=databaseTypeModel data-placeholder='DB type' ng-class='{placeholder: !#{databaseTypeModel}}' bs-select bs-options='item.value as item.label for item in {{supportedJdbcTypes}}' ignite-on-escape='tableReset(false)' tabindex='0')
-    .col-xs-3.col-sm-3.col-md-3
-        .fieldSep /
-        .input-tip
-            input.form-control(id=javaNameId ignite-on-enter-focus-move=javaTypeId type='text' ng-model=javaNameModel placeholder='Java name' ignite-on-escape='tableReset(false)')
-    .col-xs-3.col-sm-3.col-md-3
-        -var btnVisible = 'tableDbFieldSaveVisible(' + tbl + ', ' + index +')'
-        -var btnSave = 'tableDbFieldSave(' + tbl + ', ' + index +')'
-        -var btnVisibleAndSave = btnVisible + ' && ' + btnSave
-
-        +btn-save(btnVisible, btnSave)
-        .input-tip
-            button.select-toggle.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}}' ignite-on-enter=btnVisibleAndSave ignite-on-escape='tableReset(false)' tabindex='0')
-
-.panel.panel-default(ng-form=form novalidate)
-    .panel-heading(bs-collapse-toggle='' ng-click='ui.loadPanel("#{form}")')
-        ignite-form-panel-chevron
-        label(id='store-title') Domain model for cache store
-        ignite-form-field-tooltip.tipLabel
-            | Domain model properties for binding database with cache via POJO cache store#[br]
-            | #[a(href="https://apacheignite.readme.io/docs/persistent-store" target="_blank") More info]
-        ignite-form-revert
-    .panel-collapse(role='tabpanel' bs-collapse-target id=form)
-        .panel-body(ng-if='ui.isPanelLoaded("#{form}")')
-            .col-sm-6
-                .settings-row
-                    +text('Database schema:', model + '.databaseSchema', '"databaseSchema"', 'false', 'Input DB schema name', 'Schema name in database')
-                .settings-row
-                    +text('Database table:', model + '.databaseTable', '"databaseTable"', 'false', 'Input DB table name', 'Table name in database')
-                .settings-row(ng-init='keysTbl={type: "table-db-fields", model: "keyFields", focusId: "KeyField", ui: "table-db-fields"}')
-                    +ignite-form-group(ng-form=keyFieldsForm ng-model=keyFields)
-                        ignite-form-field-label(id='keyFields')
-                            | Key fields
-                        ignite-form-group-tooltip
-                            | Collection of key fields descriptions for CacheJdbcPojoStore
-                        ignite-form-group-add(ng-click='tableNewItem(keysTbl)')
-                            | Add key field
-                        .group-content-empty(ng-show='!((#{keyFields} && #{keyFields}.length > 0) || tableNewItemActive(keysTbl))') Not defined
-                        .group-content(ng-show='(#{keyFields} && #{keyFields}.length > 0) || tableNewItemActive(keysTbl)')
-                            table.links-edit(st-table=keyFields)
-                                tbody
-                                    tr(ng-repeat='item in #{keyFields} track by $index')
-                                        td
-                                            div(ng-hide='tableEditing(keysTbl, $index)')
-                                                a.labelFormField(ng-click='tableStartEdit(backupItem, keysTbl, $index)') {{$index + 1}}) {{item.databaseFieldName}} / {{item.databaseFieldType}} / {{item.javaFieldName}} / {{item.javaFieldType}}
-                                                +btn-remove('tableRemove(backupItem, keysTbl, $index)', '"Remove key field"')
-                                            div(ng-if='tableEditing(keysTbl, $index)')
-                                                +table-db-field-edit('keysTbl', 'cur', '{{::keysTbl.focusId + $index}}', '$index')
-                                tfoot(ng-show='tableNewItemActive(keysTbl)')
-                                    tr
-                                        td
-                                            +table-db-field-edit('keysTbl', 'new', 'KeyField', '-1')
-                .settings-row(ng-init='valuesTbl={type: "table-db-fields", model: "valueFields", focusId: "ValueField", ui: "table-db-fields"}')
-                    +ignite-form-group(ng-form=valueFieldsForm ng-model=valueFields)
-                        ignite-form-field-label(id='valueFields')
-                            | Value fields
-                        ignite-form-group-tooltip
-                            | Collection of value fields descriptions for CacheJdbcPojoStore
-                        ignite-form-group-add(ng-click='tableNewItem(valuesTbl)')
-                            | Add value field
-                        .group-content-empty(ng-show='!((#{valueFields} && #{valueFields}.length > 0) || tableNewItemActive(valuesTbl))') Not defined
-                        .group-content(ng-show='(#{valueFields} && #{valueFields}.length > 0) || tableNewItemActive(valuesTbl)')
-                            table.links-edit(st-table=valueFields)
-                                tbody
-                                    tr(ng-repeat='item in #{valueFields} track by $index')
-                                        td
-                                            div(ng-hide='tableEditing(valuesTbl, $index)')
-                                                a.labelFormField(ng-click='tableStartEdit(backupItem, valuesTbl, $index)') {{$index + 1}}) {{item.databaseFieldName}} / {{item.databaseFieldType}} / {{item.javaFieldName}} / {{item.javaFieldType}}
-                                                +btn-remove('tableRemove(backupItem, valuesTbl, $index)', '"Remove key field"')
-                                            div(ng-if='tableEditing(valuesTbl, $index)')
-                                                +table-db-field-edit('valuesTbl', 'cur', '{{::valuesTbl.focusId + $index}}', '$index')
-                                tfoot(ng-show='tableNewItemActive(valuesTbl)')
-                                    tr
-                                        td
-                                            +table-db-field-edit('valuesTbl', 'new', 'ValueField', '-1')
-            .col-sm-6
-                +preview-xml-java(model, 'domainStore')
-

http://git-wip-us.apache.org/repos/asf/ignite/blob/1080e686/modules/web-console/frontend/app/modules/states/configuration/domains/store.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/domains/store.pug b/modules/web-console/frontend/app/modules/states/configuration/domains/store.pug
new file mode 100644
index 0000000..4dee986
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/domains/store.pug
@@ -0,0 +1,127 @@
+//-
+    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.
+
+include /app/helpers/jade/mixins
+
+-var form = 'store'
+-var model = 'backupItem'
+-var keyFields = `${model}.keyFields`
+-var valueFields = `${model}.valueFields`
+-var keyFieldsForm = 'storeKeyFields'
+-var valueFieldsForm = 'storeValueFields'
+
+//- LEGACY mixin for LEGACY db fields tables.
+mixin table-db-field-edit(tbl, prefix, focusId, index)
+    -var databaseName = `${prefix}DatabaseFieldName`
+    -var databaseType = `${prefix}DatabaseFieldType`
+    -var javaName = `${prefix}JavaFieldName`
+    -var javaType = `${prefix}JavaFieldType`
+
+    -var databaseNameModel = `${tbl}.${databaseName}`
+    -var databaseTypeModel = `${tbl}.${databaseType}`
+    -var javaNameModel = `${tbl}.${javaName}`
+    -var javaTypeModel = `${tbl}.${javaType}`
+
+    -var databaseNameId = `${databaseName}${focusId}`
+    -var databaseTypeId = `${databaseType}${focusId}`
+    -var javaNameId = `${javaName}${focusId}`
+    -var javaTypeId = `${javaType}${focusId}`
+
+    .col-xs-3.col-sm-3.col-md-3
+        .fieldSep /
+        .input-tip
+            input.form-control(id=databaseNameId ignite-on-enter-focus-move=databaseTypeId type='text' ng-model=databaseNameModel placeholder='DB name' ignite-on-enter=`${javaNameModel} = ${javaNameModel} ? ${javaNameModel} : ${databaseNameModel}` ignite-on-escape='tableReset(false)')
+    .col-xs-3.col-sm-3.col-md-3
+        .fieldSep /
+        .input-tip
+            button.select-toggle.form-control(id=databaseTypeId ignite-on-enter-focus-move=javaNameId ng-model=databaseTypeModel data-placeholder='DB type' ng-class=`{placeholder: !${databaseTypeModel}}` bs-select bs-options='item.value as item.label for item in {{supportedJdbcTypes}}' ignite-on-escape='tableReset(false)' tabindex='0')
+    .col-xs-3.col-sm-3.col-md-3
+        .fieldSep /
+        .input-tip
+            input.form-control(id=javaNameId ignite-on-enter-focus-move=javaTypeId type='text' ng-model=javaNameModel placeholder='Java name' ignite-on-escape='tableReset(false)')
+    .col-xs-3.col-sm-3.col-md-3
+        -var btnVisible = `tableDbFieldSaveVisible(${tbl}, ${index})`
+        -var btnSave = `tableDbFieldSave(${tbl}, ${index})`
+        -var btnVisibleAndSave = `${btnVisible} && ${btnSave}`
+
+        +btn-save(btnVisible, btnSave)
+        .input-tip
+            button.select-toggle.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}}' ignite-on-enter=btnVisibleAndSave ignite-on-escape='tableReset(false)' tabindex='0')
+
+.panel.panel-default(ng-form=form novalidate)
+    .panel-heading(bs-collapse-toggle='' ng-click=`ui.loadPanel('${form}')`)
+        ignite-form-panel-chevron
+        label(id='store-title') Domain model for cache store
+        ignite-form-field-tooltip.tipLabel
+            | Domain model properties for binding database with cache via POJO cache store#[br]
+            | #[a(href="https://apacheignite.readme.io/docs/persistent-store" target="_blank") More info]
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
+        .panel-body(ng-if=`ui.isPanelLoaded('${form}')`)
+            .col-sm-6
+                .settings-row
+                    +text('Database schema:', model + '.databaseSchema', '"databaseSchema"', 'false', 'Input DB schema name', 'Schema name in database')
+                .settings-row
+                    +text('Database table:', model + '.databaseTable', '"databaseTable"', 'false', 'Input DB table name', 'Table name in database')
+                .settings-row(ng-init='keysTbl={type: "table-db-fields", model: "keyFields", focusId: "KeyField", ui: "table-db-fields"}')
+                    +ignite-form-group(ng-form=keyFieldsForm ng-model=keyFields)
+                        ignite-form-field-label(id='keyFields')
+                            | Key fields
+                        ignite-form-group-tooltip
+                            | Collection of key fields descriptions for CacheJdbcPojoStore
+                        ignite-form-group-add(ng-click='tableNewItem(keysTbl)')
+                            | Add key field
+                        .group-content-empty(ng-show=`!((${keyFields} && ${keyFields}.length > 0) || tableNewItemActive(keysTbl))`) Not defined
+                        .group-content(ng-show=`(${keyFields} && ${keyFields}.length > 0) || tableNewItemActive(keysTbl)`)
+                            table.links-edit(st-table=keyFields)
+                                tbody
+                                    tr(ng-repeat=`item in ${keyFields} track by $index`)
+                                        td
+                                            div(ng-hide='tableEditing(keysTbl, $index)')
+                                                a.labelFormField(ng-click='tableStartEdit(backupItem, keysTbl, $index)') {{$index + 1}}) {{item.databaseFieldName}} / {{item.databaseFieldType}} / {{item.javaFieldName}} / {{item.javaFieldType}}
+                                                +btn-remove('tableRemove(backupItem, keysTbl, $index)', '"Remove key field"')
+                                            div(ng-if='tableEditing(keysTbl, $index)')
+                                                +table-db-field-edit('keysTbl', 'cur', '{{::keysTbl.focusId + $index}}', '$index')
+                                tfoot(ng-show='tableNewItemActive(keysTbl)')
+                                    tr
+                                        td
+                                            +table-db-field-edit('keysTbl', 'new', 'KeyField', '-1')
+                .settings-row(ng-init='valuesTbl={type: "table-db-fields", model: "valueFields", focusId: "ValueField", ui: "table-db-fields"}')
+                    +ignite-form-group(ng-form=valueFieldsForm ng-model=valueFields)
+                        ignite-form-field-label(id='valueFields')
+                            | Value fields
+                        ignite-form-group-tooltip
+                            | Collection of value fields descriptions for CacheJdbcPojoStore
+                        ignite-form-group-add(ng-click='tableNewItem(valuesTbl)')
+                            | Add value field
+                        .group-content-empty(ng-show=`!((${valueFields} && ${valueFields}.length > 0) || tableNewItemActive(valuesTbl))`) Not defined
+                        .group-content(ng-show=`(${valueFields} && ${valueFields}.length > 0) || tableNewItemActive(valuesTbl)`)
+                            table.links-edit(st-table=valueFields)
+                                tbody
+                                    tr(ng-repeat=`item in ${valueFields} track by $index`)
+                                        td
+                                            div(ng-hide='tableEditing(valuesTbl, $index)')
+                                                a.labelFormField(ng-click='tableStartEdit(backupItem, valuesTbl, $index)') {{$index + 1}}) {{item.databaseFieldName}} / {{item.databaseFieldType}} / {{item.javaFieldName}} / {{item.javaFieldType}}
+                                                +btn-remove('tableRemove(backupItem, valuesTbl, $index)', '"Remove key field"')
+                                            div(ng-if='tableEditing(valuesTbl, $index)')
+                                                +table-db-field-edit('valuesTbl', 'cur', '{{::valuesTbl.focusId + $index}}', '$index')
+                                tfoot(ng-show='tableNewItemActive(valuesTbl)')
+                                    tr
+                                        td
+                                            +table-db-field-edit('valuesTbl', 'new', 'ValueField', '-1')
+            .col-sm-6
+                +preview-xml-java(model, 'domainStore')
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/1080e686/modules/web-console/frontend/app/modules/states/configuration/igfs/dual.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/igfs/dual.jade b/modules/web-console/frontend/app/modules/states/configuration/igfs/dual.jade
deleted file mode 100644
index f6ac89f..0000000
--- a/modules/web-console/frontend/app/modules/states/configuration/igfs/dual.jade
+++ /dev/null
@@ -1,42 +0,0 @@
-//-
-    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.
-
-include /app/helpers/jade/mixins.jade
-
--var form = 'dualMode'
--var model = 'backupItem'
-
-.panel.panel-default(ng-form=form novalidate)
-    .panel-heading(bs-collapse-toggle='' ng-click='ui.loadPanel("#{form}")')
-        ignite-form-panel-chevron
-        label Dual mode
-        ignite-form-field-tooltip.tipLabel
-            | IGFS supports dual-mode that allows it to work as either a standalone file system in Hadoop cluster, or work in tandem with HDFS, providing a primary caching layer for the secondary HDFS#[br]
-            | As a caching layer it provides highly configurable read-through and write-through behaviour
-        ignite-form-revert
-    .panel-collapse(role='tabpanel' bs-collapse-target id=form)
-        .panel-body(ng-if='ui.isPanelLoaded("#{form}")')
-            .col-sm-6
-                .settings-row
-                    +number('Maximum pending puts size:', model + '.dualModeMaxPendingPutsSize', '"dualModeMaxPendingPutsSize"', 'true', '0', 'Number.MIN_SAFE_INTEGER',
-                        'Maximum amount of pending data read from the secondary file system and waiting to be written to data cache<br/>\
-                        Zero or negative value stands for unlimited size')
-                .settings-row
-                    +java-class('Put executor service:', model + '.dualModePutExecutorService', '"dualModePutExecutorService"', 'true', 'false', 'DUAL mode put operation executor service')
-                .settings-row
-                    +checkbox('Put executor service shutdown', model + '.dualModePutExecutorServiceShutdown', '"dualModePutExecutorServiceShutdown"', 'DUAL mode put operation executor service shutdown flag')
-            .col-sm-6
-                +preview-xml-java(model, 'igfsDualMode')

http://git-wip-us.apache.org/repos/asf/ignite/blob/1080e686/modules/web-console/frontend/app/modules/states/configuration/igfs/dual.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/igfs/dual.pug b/modules/web-console/frontend/app/modules/states/configuration/igfs/dual.pug
new file mode 100644
index 0000000..613070c
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/igfs/dual.pug
@@ -0,0 +1,42 @@
+//-
+    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.
+
+include /app/helpers/jade/mixins
+
+-var form = 'dualMode'
+-var model = 'backupItem'
+
+.panel.panel-default(ng-form=form novalidate)
+    .panel-heading(bs-collapse-toggle='' ng-click=`ui.loadPanel('${form}')`)
+        ignite-form-panel-chevron
+        label Dual mode
+        ignite-form-field-tooltip.tipLabel
+            | IGFS supports dual-mode that allows it to work as either a standalone file system in Hadoop cluster, or work in tandem with HDFS, providing a primary caching layer for the secondary HDFS#[br]
+            | As a caching layer it provides highly configurable read-through and write-through behaviour
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
+        .panel-body(ng-if=`ui.isPanelLoaded('${form}')`)
+            .col-sm-6
+                .settings-row
+                    +number('Maximum pending puts size:', `${model}.dualModeMaxPendingPutsSize`, '"dualModeMaxPendingPutsSize"', 'true', '0', 'Number.MIN_SAFE_INTEGER',
+                        'Maximum amount of pending data read from the secondary file system and waiting to be written to data cache<br/>\
+                        Zero or negative value stands for unlimited size')
+                .settings-row
+                    +java-class('Put executor service:', `${model}.dualModePutExecutorService`, '"dualModePutExecutorService"', 'true', 'false', 'DUAL mode put operation executor service')
+                .settings-row
+                    +checkbox('Put executor service shutdown', `${model}.dualModePutExecutorServiceShutdown`, '"dualModePutExecutorServiceShutdown"', 'DUAL mode put operation executor service shutdown flag')
+            .col-sm-6
+                +preview-xml-java(model, 'igfsDualMode')

http://git-wip-us.apache.org/repos/asf/ignite/blob/1080e686/modules/web-console/frontend/app/modules/states/configuration/igfs/fragmentizer.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/igfs/fragmentizer.jade b/modules/web-console/frontend/app/modules/states/configuration/igfs/fragmentizer.jade
deleted file mode 100644
index 16f3749..0000000
--- a/modules/web-console/frontend/app/modules/states/configuration/igfs/fragmentizer.jade
+++ /dev/null
@@ -1,43 +0,0 @@
-//-
-    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.
-
-include /app/helpers/jade/mixins.jade
-
--var form = 'fragmentizer'
--var model = 'backupItem'
-
-.panel.panel-default(ng-form=form novalidate)
-    .panel-heading(bs-collapse-toggle='' ng-click='ui.loadPanel("#{form}")')
-        ignite-form-panel-chevron
-        label Fragmentizer
-        ignite-form-field-tooltip.tipLabel
-            | Fragmentizer settings
-        ignite-form-revert
-    .panel-collapse(role='tabpanel' bs-collapse-target id=form)
-        .panel-body(ng-if='ui.isPanelLoaded("#{form}")')
-            .col-sm-6
-                -var enabled = model + '.fragmentizerEnabled'
-
-                .settings-row
-                    +checkbox('Enabled', enabled, '"fragmentizerEnabled"', 'Fragmentizer enabled flag')
-                .settings-row
-                    +number('Concurrent files:', model + '.fragmentizerConcurrentFiles', '"fragmentizerConcurrentFiles"', enabled, '0', '0', 'Number of files to process concurrently by fragmentizer')
-                .settings-row
-                    +number('Throttling block length:', model + '.fragmentizerThrottlingBlockLength', '"fragmentizerThrottlingBlockLength"', enabled, '16777216', '1', 'Length of file chunk to transmit before throttling is delayed')
-                .settings-row
-                    +number('Throttling delay:', model + '.fragmentizerThrottlingDelay', '"fragmentizerThrottlingDelay"', enabled, '200', '0', 'Delay in milliseconds for which fragmentizer is paused')
-            .col-sm-6
-                +preview-xml-java(model, 'igfsFragmentizer')

http://git-wip-us.apache.org/repos/asf/ignite/blob/1080e686/modules/web-console/frontend/app/modules/states/configuration/igfs/fragmentizer.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/igfs/fragmentizer.pug b/modules/web-console/frontend/app/modules/states/configuration/igfs/fragmentizer.pug
new file mode 100644
index 0000000..b112697
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/igfs/fragmentizer.pug
@@ -0,0 +1,43 @@
+//-
+    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.
+
+include /app/helpers/jade/mixins
+
+-var form = 'fragmentizer'
+-var model = 'backupItem'
+
+.panel.panel-default(ng-form=form novalidate)
+    .panel-heading(bs-collapse-toggle='' ng-click=`ui.loadPanel('${form}')`)
+        ignite-form-panel-chevron
+        label Fragmentizer
+        ignite-form-field-tooltip.tipLabel
+            | Fragmentizer settings
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
+        .panel-body(ng-if=`ui.isPanelLoaded('${form}')`)
+            .col-sm-6
+                -var enabled = `${model}.fragmentizerEnabled`
+
+                .settings-row
+                    +checkbox('Enabled', enabled, '"fragmentizerEnabled"', 'Fragmentizer enabled flag')
+                .settings-row
+                    +number('Concurrent files:', `${model}.fragmentizerConcurrentFiles`, '"fragmentizerConcurrentFiles"', enabled, '0', '0', 'Number of files to process concurrently by fragmentizer')
+                .settings-row
+                    +number('Throttling block length:', `${model}.fragmentizerThrottlingBlockLength`, '"fragmentizerThrottlingBlockLength"', enabled, '16777216', '1', 'Length of file chunk to transmit before throttling is delayed')
+                .settings-row
+                    +number('Throttling delay:', `${model}.fragmentizerThrottlingDelay`, '"fragmentizerThrottlingDelay"', enabled, '200', '0', 'Delay in milliseconds for which fragmentizer is paused')
+            .col-sm-6
+                +preview-xml-java(model, 'igfsFragmentizer')

http://git-wip-us.apache.org/repos/asf/ignite/blob/1080e686/modules/web-console/frontend/app/modules/states/configuration/igfs/general.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/igfs/general.jade b/modules/web-console/frontend/app/modules/states/configuration/igfs/general.jade
deleted file mode 100644
index 62cda77..0000000
--- a/modules/web-console/frontend/app/modules/states/configuration/igfs/general.jade
+++ /dev/null
@@ -1,57 +0,0 @@
-//-
-    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.
-
-include /app/helpers/jade/mixins.jade
-
--var form = 'general'
--var model = 'backupItem'
-
-.panel.panel-default(ng-form=form novalidate)
-    .panel-heading(bs-collapse-toggle)
-        ignite-form-panel-chevron
-        label General
-        ignite-form-field-tooltip.tipLabel
-            | General IGFS configuration#[br]
-            | #[a(href="https://apacheignite-fs.readme.io/docs/in-memory-file-system" target="_blank") More info]
-        ignite-form-revert
-    .panel-collapse(role='tabpanel' bs-collapse-target id='general')
-        .panel-body
-            .col-sm-6
-                .settings-row
-                    +text('Name:', model + '.name', '"igfsName"', 'true', 'Input name', 'IGFS name')
-                .settings-row
-                    +clusters(model, 'Associate clusters with the current IGFS')
-                .settings-row
-                    +dropdown('IGFS mode:', model + '.defaultMode', '"defaultMode"', 'true', 'DUAL_ASYNC',
-                    '[\
-                        {value: "PRIMARY", label: "PRIMARY"},\
-                        {value: "PROXY", label: "PROXY"},\
-                        {value: "DUAL_SYNC", label: "DUAL_SYNC"},\
-                        {value: "DUAL_ASYNC", label: "DUAL_ASYNC"}\
-                    ]',
-                    'Mode to specify how IGFS interacts with Hadoop file system\
-                    <ul>\
-                        <li>PRIMARY - in this mode IGFS will not delegate to secondary Hadoop file system and will cache all the files in memory only</li>\
-                        <li>PROXY - in this mode IGFS will not cache any files in memory and will only pass them through to secondary file system</li>\
-                        <li>DUAL_SYNC - in this mode IGFS will cache files locally and also <b>synchronously</b> write them through to secondary file system</li>\
-                        <li>DUAL_ASYNC - in this mode IGFS will cache files locally and also <b> asynchronously </b> write them through to secondary file system</li>\
-                    </ul>')
-                .settings-row
-                    +number('Group size:', model + '.affinnityGroupSize', '"affinnityGroupSize"', 'true', '512', '1',
-                        'Size of the group in blocks<br/>\
-                        Required for construction of affinity mapper in IGFS data cache')
-            .col-sm-6
-                +preview-xml-java(model, 'igfsGeneral')

http://git-wip-us.apache.org/repos/asf/ignite/blob/1080e686/modules/web-console/frontend/app/modules/states/configuration/igfs/general.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/igfs/general.pug b/modules/web-console/frontend/app/modules/states/configuration/igfs/general.pug
new file mode 100644
index 0000000..e002d36
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/igfs/general.pug
@@ -0,0 +1,57 @@
+//-
+    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.
+
+include /app/helpers/jade/mixins
+
+-var form = 'general'
+-var model = 'backupItem'
+
+.panel.panel-default(ng-form=form novalidate)
+    .panel-heading(bs-collapse-toggle)
+        ignite-form-panel-chevron
+        label General
+        ignite-form-field-tooltip.tipLabel
+            | General IGFS configuration#[br]
+            | #[a(href="https://apacheignite-fs.readme.io/docs/in-memory-file-system" target="_blank") More info]
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id='general')
+        .panel-body
+            .col-sm-6
+                .settings-row
+                    +text('Name:', `${model}.name`, '"igfsName"', 'true', 'Input name', 'IGFS name')
+                .settings-row
+                    +clusters(model, 'Associate clusters with the current IGFS')
+                .settings-row
+                    +dropdown('IGFS mode:', `${model}.defaultMode`, '"defaultMode"', 'true', 'DUAL_ASYNC',
+                    '[\
+                        {value: "PRIMARY", label: "PRIMARY"},\
+                        {value: "PROXY", label: "PROXY"},\
+                        {value: "DUAL_SYNC", label: "DUAL_SYNC"},\
+                        {value: "DUAL_ASYNC", label: "DUAL_ASYNC"}\
+                    ]',
+                    'Mode to specify how IGFS interacts with Hadoop file system\
+                    <ul>\
+                        <li>PRIMARY - in this mode IGFS will not delegate to secondary Hadoop file system and will cache all the files in memory only</li>\
+                        <li>PROXY - in this mode IGFS will not cache any files in memory and will only pass them through to secondary file system</li>\
+                        <li>DUAL_SYNC - in this mode IGFS will cache files locally and also <b>synchronously</b> write them through to secondary file system</li>\
+                        <li>DUAL_ASYNC - in this mode IGFS will cache files locally and also <b> asynchronously </b> write them through to secondary file system</li>\
+                    </ul>')
+                .settings-row
+                    +number('Group size:', `${model}.affinnityGroupSize`, '"affinnityGroupSize"', 'true', '512', '1',
+                        'Size of the group in blocks<br/>\
+                        Required for construction of affinity mapper in IGFS data cache')
+            .col-sm-6
+                +preview-xml-java(model, 'igfsGeneral')

http://git-wip-us.apache.org/repos/asf/ignite/blob/1080e686/modules/web-console/frontend/app/modules/states/configuration/igfs/ipc.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/igfs/ipc.jade b/modules/web-console/frontend/app/modules/states/configuration/igfs/ipc.jade
deleted file mode 100644
index 83c5de6..0000000
--- a/modules/web-console/frontend/app/modules/states/configuration/igfs/ipc.jade
+++ /dev/null
@@ -1,60 +0,0 @@
-//-
-    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.
-
-include /app/helpers/jade/mixins.jade
-
--var form = 'ipc'
--var model = 'backupItem'
-
-.panel.panel-default(ng-form=form novalidate)
-    .panel-heading(bs-collapse-toggle='' ng-click='ui.loadPanel("#{form}")')
-        ignite-form-panel-chevron
-        label IPC
-        ignite-form-field-tooltip.tipLabel
-            | IGFS Inter-process communication properties
-        ignite-form-revert
-    .panel-collapse(role='tabpanel' bs-collapse-target id=form)
-        .panel-body(ng-if='ui.isPanelLoaded("#{form}")')
-            .col-sm-6
-                -var ipcEndpointConfiguration = model + '.ipcEndpointConfiguration'
-                -var enabled = model + '.ipcEndpointEnabled'
-
-                .settings-row
-                    +checkbox('Enabled', enabled, '"ipcEndpointEnabled"', 'IPC endpoint enabled flag')
-                .settings-row
-                    +dropdown('Type:', ipcEndpointConfiguration + '.type', '"ipcEndpointConfigurationType"', enabled, 'TCP',
-                        '[\
-                            {value: "SHMEM", label: "SHMEM"},\
-                            {value: "TCP", label: "TCP"}\
-                        ]',
-                        'IPC endpoint type\
-                        <ul>\
-                            <li>SHMEM - shared memory endpoint</li>\
-                            <li>TCP - TCP endpoint</li>\
-                        </ul>')
-                .settings-row
-                    +text-ip-address('Host:', ipcEndpointConfiguration + '.host', '"ipcEndpointConfigurationHost"', enabled, '127.0.0.1', 'Host endpoint is bound to')
-                .settings-row
-                    +number-min-max('Port:', ipcEndpointConfiguration + '.port', '"ipcEndpointConfigurationPort"', enabled, '10500', '1', '65535', 'Port endpoint is bound to')
-                .settings-row
-                    +number('Memory size:', ipcEndpointConfiguration + '.memorySize', '"ipcEndpointConfigurationMemorySize"', enabled, '262144', '1', 'Shared memory size in bytes allocated for endpoint communication')
-                .settings-row
-                    +text-enabled('Token directory:', ipcEndpointConfiguration + '.tokenDirectoryPath', '"ipcEndpointConfigurationTokenDirectoryPath"', enabled, 'false', 'ipc/shmem', 'Directory where shared memory tokens are stored')
-                .settings-row
-                    +number('Thread count:', ipcEndpointConfiguration + '.threadCount', '"ipcEndpointConfigurationThreadCount"', enabled, 'availableProcessors', '1',
-                        'Number of threads used by this endpoint to process incoming requests')
-            .col-sm-6
-                +preview-xml-java(model, 'igfsIPC')

http://git-wip-us.apache.org/repos/asf/ignite/blob/1080e686/modules/web-console/frontend/app/modules/states/configuration/igfs/ipc.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/igfs/ipc.pug b/modules/web-console/frontend/app/modules/states/configuration/igfs/ipc.pug
new file mode 100644
index 0000000..7c8c056
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/igfs/ipc.pug
@@ -0,0 +1,60 @@
+//-
+    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.
+
+include /app/helpers/jade/mixins
+
+-var form = 'ipc'
+-var model = 'backupItem'
+
+.panel.panel-default(ng-form=form novalidate)
+    .panel-heading(bs-collapse-toggle='' ng-click=`ui.loadPanel('${form}')`)
+        ignite-form-panel-chevron
+        label IPC
+        ignite-form-field-tooltip.tipLabel
+            | IGFS Inter-process communication properties
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
+        .panel-body(ng-if=`ui.isPanelLoaded('${form}')`)
+            .col-sm-6
+                -var ipcEndpointConfiguration = `${model}.ipcEndpointConfiguration`
+                -var enabled = `${model}.ipcEndpointEnabled`
+
+                .settings-row
+                    +checkbox('Enabled', enabled, '"ipcEndpointEnabled"', 'IPC endpoint enabled flag')
+                .settings-row
+                    +dropdown('Type:', `${ipcEndpointConfiguration}.type`, '"ipcEndpointConfigurationType"', enabled, 'TCP',
+                        '[\
+                            {value: "SHMEM", label: "SHMEM"},\
+                            {value: "TCP", label: "TCP"}\
+                        ]',
+                        'IPC endpoint type\
+                        <ul>\
+                            <li>SHMEM - shared memory endpoint</li>\
+                            <li>TCP - TCP endpoint</li>\
+                        </ul>')
+                .settings-row
+                    +text-ip-address('Host:', `${ipcEndpointConfiguration}.host`, '"ipcEndpointConfigurationHost"', enabled, '127.0.0.1', 'Host endpoint is bound to')
+                .settings-row
+                    +number-min-max('Port:', `${ipcEndpointConfiguration}.port`, '"ipcEndpointConfigurationPort"', enabled, '10500', '1', '65535', 'Port endpoint is bound to')
+                .settings-row
+                    +number('Memory size:', `${ipcEndpointConfiguration}.memorySize`, '"ipcEndpointConfigurationMemorySize"', enabled, '262144', '1', 'Shared memory size in bytes allocated for endpoint communication')
+                .settings-row
+                    +text-enabled('Token directory:', `${ipcEndpointConfiguration}.tokenDirectoryPath`, '"ipcEndpointConfigurationTokenDirectoryPath"', enabled, 'false', 'ipc/shmem', 'Directory where shared memory tokens are stored')
+                .settings-row
+                    +number('Thread count:', `${ipcEndpointConfiguration}.threadCount`, '"ipcEndpointConfigurationThreadCount"', enabled, 'availableProcessors', '1',
+                        'Number of threads used by this endpoint to process incoming requests')
+            .col-sm-6
+                +preview-xml-java(model, 'igfsIPC')

http://git-wip-us.apache.org/repos/asf/ignite/blob/1080e686/modules/web-console/frontend/app/modules/states/configuration/igfs/misc.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/igfs/misc.jade b/modules/web-console/frontend/app/modules/states/configuration/igfs/misc.jade
deleted file mode 100644
index dc0e9fc..0000000
--- a/modules/web-console/frontend/app/modules/states/configuration/igfs/misc.jade
+++ /dev/null
@@ -1,108 +0,0 @@
-//-
-    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.
-
-include /app/helpers/jade/mixins.jade
-
--var form = 'misc'
--var model = 'backupItem'
--var pathModesForm = 'miscPathModes'
--var pathModes = model + '.pathModes'
-
-//- LEGACY mixin for LEGACY IGFS path modes table.
-mixin table-igfs-path-mode-edit(prefix, focusId, index)
-    -var keyModel = 'tblPathModes.' + prefix + 'Key'
-    -var valModel = 'tblPathModes.' + prefix + 'Value'
-
-    -var keyFocusId = prefix + 'Key' + focusId
-    -var valFocusId = prefix + 'Value' + focusId
-
-    .col-xs-8.col-sm-8.col-md-8
-        .fieldSep /
-        .input-tip
-            input.form-control(id=keyFocusId ignite-on-enter-focus-move=valFocusId type='text' ng-model=keyModel placeholder='Path' ignite-on-escape='tableReset(false)')
-    .col-xs-4.col-sm-4.col-md-4
-        -var arg = keyModel + ', ' + valModel
-        -var btnVisible = 'tablePairSaveVisible(tblPathModes, ' + index + ')'
-        -var btnSave = 'tablePairSave(tablePairValid, backupItem, tblPathModes, ' + index + ')'
-        -var btnVisibleAndSave = btnVisible + ' && ' + btnSave
-        +btn-save(btnVisible, btnSave)
-        .input-tip
-            button.select-toggle.form-control(id=valFocusId bs-select ng-model=valModel data-placeholder='Mode' bs-options='item.value as item.label for item in igfsModes' tabindex='0' ignite-on-enter=btnVisibleAndSave ignite-on-escape='tableReset(false)')
-
-.panel.panel-default(ng-form=form novalidate)
-    .panel-heading(bs-collapse-toggle='' ng-click='ui.loadPanel("#{form}")')
-        ignite-form-panel-chevron
-        label Miscellaneous
-        ignite-form-field-tooltip.tipLabel
-            | Various miscellaneous IGFS settings
-        ignite-form-revert
-    .panel-collapse(role='tabpanel' bs-collapse-target id=form)
-        .panel-body(ng-if='ui.isPanelLoaded("#{form}")')
-            .col-sm-6
-                .settings-row
-                    +number('Block size:', model + '.blockSize', '"blockSize"', 'true', '65536', '0', 'File data block size in bytes')
-                .settings-row
-                    +number('Stream buffer size:', model + '.streamBufferSize', '"streamBufferSize"', 'true', '65536', '0', 'Read/write buffer size for IGFS stream operations in bytes')
-                .settings-row
-                    +number('Maximum space size:', model + '.maxSpaceSize', '"maxSpaceSize"', 'true', '0', '0', 'Maximum space available for data cache to store file system entries')
-                .settings-row
-                    +number('Maximum task range length:', model + '.maximumTaskRangeLength', '"maximumTaskRangeLength"', 'true', '0', '0', 'Maximum default range size of a file being split during IGFS task execution')
-                .settings-row
-                    +number-min-max('Management port:', model + '.managementPort', '"managementPort"', 'true', '11400', '0', '65535', 'Port number for management endpoint')
-                .settings-row
-                    +number('Per node batch size:', model + '.perNodeBatchSize', '"perNodeBatchSize"', 'true', '100', '0', 'Number of file blocks collected on local node before sending batch to remote node')
-                .settings-row
-                    +number('Per node parallel batch count:', model + '.perNodeParallelBatchCount', '"perNodeParallelBatchCount"', 'true', '8', '0', 'Number of file block batches that can be concurrently sent to remote node')
-                .settings-row
-                    +number('Prefetch blocks:', model + '.prefetchBlocks', '"prefetchBlocks"', 'true', '0', '0', 'Number of pre-fetched blocks if specific file chunk is requested')
-                .settings-row
-                    +number('Sequential reads before prefetch:', model + '.sequentialReadsBeforePrefetch', '"sequentialReadsBeforePrefetch"', 'true', '0', '0', 'Amount of sequential block reads before prefetch is triggered')
-                .settings-row
-                    +number('Trash purge timeout:', model + '.trashPurgeTimeout', '"trashPurgeTimeout"', 'true', '1000', '0', 'Maximum timeout awaiting for trash purging in case data cache oversize is detected')
-                .settings-row
-                    +checkbox('Colocate metadata', model + '.colocateMetadata', '"colocateMetadata"', 'Whether to co-locate metadata on a single node')
-                .settings-row
-                    +checkbox('Relaxed consistency', model + '.relaxedConsistency', '"relaxedConsistency"',
-                        'If value of this flag is <b>true</b>, IGFS will skip expensive consistency checks<br/>\
-                        It is recommended to set this flag to <b>false</b> if your application has conflicting\
-                        operations, or you do not know how exactly users will use your system')
-                .settings-row
-                    +ignite-form-group(ng-model=pathModes ng-form=pathModesForm)
-                        ignite-form-field-label
-                            | Path modes
-                        ignite-form-group-tooltip
-                            | Map of path prefixes to IGFS modes used for them
-                        ignite-form-group-add(ng-click='tableNewItem(tblPathModes)')
-                            | Add path mode
-
-                        .group-content-empty(ng-if='!((#{pathModes} && #{pathModes}.length > 0) || tableNewItemActive(tblPathModes))') Not defined
-
-                        .group-content(ng-show='(#{pathModes} && #{pathModes}.length > 0) || tableNewItemActive(tblPathModes)')
-                            table.links-edit(id='pathModes' st-table=pathModes)
-                                tbody
-                                    tr(ng-repeat='item in #{pathModes} track by $index')
-                                        td.col-sm-12(ng-hide='tableEditing(tblPathModes, $index)')
-                                            a.labelFormField(ng-click='tableStartEdit(backupItem, tblPathModes, $index)') {{item.path + " [" + item.mode + "]"}}
-                                            +btn-remove('tableRemove(backupItem, tblPathModes, $index)', '"Remove path"')
-                                        td.col-sm-12(ng-show='tableEditing(tblPathModes, $index)')
-                                            +table-igfs-path-mode-edit('cur', '{{::tblPathModes.focusId + $index}}', '$index')
-                                tfoot(ng-show='tableNewItemActive(tblPathModes)')
-                                    tr
-                                        td.col-sm-12
-                                            +table-igfs-path-mode-edit('new', 'PathMode', '-1')
-
-            .col-sm-6
-                +preview-xml-java(model, 'igfsMisc')

http://git-wip-us.apache.org/repos/asf/ignite/blob/1080e686/modules/web-console/frontend/app/modules/states/configuration/igfs/misc.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/igfs/misc.pug b/modules/web-console/frontend/app/modules/states/configuration/igfs/misc.pug
new file mode 100644
index 0000000..aa4b957
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/igfs/misc.pug
@@ -0,0 +1,108 @@
+//-
+    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.
+
+include /app/helpers/jade/mixins
+
+-var form = 'misc'
+-var model = 'backupItem'
+-var pathModesForm = 'miscPathModes'
+-var pathModes = `${model}.pathModes`
+
+//- LEGACY mixin for LEGACY IGFS path modes table.
+mixin table-igfs-path-mode-edit(prefix, focusId, index)
+    -var keyModel = `tblPathModes.${prefix}Key`
+    -var valModel = `tblPathModes.${prefix}Value`
+
+    -var keyFocusId = `${prefix}Key${focusId}`
+    -var valFocusId = `${prefix}Value${focusId}`
+
+    .col-xs-8.col-sm-8.col-md-8
+        .fieldSep /
+        .input-tip
+            input.form-control(id=keyFocusId ignite-on-enter-focus-move=valFocusId type='text' ng-model=keyModel placeholder='Path' ignite-on-escape='tableReset(false)')
+    .col-xs-4.col-sm-4.col-md-4
+        -var arg = `${keyModel}, ${valModel}`
+        -var btnVisible = `tablePairSaveVisible(tblPathModes, ${index})`
+        -var btnSave = `tablePairSave(tablePairValid, backupItem, tblPathModes, ${index})`
+        -var btnVisibleAndSave = `${btnVisible} && ${btnSave}`
+        +btn-save(btnVisible, btnSave)
+        .input-tip
+            button.select-toggle.form-control(id=valFocusId bs-select ng-model=valModel data-placeholder='Mode' bs-options='item.value as item.label for item in igfsModes' tabindex='0' ignite-on-enter=btnVisibleAndSave ignite-on-escape='tableReset(false)')
+
+.panel.panel-default(ng-form=form novalidate)
+    .panel-heading(bs-collapse-toggle='' ng-click=`ui.loadPanel('${form}')`)
+        ignite-form-panel-chevron
+        label Miscellaneous
+        ignite-form-field-tooltip.tipLabel
+            | Various miscellaneous IGFS settings
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
+        .panel-body(ng-if=`ui.isPanelLoaded('${form}')`)
+            .col-sm-6
+                .settings-row
+                    +number('Block size:', `${model}.blockSize`, '"blockSize"', 'true', '65536', '0', 'File data block size in bytes')
+                .settings-row
+                    +number('Stream buffer size:', `${model}.streamBufferSize`, '"streamBufferSize"', 'true', '65536', '0', 'Read/write buffer size for IGFS stream operations in bytes')
+                .settings-row
+                    +number('Maximum space size:', `${model}.maxSpaceSize`, '"maxSpaceSize"', 'true', '0', '0', 'Maximum space available for data cache to store file system entries')
+                .settings-row
+                    +number('Maximum task range length:', `${model}.maximumTaskRangeLength`, '"maximumTaskRangeLength"', 'true', '0', '0', 'Maximum default range size of a file being split during IGFS task execution')
+                .settings-row
+                    +number-min-max('Management port:', `${model}.managementPort`, '"managementPort"', 'true', '11400', '0', '65535', 'Port number for management endpoint')
+                .settings-row
+                    +number('Per node batch size:', `${model}.perNodeBatchSize`, '"perNodeBatchSize"', 'true', '100', '0', 'Number of file blocks collected on local node before sending batch to remote node')
+                .settings-row
+                    +number('Per node parallel batch count:', `${model}.perNodeParallelBatchCount`, '"perNodeParallelBatchCount"', 'true', '8', '0', 'Number of file block batches that can be concurrently sent to remote node')
+                .settings-row
+                    +number('Prefetch blocks:', `${model}.prefetchBlocks`, '"prefetchBlocks"', 'true', '0', '0', 'Number of pre-fetched blocks if specific file chunk is requested')
+                .settings-row
+                    +number('Sequential reads before prefetch:', `${model}.sequentialReadsBeforePrefetch`, '"sequentialReadsBeforePrefetch"', 'true', '0', '0', 'Amount of sequential block reads before prefetch is triggered')
+                .settings-row
+                    +number('Trash purge timeout:', `${model}.trashPurgeTimeout`, '"trashPurgeTimeout"', 'true', '1000', '0', 'Maximum timeout awaiting for trash purging in case data cache oversize is detected')
+                .settings-row
+                    +checkbox('Colocate metadata', `${model}.colocateMetadata`, '"colocateMetadata"', 'Whether to co-locate metadata on a single node')
+                .settings-row
+                    +checkbox('Relaxed consistency', `${model}.relaxedConsistency`, '"relaxedConsistency"',
+                        'If value of this flag is <b>true</b>, IGFS will skip expensive consistency checks<br/>\
+                        It is recommended to set this flag to <b>false</b> if your application has conflicting\
+                        operations, or you do not know how exactly users will use your system')
+                .settings-row
+                    +ignite-form-group(ng-model=pathModes ng-form=pathModesForm)
+                        ignite-form-field-label
+                            | Path modes
+                        ignite-form-group-tooltip
+                            | Map of path prefixes to IGFS modes used for them
+                        ignite-form-group-add(ng-click='tableNewItem(tblPathModes)')
+                            | Add path mode
+
+                        .group-content-empty(ng-if=`!((${pathModes} && ${pathModes}.length > 0) || tableNewItemActive(tblPathModes))`) Not defined
+
+                        .group-content(ng-show=`(${pathModes} && ${pathModes}.length > 0) || tableNewItemActive(tblPathModes)`)
+                            table.links-edit(id='pathModes' st-table=pathModes)
+                                tbody
+                                    tr(ng-repeat=`item in ${pathModes} track by $index`)
+                                        td.col-sm-12(ng-hide='tableEditing(tblPathModes, $index)')
+                                            a.labelFormField(ng-click='tableStartEdit(backupItem, tblPathModes, $index)') {{item.path + " [" + item.mode + "]"}}
+                                            +btn-remove('tableRemove(backupItem, tblPathModes, $index)', '"Remove path"')
+                                        td.col-sm-12(ng-show='tableEditing(tblPathModes, $index)')
+                                            +table-igfs-path-mode-edit('cur', '{{::tblPathModes.focusId + $index}}', '$index')
+                                tfoot(ng-show='tableNewItemActive(tblPathModes)')
+                                    tr
+                                        td.col-sm-12
+                                            +table-igfs-path-mode-edit('new', 'PathMode', '-1')
+
+            .col-sm-6
+                +preview-xml-java(model, 'igfsMisc')

http://git-wip-us.apache.org/repos/asf/ignite/blob/1080e686/modules/web-console/frontend/app/modules/states/configuration/igfs/secondary.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/igfs/secondary.jade b/modules/web-console/frontend/app/modules/states/configuration/igfs/secondary.jade
deleted file mode 100644
index b605e77..0000000
--- a/modules/web-console/frontend/app/modules/states/configuration/igfs/secondary.jade
+++ /dev/null
@@ -1,45 +0,0 @@
-//-
-    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.
-
-include /app/helpers/jade/mixins.jade
-
--var form = 'secondaryFileSystem'
--var model = 'backupItem'
-
-.panel.panel-default(ng-form=form novalidate)
-    .panel-heading(bs-collapse-toggle='' ng-click='ui.loadPanel("#{form}")')
-        ignite-form-panel-chevron
-        label(id="secondaryFileSystem-title") Secondary file system
-        ignite-form-field-tooltip.tipLabel
-            | Secondary file system is provided for pass-through, write-through, and read-through purposes#[br]
-            | #[a(href="https://apacheignite-fs.readme.io/docs/secondary-file-system" target="_blank") More info]
-        ignite-form-revert
-    .panel-collapse(role='tabpanel' bs-collapse-target id=form)
-        .panel-body(ng-if='ui.isPanelLoaded("#{form}")')
-            .col-sm-6
-                -var enabled = model + '.secondaryFileSystemEnabled'
-                -var secondaryFileSystem = model + '.secondaryFileSystem'
-
-                .settings-row
-                    +checkbox('Enabled', enabled, '"secondaryFileSystemEnabled"', 'Secondary file system enabled flag')
-                .settings-row
-                    +text-enabled('URI:', secondaryFileSystem + '.uri', '"hadoopURI"', enabled, 'false', 'hdfs://[namenodehost]:[port]/[path]', 'URI of file system')
-                .settings-row
-                    +text-enabled('Config path:', secondaryFileSystem + '.cfgPath', '"cfgPath"', enabled, 'false', 'Path to additional config', 'Additional path to Hadoop configuration')
-                .settings-row
-                    +text-enabled('User name:', secondaryFileSystem + '.userName', '"userName"', enabled, 'false', 'Input user name', 'User name')
-            .col-sm-6
-                +preview-xml-java(model, 'igfsSecondFS')

http://git-wip-us.apache.org/repos/asf/ignite/blob/1080e686/modules/web-console/frontend/app/modules/states/configuration/igfs/secondary.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/igfs/secondary.pug b/modules/web-console/frontend/app/modules/states/configuration/igfs/secondary.pug
new file mode 100644
index 0000000..87e1f4f
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/igfs/secondary.pug
@@ -0,0 +1,45 @@
+//-
+    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.
+
+include /app/helpers/jade/mixins
+
+-var form = 'secondaryFileSystem'
+-var model = 'backupItem'
+
+.panel.panel-default(ng-form=form novalidate)
+    .panel-heading(bs-collapse-toggle='' ng-click=`ui.loadPanel('${form}')`)
+        ignite-form-panel-chevron
+        label(id="secondaryFileSystem-title") Secondary file system
+        ignite-form-field-tooltip.tipLabel
+            | Secondary file system is provided for pass-through, write-through, and read-through purposes#[br]
+            | #[a(href="https://apacheignite-fs.readme.io/docs/secondary-file-system" target="_blank") More info]
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id=`${form}`)
+        .panel-body(ng-if=`ui.isPanelLoaded('${form}')`)
+            .col-sm-6
+                -var enabled = `${model}.secondaryFileSystemEnabled`
+                -var secondaryFileSystem = `${model}.secondaryFileSystem`
+
+                .settings-row
+                    +checkbox('Enabled', enabled, '"secondaryFileSystemEnabled"', 'Secondary file system enabled flag')
+                .settings-row
+                    +text-enabled('URI:', `${secondaryFileSystem}.uri`, '"hadoopURI"', enabled, 'false', 'hdfs://[namenodehost]:[port]/[path]', 'URI of file system')
+                .settings-row
+                    +text-enabled('Config path:', `${secondaryFileSystem}.cfgPath`, '"cfgPath"', enabled, 'false', 'Path to additional config', 'Additional path to Hadoop configuration')
+                .settings-row
+                    +text-enabled('User name:', `${secondaryFileSystem}.userName`, '"userName"', enabled, 'false', 'Input user name', 'User name')
+            .col-sm-6
+                +preview-xml-java(model, 'igfsSecondFS')

http://git-wip-us.apache.org/repos/asf/ignite/blob/1080e686/modules/web-console/frontend/app/modules/states/configuration/summary/summary.controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/summary/summary.controller.js b/modules/web-console/frontend/app/modules/states/configuration/summary/summary.controller.js
index 16d2fae..25203b3 100644
--- a/modules/web-console/frontend/app/modules/states/configuration/summary/summary.controller.js
+++ b/modules/web-console/frontend/app/modules/states/configuration/summary/summary.controller.js
@@ -18,6 +18,8 @@
 import _ from 'lodash';
 import saver from 'file-saver';
 
+import summaryProjectStructureTemplateUrl from 'views/configuration/summary-project-structure.tpl.pug';
+
 const escapeFileName = (name) => name.replace(/[\\\/*\"\[\],\.:;|=<>?]/g, '-').replace(/ /g, '_');
 
 export default [
@@ -25,6 +27,9 @@ export default [
     function($root, $scope, $http, LegacyUtils, Messages, Loading, $filter, Resource, JavaTypes, Version, generator, spring, java, docker, pom, propsGenerator, readme, FormUtils, SummaryZipper, ActivitiesData) {
         const ctrl = this;
 
+        // Define template urls.
+        ctrl.summaryProjectStructureTemplateUrl = summaryProjectStructureTemplateUrl;
+
         $scope.ui = {
             isSafari: !!(/constructor/i.test(window.HTMLElement) || window.safari),
             ready: false

http://git-wip-us.apache.org/repos/asf/ignite/blob/1080e686/modules/web-console/frontend/app/modules/states/errors.state.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/errors.state.js b/modules/web-console/frontend/app/modules/states/errors.state.js
index 2bdb80a..e219132 100644
--- a/modules/web-console/frontend/app/modules/states/errors.state.js
+++ b/modules/web-console/frontend/app/modules/states/errors.state.js
@@ -16,8 +16,8 @@
  */
 
 import angular from 'angular';
-import templateNotFoundPage from '../../../views/404.jade';
-import templateNotAuthorizedPage from '../../../views/403.jade';
+import templateNotFoundPage from 'views/404.pug';
+import templateNotAuthorizedPage from 'views/403.pug';
 
 angular
     .module('ignite-console.states.errors', [

http://git-wip-us.apache.org/repos/asf/ignite/blob/1080e686/modules/web-console/frontend/app/modules/states/password.state.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/password.state.js b/modules/web-console/frontend/app/modules/states/password.state.js
index 48d01df..587f83d 100644
--- a/modules/web-console/frontend/app/modules/states/password.state.js
+++ b/modules/web-console/frontend/app/modules/states/password.state.js
@@ -17,6 +17,8 @@
 
 import angular from 'angular';
 
+import templateUrl from 'views/reset.tpl.pug';
+
 angular
 .module('ignite-console.states.password', [
     'ui.router'
@@ -31,14 +33,14 @@ angular
     })
     .state('password.reset', {
         url: '/reset?{token}',
-        templateUrl: '/reset.html',
+        templateUrl,
         metaTags: {
             title: 'Reset password'
         }
     })
     .state('password.send', {
         url: '/send',
-        templateUrl: '/reset.html',
+        templateUrl,
         metaTags: {
             title: 'Password Send'
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1080e686/modules/web-console/frontend/app/modules/states/profile.state.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/profile.state.js b/modules/web-console/frontend/app/modules/states/profile.state.js
index 9c31340..7c270ad 100644
--- a/modules/web-console/frontend/app/modules/states/profile.state.js
+++ b/modules/web-console/frontend/app/modules/states/profile.state.js
@@ -17,6 +17,8 @@
 
 import angular from 'angular';
 
+import templateUrl from 'views/settings/profile.tpl.pug';
+
 angular
 .module('ignite-console.states.profile', [
     'ui.router'
@@ -26,7 +28,7 @@ angular
     $stateProvider
     .state('settings.profile', {
         url: '/profile',
-        templateUrl: '/settings/profile.html',
+        templateUrl,
         onEnter: AclRoute.checkAccess('profile'),
         metaTags: {
             title: 'User profile'

http://git-wip-us.apache.org/repos/asf/ignite/blob/1080e686/modules/web-console/frontend/app/modules/states/signin.state.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/signin.state.js b/modules/web-console/frontend/app/modules/states/signin.state.js
index 14ebc1b..2625aaa 100644
--- a/modules/web-console/frontend/app/modules/states/signin.state.js
+++ b/modules/web-console/frontend/app/modules/states/signin.state.js
@@ -16,7 +16,7 @@
  */
 
 import angular from 'angular';
-import templateUrl from 'views/signin.jade';
+import templateUrl from 'views/signin.tpl.pug';
 
 angular
 .module('ignite-console.states.login', [