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

[03/18] ignite git commit: IGNITE-843 Web console initial commit.

http://git-wip-us.apache.org/repos/asf/ignite/blob/bce0deb7/modules/control-center-web/src/main/js/views/sql/notebook-new.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/sql/notebook-new.jade b/modules/control-center-web/src/main/js/views/sql/notebook-new.jade
new file mode 100644
index 0000000..15db4dc
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/sql/notebook-new.jade
@@ -0,0 +1,31 @@
+//-
+    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.
+
+.modal(tabindex='-1' role='dialog')
+    .modal-dialog
+        .modal-content
+            .modal-header
+                button.close(ng-click='$hide()') ×
+                h4.modal-title New SQL notebook
+            form.form-horizontal(name='ui.inputForm' novalidate)
+                .modal-body.row
+                    .col-sm-9.login.col-sm-offset-1
+                        label.required.labelFormField Name: 
+                        .col-sm-9
+                            input.form-control(id='create-notebook' type='text' ng-model='name' required on-enter='ui.inputForm.$valid && createNewNotebook(name)' auto-focus)
+            .modal-footer
+                button.btn.btn-default(id='copy-btn-cancel' ng-click='$hide()') Cancel
+                button.btn.btn-primary(id='copy-btn-confirm' ng-disabled='ui.inputForm.$invalid' ng-click='createNewNotebook(name)') Create

http://git-wip-us.apache.org/repos/asf/ignite/blob/bce0deb7/modules/control-center-web/src/main/js/views/sql/paragraph-rate.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/sql/paragraph-rate.jade b/modules/control-center-web/src/main/js/views/sql/paragraph-rate.jade
new file mode 100644
index 0000000..689fd24
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/sql/paragraph-rate.jade
@@ -0,0 +1,31 @@
+//-
+    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.
+
+.popover.settings(tabindex='-1' style='width: 200px')
+    .arrow
+    h3.popover-title(style='color: black') Refresh rate
+    button.close(id='paragraph-rate-close' ng-click='$hide()') ×
+    .popover-content
+        form(name='popoverForm')
+            .form-group(style='padding: 5px')
+                .col-sm-4
+                    input.form-control(id='paragraph-rate' ng-init='value = paragraph.rate.value' ng-model='value' type='number' min='1' required auto-focus)
+                .col-sm-8(style='padding-left: 5px')
+                    button.form-control.select-toggle(id='paragraph-unit' ng-init='unit = paragraph.rate.unit' ng-model='unit' required placeholder='Time unit' bs-select bs-options='item.value as item.label for item in timeUnit' data-container='false' tabindex='0')
+            .form-actions(style='margin-top: 30px; padding: 5px')
+                button.btn.btn-primary(id='paragraph-rate-start' ng-disabled='popoverForm.$invalid' ng-click='startRefresh(paragraph, value, unit); $hide()') Start
+                button.btn.btn-primary.btn-default(id='paragraph-rate-stop' ng-click='stopRefresh(paragraph); $hide()' ng-disabled='!paragraph.rate.installed') Stop
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/bce0deb7/modules/control-center-web/src/main/js/views/sql/sql.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/sql/sql.jade b/modules/control-center-web/src/main/js/views/sql/sql.jade
new file mode 100644
index 0000000..de58686
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/sql/sql.jade
@@ -0,0 +1,173 @@
+//-
+    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.
+
+extends ../templates/layout
+
+append css
+    link(rel='stylesheet', href='//cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.1/nv.d3.css')
+append scripts
+    script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/mode-sql.js')
+    script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ext-language_tools.js')
+
+    script(src='//cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js')
+    script(src='//cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.1/nv.d3.min.js')
+
+    script(src='/sql-controller.js')
+
+mixin btn-toolbar(btn, click, tip)
+    i.btn.btn-default.fa(class=btn ng-click=click bs-tooltip='' data-title=tip data-trigger='hover' data-placement='bottom')
+
+mixin btn-toolbar-data(btn, kind, tip)
+    i.btn.btn-default.fa(class=btn ng-click='setResult(paragraph, "#{kind}")' ng-class='{active: resultEq(paragraph, "#{kind}")}' bs-tooltip='' data-title=tip data-trigger='hover' data-placement='bottom')
+
+block container
+    .row
+        .col-sm-12(ng-init='noteId = "#{noteId}"')
+            .docs-content(ng-controller='sqlController' )
+                div(bs-affix)
+                    .docs-header.notebook-header
+                        h1.col-sm-6(ng-hide='notebook.edit')
+                            label {{notebook.name}}
+                            .btn-group
+                                +btn-toolbar('fa-pencil', 'notebook.edit = true;notebook.editName = notebook.name', 'Rename notebook')
+                                +btn-toolbar('fa-trash', 'removeNotebook()', 'Remove notebook')
+                        h1.col-sm-6(ng-show='notebook.edit')
+                            input.sql-name-input(ng-model='notebook.editName' required on-enter='renameNotebook(notebook.editName)' on-escape='notebook.edit = false;')
+                            i.tipLabel.fa.fa-floppy-o(ng-show='notebook.editName' ng-click='renameNotebook(notebook.editName)' bs-tooltip data-title='Save notebook name' data-trigger='hover')
+                        .pull-right
+                            +btn-toolbar('fa-plus', 'addParagraph()', 'Add new query')
+                .block-callout-parent
+                    table
+                        tbody
+                            tr
+                                td.block-callout-left(width='50%')
+                                    i.fa.fa-check-square.block-callout-header-left
+                                    label.block-callout-header-left With SQL Notebook you can:
+                                    ul
+                                        li Create any number of queries
+                                        li Execute and explain SQL queries
+                                        li Execute scan queries
+                                        li View data in tabular form and as charts
+                                td.block-callout-right(width='50%')
+                                    i.fa.fa-check-square.block-callout-header-right
+                                    label.block-callout-header-right To execute SQL you need:
+                                    ul
+                                        li Start Apache Ignite Cluster with caches
+                                        li Populate caches with data
+                                        li Start Apache Ignite Web Agent
+                                        li Create query, enter some SQL and execute it
+                hr
+                .docs-body.paragraphs
+                    .panel-group(bs-collapse ng-model='notebook.expandedParagraphs' data-allow-multiple='true' data-start-collapsed='false')
+                        .panel.panel-default(ng-repeat='paragraph in notebook.paragraphs')
+                            .panel-heading(bs-collapse-toggle)
+                                div(ng-hide='paragraph.edit')
+                                    a {{paragraph.name}}
+
+                                    .btn-group(ng-hide='notebook.paragraphs.length > 1')
+                                        +btn-toolbar('fa-pencil', 'paragraph.edit = true; paragraph.editName = paragraph.name; $event.stopPropagation();', 'Rename query')
+
+                                    .btn-group(ng-show='notebook.paragraphs.length > 1' ng-click='$event.stopPropagation();')
+                                        +btn-toolbar('fa-pencil', 'paragraph.edit = true; paragraph.editName = paragraph.name;', 'Rename query')
+                                        +btn-toolbar('fa-remove', 'removeParagraph(paragraph)', 'Remove query')
+
+                                    .pull-right
+                                        .btn-group(ng-model='paragraph.result' ng-click='$event.stopPropagation()' style='float: right')
+                                            +btn-toolbar-data('fa-table', 'table', 'Show data in tabular form.')
+                                            +btn-toolbar-data('fa-bar-chart', 'bar', 'Show bar chart.<br/>By default first column - X values, second column - Y values.<br/>In case of one column it will be treated as Y values.')
+                                            +btn-toolbar-data('fa-pie-chart', 'pie', 'Show pie chart.<br/>By default first column - pie labels, second column - pie values.<br/>In case of one column it will be treated as pie values.')
+                                            +btn-toolbar-data('fa-line-chart', 'line', 'Show line chart.<br/>By default first column - X values, second column - Y values.<br/>In case of one column it will be treated as Y values.')
+                                            +btn-toolbar-data('fa-area-chart', 'area', 'Show area chart.<br/>By default first column - X values, second column - Y values.<br/>In case of one column it will be treated as Y values.')
+                                div(ng-show='paragraph.edit')
+                                    input.sql-name-input(ng-model='paragraph.editName' required ng-click='$event.stopPropagation();' on-enter='renameParagraph(paragraph, paragraph.editName)' on-escape='paragraph.edit = false')
+                                    i.tipLabel.fa.fa-floppy-o(ng-show='paragraph.editName' ng-click='renameParagraph(paragraph, paragraph.editName); $event.stopPropagation();' bs-tooltip data-title='Save paragraph name' data-trigger='hover')
+                            .panel-collapse(role='tabpanel' bs-collapse-target)
+                                .col-sm-12(ng-show='paragraph.editor')
+                                    .col-xs-8.col-sm-9(style='border-right: 1px solid #eee')
+                                        .sql-editor(ui-ace='{onLoad: aceInit(paragraph), theme: "chrome", mode: "sql", require: ["ace/ext/language_tools"],' +
+                                            'advanced: {enableSnippets: false, enableBasicAutocompletion: true, enableLiveAutocompletion: true}}'
+                                        ng-model='paragraph.query')
+                                    .col-xs-4.col-sm-3
+                                        div(ng-show='caches.length > 0' style='padding: 5px 10px' st-table='displayedCaches' st-safe-src='caches')
+                                            lable.labelField.labelFormField Caches:
+                                            .input-tip
+                                                input.form-control(type='text' st-search placeholder='Filter caches...')
+                                            table.links
+                                                tbody.scrollable-y(style='max-height: 15em;display:block;' ng-model='paragraph.cacheName' bs-radio-group)
+                                                    tr(ng-repeat='cache in displayedCaches track by cache.name')
+                                                        td(style='width: 100%')
+                                                            input.labelField(type='radio' value='{{cache.name}}')
+                                                            a(bs-popover data-template-url='cache-metadata', data-placement='bottom', data-trigger='click') {{cache.name}}
+                                        .empty-caches(ng-show='displayedCaches.length == 0 && caches.length != 0')
+                                            label Wrong caches filter
+                                        .empty-caches(ng-show='caches.length == 0')
+                                            label No caches
+                                .col-sm-12
+                                    hr(style='margin: 0')
+                                .col-sm-12
+                                    .details-row
+                                        a.btn.btn-primary(ng-disabled='!actionAvailable(paragraph, true)' ng-click='actionAvailable(paragraph, true) ? explain(paragraph) : ""' data-placement='bottom' bs-tooltip data-title='{{actionTooltip(paragraph, "explain", true)}}') Explain
+                                        a.btn.btn-primary(ng-disabled='!actionAvailable(paragraph, true)' ng-click='actionAvailable(paragraph, true) ? execute(paragraph) : ""' data-placement='bottom' bs-tooltip data-title='{{actionTooltip(paragraph, "execute", true)}}') Execute
+                                        a.btn.btn-primary(ng-disabled='!actionAvailable(paragraph, false)' ng-click='actionAvailable(paragraph, false) ? scan(paragraph): ""' data-placement='bottom' bs-tooltip data-title='{{actionTooltip(paragraph, "execute scan", false)}}') Scan
+                                        .pull-right
+                                            labelHide System columns:
+                                            a.btn.btn-default.fa.fa-bars.tipLabel(ng-class='{"btn-info": paragraph.systemColumns}' ng-click='toggleSystemColumns(paragraph)' ng-disabled='paragraph.disabledSystemColumns')
+                                            label.tipLabel Refresh rate:
+                                            button.btn.btn-default.fa.fa-clock-o.tipLabel(ng-class='{"btn-info": paragraph.rate && paragraph.rate.installed}' bs-popover data-template-url='rate' data-placement='left' data-auto-close='1' data-trigger='click') {{rateAsString(paragraph)}}
+                                            label.tipLabel Page size:
+                                            button.select-toggle.fieldButton.btn.btn-default(ng-model='paragraph.pageSize' bs-options='item for item in pageSizes' bs-select)
+                                .col-sm-12(ng-show='paragraph.errMsg')
+                                    hr(style='margin-top: 0; margin-bottom: 10px')
+                                    .sql-error-result(ng-show='paragraph.errMsg') Error: {{paragraph.errMsg}}
+                                .col-sm-12(ng-show='!paragraph.errMsg && paragraph.result != "none"')
+                                    hr(style='margin-top: 0; margin-bottom: 10px')
+                                    .sql-empty-result(ng-show='!paragraph.nonEmpty()') Result set is empty
+                                    div(ng-show='paragraph.table() && paragraph.nonEmpty()')
+                                        .sql-table-total
+                                            label Page #&nbsp;
+                                            b {{paragraph.page}}&nbsp;&nbsp;&nbsp;
+                                            label Results so far:&nbsp;
+                                            b {{paragraph.rows.length + paragraph.total}}
+                                            .pull-right
+                                                .btn-group(ng-disabled='paragraph.loading')
+                                                    button.btn.btn-primary.fieldButton(ng-click='exportPage(paragraph)' bs-tooltip data-title='{{actionTooltip(paragraph, "export", false)}}') Export
+                                                    button.btn.btn-primary(id='export-item-dropdown' data-toggle='dropdown' data-container='body' bs-dropdown='exportDropdown' data-placement='bottom-right')
+                                                        span.caret
+                                        .sql-table.ag-bootstrap(ag-grid='paragraph.gridOptions')
+                                    div(ng-show='paragraph.chart() && paragraph.nonEmpty()')
+                                        div(ng-show='paragraph.queryExecute()')
+                                            div(ng-hide='paragraph.chartColumnsConfigured()')
+                                                .chart-settings-link
+                                                    i.fa.fa-chevron-circle-down
+                                                    a(ng-show='paragraph.chart' ng-click='$event.stopPropagation()' bs-popover data-template-url='chart-settings' data-placement='bottom' data-auto-close='1' data-trigger='click') Chart settings
+                                                .sql-empty-result Can't display chart. Need configure axis using&nbsp
+                                                    b Chart settings
+                                            div(ng-show='paragraph.chartColumnsConfigured()')
+                                                div(ng-show='paragraph.timeLineSupported() || !paragraph.chartTimeLineEnabled()')
+                                                    .chart-settings-link
+                                                        i.fa.fa-chevron-circle-down
+                                                        a(ng-show='paragraph.chart' ng-click='$event.stopPropagation()' bs-popover data-template-url='chart-settings' data-placement='bottom' data-auto-close='1' data-trigger='click') Chart settings
+                                                    div(ng-repeat='chart in paragraph.charts')
+                                                        nvd3(options='chart.options' data='chart.data' api='chart.api')
+                                                .sql-empty-result(ng-show='!paragraph.timeLineSupported() && paragraph.chartTimeLineEnabled()') Pie chart does not support 'TIME_LINE' column for X-axis
+                                        .sql-empty-result(ng-hide='paragraph.queryExecute()')
+                                            | Charts do not support&nbsp
+                                            b Explain
+                                            | &nbspand&nbsp
+                                            b Scan
+                                            | &nbspquery
+                                    div(ng-show='paragraph.queryId && (paragraph.table() || paragraph.chart() && paragraph.queryExecute())')
+                                        hr(style='margin-top: 0; margin-bottom: 5px')
+                                        i.fa.fa-chevron-circle-right(style='float: right;margin-right: 10px;' ng-click='nextPage(paragraph)')
+                                        a(style='float: right; margin-bottom: 5px;margin-right: 5px;' ng-click='nextPage(paragraph)') Next

http://git-wip-us.apache.org/repos/asf/ignite/blob/bce0deb7/modules/control-center-web/src/main/js/views/templates/agent-download.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/templates/agent-download.jade b/modules/control-center-web/src/main/js/views/templates/agent-download.jade
new file mode 100644
index 0000000..47b0940
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/templates/agent-download.jade
@@ -0,0 +1,49 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+         http://www.apache.org/licenses/LICENSE-2.0
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+.modal.center(tabindex='-1' role='dialog')
+    .modal-dialog
+        .modal-content
+            #errors-container.modal-header.header
+                button.close(ng-if='!checkConnection' ng-click='$hide()') &times;
+                h4.modal-title Connection to Ignite Web Agent is not established
+            .agent-download
+                p Please download and run&nbsp;
+                    a(href='javascript:void(0)' ng-click='downloadAgent()') ignite-web-agent
+                    | &nbsp;in order to {{::agentGoal}}.
+                p For installation:
+                ul
+                    li Download and unzip&nbsp;
+                        b ignite-web-agent
+                        | .
+                    li For list of options, run&nbsp;
+                        b ignite-web-agent.{sh|bat} --help
+                        | .
+                    li To test drive, run&nbsp;
+                        b ignite-web-agent.{sh|bat} {{::agentTestDriveOption}}
+                        | .
+                    li Refer to&nbsp;
+                        b README.txt
+                        | &nbsp;for more information.
+                .modal-advanced-options
+                    i.fa.fa-chevron-circle-up(ng-show='agentLoad.showToken' ng-click='agentLoad.showToken = ! agentLoad.showToken')
+                    i.fa.fa-chevron-circle-down(ng-show='!agentLoad.showToken' ng-click='agentLoad.showToken = ! agentLoad.showToken')
+                    a(ng-click='agentLoad.showToken = ! agentLoad.showToken') {{agentLoad.showToken ? 'Hide security token...' : 'Show security token...'}}
+                .details-row(ng-show='agentLoad.showToken')
+                    label.labelField Security token: {{user.token}}
+                    i.tipLabel.fa.fa-clipboard(ng-click-copy='{{user.token}}' bs-tooltip='' data-title='Copy security token to clipboard')
+                    i.tipLabel.fa.fa-question-circle(ng-if=lines bs-tooltip='' data-title='The security token is used for authorization of web agent')
+            .modal-footer
+                button.btn.btn-default(ng-if='checkConnection' ng-click='goHome()') Back to Configuration
+                button.btn.btn-primary(ng-click='downloadAgent()') Download zip

http://git-wip-us.apache.org/repos/asf/ignite/blob/bce0deb7/modules/control-center-web/src/main/js/views/templates/batch-confirm.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/templates/batch-confirm.jade b/modules/control-center-web/src/main/js/views/templates/batch-confirm.jade
new file mode 100644
index 0000000..a4d7681
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/templates/batch-confirm.jade
@@ -0,0 +1,32 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+.modal(tabindex='-1' role='dialog')
+    .modal-dialog
+        .modal-content
+            .modal-header
+                button.close(ng-click='cancel()' aria-hidden='true') &times;
+                h4.modal-title Confirmation
+            .modal-body(ng-show='batchConfirm.content')
+                p(ng-bind-html='batchConfirm.content' style='text-align: center')
+            .modal-footer
+                .checkbox.labelField
+                    label
+                        input(type='checkbox' ng-model='batchConfirm.applyToAll')
+                        | Apply to all
+                button.btn.btn-default(id='batch-confirm-btn-cancel' ng-click='batchConfirm.cancel()') Cancel
+                button.btn.btn-default(id='batch-confirm-btn-cancel' ng-click='batchConfirm.skip()') Skip
+                button.btn.btn-primary(id='batch-confirm-btn-overwrite' ng-click='batchConfirm.overwrite()') Overwrite

http://git-wip-us.apache.org/repos/asf/ignite/blob/bce0deb7/modules/control-center-web/src/main/js/views/templates/clone.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/templates/clone.jade b/modules/control-center-web/src/main/js/views/templates/clone.jade
new file mode 100644
index 0000000..be33821
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/templates/clone.jade
@@ -0,0 +1,32 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+.modal(tabindex='-1' role='dialog')
+    .modal-dialog
+        .modal-content
+            .modal-header
+                button.close(ng-click='$hide()') &times;
+                h4.modal-title Clone
+            form.form-horizontal(name='ui.inputForm' novalidate)
+                .modal-body.row
+                    .login
+                        .col-sm-3
+                            label.required.labelFormField New name:&nbsp;
+                        .col-sm-9
+                            input.form-control(id='copy-new-name' type='text' ng-model='newName' required auto-focus)
+            .modal-footer
+                button.btn.btn-default(id='copy-btn-cancel' ng-click='$hide()') Cancel
+                button.btn.btn-primary(id='copy-btn-confirm' ng-disabled='ui.inputForm.$invalid' ng-click='ok(newName)') Confirm

http://git-wip-us.apache.org/repos/asf/ignite/blob/bce0deb7/modules/control-center-web/src/main/js/views/templates/confirm.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/templates/confirm.jade b/modules/control-center-web/src/main/js/views/templates/confirm.jade
new file mode 100644
index 0000000..b0acc1d
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/templates/confirm.jade
@@ -0,0 +1,27 @@
+//-
+    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.
+
+.modal(tabindex='-1' role='dialog')
+    .modal-dialog
+        .modal-content
+            .modal-header
+                button.close(ng-click='confirmCancel()' aria-hidden='true') &times;
+                h4.modal-title Confirmation
+            .modal-body(ng-show='content')
+                p(ng-bind-html='content' style='text-align: center;')
+            .modal-footer
+                button.btn.btn-default(id='confirm-btn-cancel' ng-click='confirmCancel()') Cancel
+                button.btn.btn-primary(id='confirm-btn-confirm' ng-click='confirmOk()') Confirm

http://git-wip-us.apache.org/repos/asf/ignite/blob/bce0deb7/modules/control-center-web/src/main/js/views/templates/layout.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/templates/layout.jade b/modules/control-center-web/src/main/js/views/templates/layout.jade
new file mode 100644
index 0000000..c6c0e18
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/templates/layout.jade
@@ -0,0 +1,82 @@
+//-
+    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.
+
+doctype html
+html(ng-app='ignite-web-console' ng-init='user = #{JSON.stringify(user)}; becomeUsed = #{becomeUsed}')
+    head
+        title=title
+
+        block css
+            // Font Awesome Icons
+            link(rel='stylesheet', href='//maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.css')
+
+            // Font
+            link(rel='stylesheet', href='//fonts.googleapis.com/css?family=Roboto+Slab:700:serif|Roboto+Slab:400:serif')
+            link(rel='stylesheet', href='//cdnjs.cloudflare.com/ajax/libs/angular-motion/0.4.2/angular-motion.min.css')
+            link(rel='stylesheet', href='//cdn.rawgit.com/wix/angular-tree-control/master/css/tree-control.css')
+            link(rel='stylesheet', href='//cdn.rawgit.com/wix/angular-tree-control/master/css/tree-control-attribute.css')
+            link(rel='stylesheet'  href='//rawgithub.com/darthwade/angular-loading/master/angular-loading.css')
+            link(rel='stylesheet'  href='//cdn.rawgit.com/ceolter/ag-grid/master/dist/ag-grid.css')
+            link(rel='stylesheet', href='/stylesheets/style.css')
+
+        block scripts
+            script(src='/common-utils.js')
+
+            script(src='//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js')
+
+            script(src='//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js')
+
+            script(src='//ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.min.js')
+            script(src='//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular-sanitize.min.js')
+            script(src='//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular-animate.min.js')
+
+            // script(src='//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.3.2/angular-strap.js')
+            // script(src='/js/angular-strap-2.3.2.js')
+            // TODO IGNITE-843: Forked Angular Strap with fix for https://github.com/mgcrea/angular-strap/issues/1852
+            script(src='//cdn.rawgit.com/akuznetsov-gridgain/angular-strap/fix-1852/dist/angular-strap.min.js')
+            script(src='//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.3.2/angular-strap.tpl.min.js')
+
+            script(src='//cdnjs.cloudflare.com/ajax/libs/angular-smart-table/2.1.3/smart-table.js')
+
+            script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ace.js')
+            script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/theme-chrome.js')
+            script(src='//angular-ui.github.io/ui-ace/dist/ui-ace.min.js')
+
+            script(src='//cdn.rawgit.com/wix/angular-tree-control/master/angular-tree-control.js')
+
+            script(src='//cdnjs.cloudflare.com/ajax/libs/spin.js/2.3.2/spin.min.js')
+            script(src='//rawgithub.com/darthwade/angular-loading/master/angular-loading.min.js')
+
+            script(src='//cdn.rawgit.com/ceolter/ag-grid/master/dist/ag-grid.js')
+
+            script(src='//cdnjs.cloudflare.com/ajax/libs/angular-drag-and-drop-lists/1.3.0/angular-drag-and-drop-lists.min.js')
+
+            script(src='//cdn.rawgit.com/krispo/angular-nvd3/master/dist/angular-nvd3.min.js')
+
+            script(src='/common-module.js')
+            script(src='/data-structures.js')
+
+    body.theme-line.body-overlap.greedy
+        .wrapper
+            block body
+                include ../includes/header
+
+                block main-container
+                    .container.body-container
+                        .main-content
+                            block container
+
+                include ../includes/footer

http://git-wip-us.apache.org/repos/asf/ignite/blob/bce0deb7/modules/control-center-web/src/main/js/views/templates/message.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/templates/message.jade b/modules/control-center-web/src/main/js/views/templates/message.jade
new file mode 100644
index 0000000..0043709
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/templates/message.jade
@@ -0,0 +1,26 @@
+//-
+    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.
+
+.modal(tabindex='-1' role='dialog')
+    .modal-dialog
+        .modal-content
+            .modal-header
+                button.close(ng-click='$hide()' aria-hidden='true') &times;
+                h4.modal-title {{title}}
+            .modal-body(ng-show='content')
+                p(ng-bind-html='content' style='text-align: left;')
+            .modal-footer
+                button.btn.btn-primary(id='confirm-btn-confirm' ng-click='$hide()') Ok

http://git-wip-us.apache.org/repos/asf/ignite/blob/bce0deb7/modules/control-center-web/src/main/js/views/templates/select.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/templates/select.jade b/modules/control-center-web/src/main/js/views/templates/select.jade
new file mode 100644
index 0000000..3ff8d21
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/templates/select.jade
@@ -0,0 +1,26 @@
+//-
+    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.
+
+ul.select.dropdown-menu(tabindex='-1' ng-show='$isVisible()' role='select')
+    li(ng-if='$showAllNoneButtons || ($isMultiple && $matches.length > 2)')
+        a(id='li-dropdown-select-all' ng-click='$selectAllAtOnce()') {{$allText}} ({{$matches.length}})
+        a(id='li-dropdown-select-none' ng-click='$selectNoneAtOnce()') {{$noneText}}
+        hr(style='margin: 5px 0')
+    li(role='presentation' ng-repeat='match in $matches')
+        hr(ng-if='match.value == undefined' style='margin: 5px 0')
+        a(id='li-dropdown-item-{{$index}}'  role='menuitem' tabindex='-1' ng-class='{active: $isActive($index)}' ng-click='$select($index, $event)')
+            i(class='{{$iconCheckmark}}' ng-if='$isActive($index)' ng-class='{active: $isActive($index)}')
+            span(ng-bind='match.label')

http://git-wip-us.apache.org/repos/asf/ignite/blob/bce0deb7/modules/control-center-web/src/main/js/views/templates/validation-error.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/templates/validation-error.jade b/modules/control-center-web/src/main/js/views/templates/validation-error.jade
new file mode 100644
index 0000000..13deb9b
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/templates/validation-error.jade
@@ -0,0 +1,25 @@
+//-
+    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.
+
+.popover.validation-error
+    .arrow
+    .popover-content
+        table
+            tr
+                td
+                    label {{content}}&nbsp&nbsp
+                td
+                    button.close(id='popover-btn-close' ng-click='$hide()') &times;

http://git-wip-us.apache.org/repos/asf/ignite/blob/bce0deb7/modules/control-center-web/src/test/js/routes/agent.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/test/js/routes/agent.js b/modules/control-center-web/src/test/js/routes/agent.js
new file mode 100644
index 0000000..4b7dfeb
--- /dev/null
+++ b/modules/control-center-web/src/test/js/routes/agent.js
@@ -0,0 +1,96 @@
+/*
+ *
+ *  * Licensed to the Apache Software Foundation (ASF) under one or more
+ *  * contributor license agreements.  See the NOTICE file distributed with
+ *  * this work for additional information regarding copyright ownership.
+ *  * The ASF licenses this file to You under the Apache License, Version 2.0
+ *  * (the "License"); you may not use this file except in compliance with
+ *  * the License.  You may obtain a copy of the License at
+ *  *
+ *  *      http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+var request = require('supertest'),
+    should = require('should'),
+    app = require('../../app'),
+    fs = require('fs'),
+    https = require('https'),
+    config = require('../../helpers/configuration-loader.js'),
+    agentManager = require('../../agents/agent-manager');
+
+/**
+ * Create HTTP server.
+ */
+/**
+ * Start agent server.
+ */
+var agentServer = https.createServer({
+    key: fs.readFileSync(config.get('monitor:server:key')),
+    cert: fs.readFileSync(config.get('monitor:server:cert')),
+    passphrase: config.get('monitor:server:keyPassphrase')
+});
+
+agentServer.listen(config.get('monitor:server:port'));
+
+agentManager.createManager(agentServer);
+
+describe('request from agent', function() {
+    var agent = request.agent(app);
+
+    before(function (done) {
+        this.timeout(10000);
+
+        agent
+            .post('/login')
+            .send({email: 'test@test.com', password: 'test'})
+            .expect(302)
+            .end(function (err) {
+                if (err)
+                    throw err;
+
+                setTimeout(done, 5000);
+            });
+    });
+
+    it('should return topology snapshot', function(done){
+        agent
+            .post('/agent/topology')
+            .send({})
+            .end(function(err, nodes) {
+                if (err) {
+                    console.log(err.response.text);
+
+                    throw err;
+                }
+
+                console.log(nodes);
+
+                done();
+            });
+    });
+
+    //it('should query result', function(done){
+    //    agent
+    //        .post('/agent/query')
+    //        .send({
+    //            username: 'nva',
+    //            password: 'nva.141',
+    //            host: 'localhost',
+    //            port: '5432',
+    //            dbName: 'ggmonitor'
+    //        })
+    //        .end(function(err, res) {
+    //            if (err)
+    //                throw err;
+    //
+    //            done();
+    //        });
+    //});
+});