ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From akuznet...@apache.org
Subject [1/5] ignite git commit: IGNITE-6390 Web Console: Added component for cluster selection.
Date Wed, 06 Dec 2017 03:37:39 GMT
Repository: ignite
Updated Branches:
  refs/heads/master cbd69d6b3 -> 1367bc98e


http://git-wip-us.apache.org/repos/asf/ignite/blob/1367bc98/modules/web-console/frontend/views/sql/sql.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/sql/sql.tpl.pug b/modules/web-console/frontend/views/sql/sql.tpl.pug
deleted file mode 100644
index 98b4d68..0000000
--- a/modules/web-console/frontend/views/sql/sql.tpl.pug
+++ /dev/null
@@ -1,381 +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
-
-mixin btn-toolbar(btn, click, tip, focusId)
-    i.btn.btn-default.fa(class=btn ng-click=click bs-tooltip='' data-title=tip ignite-on-click-focus=focusId
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')
-
-mixin result-toolbar
-    .btn-group(ng-model='paragraph.result' ng-click='$event.stopPropagation()' style='left:
50%; margin: 0 0 0 -70px;display: block;')
-        +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')
-
-mixin chart-settings
-    .total.row
-        .col-xs-7
-            .chart-settings-link(ng-show='paragraph.chart && paragraph.chartColumns.length
> 0')
-                a(title='Click to show chart settings dialog' ng-click='$event.stopPropagation()'
bs-popover data-template-url='{{ $ctrl.chartSettingsTemplateUrl }}' data-placement='bottom'
data-auto-close='1' data-trigger='click')
-                    i.fa.fa-bars
-                    | Chart settings
-                div(ng-show='paragraphTimeSpanVisible(paragraph)')
-                    label Show
-                    button.select-manual-caret.btn.btn-default(ng-model='paragraph.timeLineSpan'
ng-change='applyChartSettings(paragraph)' bs-options='item for item in timeLineSpans' bs-select
data-caret-html='<span class="caret"></span>')
-                    label min
-
-                div
-                    label Duration: #[b {{paragraph.duration | duration}}]
-                    label.margin-left-dflt(ng-show='paragraph.localQueryMode') NodeID8: #[b
{{paragraph.resNodeId | id8}}]
-        .col-xs-2
-            +result-toolbar
-
-mixin notebook-rename
-    .docs-header.notebook-header
-        h1.col-sm-6(ng-hide='notebook.edit')
-            label(style='max-width: calc(100% - 60px)') {{notebook.name}}
-            .btn-group(ng-if='!demo')
-                +btn-toolbar('fa-pencil', 'notebook.edit = true;notebook.editName = notebook.name',
'Rename notebook')
-                +btn-toolbar('fa-trash', 'removeNotebook(notebook)', 'Remove notebook')
-        h1.col-sm-6(ng-show='notebook.edit')
-            i.btn.fa.fa-floppy-o(ng-show='notebook.editName' ng-click='renameNotebook(notebook.editName)'
bs-tooltip data-title='Save notebook name' data-trigger='hover')
-            .input-tip
-                input.form-control(ng-model='notebook.editName' required ignite-on-enter='renameNotebook(notebook.editName)'
ignite-on-escape='notebook.edit = false;')
-        h1.pull-right
-            a.dropdown-toggle(style='margin-right: 20px' data-toggle='dropdown' bs-dropdown='scrollParagraphs'
data-placement='bottom-right') Scroll to query
-                span.caret
-            button.btn.btn-default(style='margin-top: 2px' ng-click='addQuery()' ignite-on-click-focus=focusId)
-                i.fa.fa-fw.fa-plus
-                | Add query
-
-            button.btn.btn-default(style='margin-top: 2px' ng-click='addScan()' ignite-on-click-focus=focusId)
-                i.fa.fa-fw.fa-plus
-                | Add scan
-
-mixin notebook-error
-    h2 Failed to load notebook
-    label.col-sm-12 Notebook not accessible any more. Go back to configuration or open to
another notebook.
-    button.h3.btn.btn-primary(ui-sref='base.configuration.tabs.advanced.clusters') Back to
configuration
-
-mixin paragraph-rename
-    .col-sm-6(ng-hide='paragraph.edit')
-        i.fa(ng-class='paragraphExpanded(paragraph) ? "fa-chevron-circle-down" : "fa-chevron-circle-right"')
-        label {{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', 'paragraph-name-{{paragraph.id}}')
-
-        .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', 'paragraph-name-{{paragraph.id}}')
-            +btn-toolbar('fa-remove', 'removeParagraph(paragraph)', 'Remove query')
-
-    .col-sm-6(ng-show='paragraph.edit')
-        i.tipLabel.fa(style='float: left;' ng-class='paragraphExpanded(paragraph) ? "fa-chevron-circle-down"
: "fa-chevron-circle-right"')
-        i.tipLabel.fa.fa-floppy-o(style='float: right;' ng-show='paragraph.editName' ng-click='renameParagraph(paragraph,
paragraph.editName); $event.stopPropagation();' bs-tooltip data-title='Save query name' data-trigger='hover')
-        .input-tip
-            input.form-control(id='paragraph-name-{{paragraph.id}}' ng-model='paragraph.editName'
required ng-click='$event.stopPropagation();' ignite-on-enter='renameParagraph(paragraph,
paragraph.editName)' ignite-on-escape='paragraph.edit = false')
-
-mixin query-settings
-    .panel-top-align
-        label.tipLabel(bs-tooltip data-placement='bottom' data-title='Configure periodical
execution of last successfully executed query') 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='{{ $ctrl.paragraphRateTemplateUrl
}}' data-placement='left' data-auto-close='1' data-trigger='click') {{rateAsString(paragraph)}}
-
-        label.tipLabel(bs-tooltip data-placement='bottom' data-title='Max number of rows
to show in query result as one page') Page size:
-            button.btn.btn-default.select-toggle.tipLabel(ng-model='paragraph.pageSize' bs-select
bs-options='item for item in pageSizes')
-
-        label.tipLabel(bs-tooltip data-placement='bottom' data-title='Limit query max results
to specified number of pages') Max pages:
-            button.btn.btn-default.select-toggle.tipLabel(ng-model='paragraph.maxPages' bs-select
bs-options='item.value as item.label for item in maxPages')
-
-        .panel-tip-container
-            .row(ng-if='nonCollocatedJoinsAvailable(paragraph)')
-                label.tipLabel(bs-tooltip data-placement='bottom' data-title='Non-collocated
joins is a special mode that allow to join data across cluster without collocation.<br/>\
-                    Nested joins are not supported for now.<br/>\
-                    <b>NOTE</b>: In some cases it may consume more heap memory
or may take a long time than collocated joins.' data-trigger='hover')
-                    input(type='checkbox' ng-model='paragraph.nonCollocatedJoins')
-                    span Allow non-collocated joins
-            .row(ng-if='enforceJoinOrderAvailable(paragraph)')
-                label.tipLabel(bs-tooltip data-placement='bottom' data-title='Enforce join
order of tables in the query.<br/>\
-                    If <b>set</b>, then query optimizer will not reorder tables
within join.<br/>\
-                    <b>NOTE:</b> It is not recommended to enable this property
unless you have verified that\
-                    indexes are not selected in optimal order.' data-trigger='hover')
-                    input(type='checkbox' ng-model='paragraph.enforceJoinOrder')
-                    span Enforce join order
-            .row(ng-if='lazyQueryAvailable(paragraph)')
-                label.tipLabel(bs-tooltip data-placement='bottom' data-title='By default
Ignite attempts to fetch the whole query result set to memory and send it to the client.<br/>\
-                    For small and medium result sets this provides optimal performance and
minimize duration of internal database locks, thus increasing concurrency.<br/>\
-                    If result set is too big to fit in available memory this could lead to
excessive GC pauses and even OutOfMemoryError.<br/>\
-                    Use this flag as a hint for Ignite to fetch result set lazily, thus minimizing
memory consumption at the cost of moderate performance hit.' data-trigger='hover')
-                    input(type='checkbox' ng-model='paragraph.lazy')
-                    span Lazy result set
-
-mixin query-actions
-    button.btn.btn-primary(ng-disabled='!queryAvailable(paragraph)' ng-click='execute(paragraph)')
-        div
-            i.fa.fa-fw.fa-play(ng-hide='paragraph.executionInProgress(false)')
-            i.fa.fa-fw.fa-refresh.fa-spin(ng-show='paragraph.executionInProgress(false)')
-            span.tipLabelExecute Execute
-    button.btn.btn-primary(ng-disabled='!queryAvailable(paragraph)' ng-click='execute(paragraph,
true)')
-        div
-            i.fa.fa-fw.fa-play(ng-hide='paragraph.executionInProgress(true)')
-            i.fa.fa-fw.fa-refresh.fa-spin(ng-show='paragraph.executionInProgress(true)')
-            span.tipLabelExecute Execute on selected node
-
-
-    a.btn.btn-default(ng-disabled='!queryAvailable(paragraph)' ng-click='explain(paragraph)'
data-placement='bottom' bs-tooltip='' data-title='{{queryTooltip(paragraph, "explain query")}}')
Explain
-
-mixin table-result-heading-query
-    .total.row
-        .col-xs-7
-            grid-column-selector(grid-api='paragraph.gridOptions.api')
-                .fa.fa-bars.icon
-            label Page: #[b {{paragraph.page}}]
-            label.margin-left-dflt Results so far: #[b {{paragraph.rows.length + paragraph.total}}]
-            label.margin-left-dflt Duration: #[b {{paragraph.duration | duration}}]
-            label.margin-left-dflt(ng-show='paragraph.localQueryMode') NodeID8: #[b {{paragraph.resNodeId
| id8}}]
-        .col-xs-2
-            div(ng-if='paragraph.qryType === "query"')
-                +result-toolbar
-        .col-xs-3
-            .pull-right
-                .btn-group.panel-tip-container
-                    button.btn.btn-primary.btn--with-icon(
-                        ng-click='exportCsv(paragraph)'
-
-                        ng-disabled='paragraph.loading'
-
-                        bs-tooltip=''
-                        ng-attr-title='{{ queryTooltip(paragraph, "export query results")
}}'
-
-                        data-trigger='hover'
-                        data-placement='bottom'
-                    )
-                        svg(ignite-icon='csv' ng-if='!paragraph.csvIsPreparing')
-                        i.fa.fa-fw.fa-refresh.fa-spin(ng-if='paragraph.csvIsPreparing')
-                        span Export
-
-                    -var options = [{ text: 'Export', click: 'exportCsv(paragraph)' }, {
text: 'Export all', click: 'exportCsvAll(paragraph)' }, { divider: true }, { text: '<span
title="Copy current result page to clipboard">Copy to clipboard</span>', click: 'exportCsvToClipBoard(paragraph)'
}]
-                    button.btn.dropdown-toggle.btn-primary(
-                        ng-disabled='paragraph.loading'
-
-                        bs-dropdown=`${JSON.stringify(options)}`
-
-                        data-toggle='dropdown'
-                        data-container='body'
-                        data-placement='bottom-right'
-                        data-html='true'
-                    )
-                        span.caret
-
-
-
-mixin table-result-heading-scan
-    .total.row
-        .col-xs-7
-            grid-column-selector(grid-api='paragraph.gridOptions.api')
-                .fa.fa-bars.icon
-            label Page: #[b {{paragraph.page}}]
-            label.margin-left-dflt Results so far: #[b {{paragraph.rows.length + paragraph.total}}]
-            label.margin-left-dflt Duration: #[b {{paragraph.duration | duration}}]
-            label.margin-left-dflt(ng-show='paragraph.localQueryMode') NodeID8: #[b {{paragraph.resNodeId
| id8}}]
-        .col-xs-2
-            div(ng-if='paragraph.qryType === "query"')
-                +result-toolbar
-        .col-xs-3
-            .pull-right
-                .btn-group.panel-tip-container
-                    // TODO: replace this logic for exporting under one component
-                    button.btn.btn-primary.btn--with-icon(
-                        ng-click='exportCsv(paragraph)'
-
-                        ng-disabled='paragraph.loading || paragraph.csvIsPreparing'
-
-                        bs-tooltip=''
-                        ng-attr-title='{{ scanTooltip(paragraph) }}'
-
-                        data-trigger='hover'
-                        data-placement='bottom'
-                    )
-                        svg(ignite-icon='csv' ng-if='!paragraph.csvIsPreparing')
-                        i.fa.fa-fw.fa-refresh.fa-spin(ng-if='paragraph.csvIsPreparing')
-                        span Export
-
-                    -var options = [{ text: "Export", click: 'exportCsv(paragraph)' }, {
text: 'Export all', click: 'exportCsvAll(paragraph)' }, { divider: true }, { text: '<span
title="Copy current result page to clipboard">Copy to clipboard</span>', click: 'exportCsvToClipBoard(paragraph)'
}]
-                    button.btn.dropdown-toggle.btn-primary(
-                        ng-disabled='paragraph.loading || paragraph.csvIsPreparing'
-
-                        bs-dropdown=`${JSON.stringify(options)}`
-
-                        data-toggle='dropdown'
-                        data-container='body'
-                        data-placement='bottom-right'
-                        data-html='true'
-                    )
-                        span.caret
-
-mixin table-result-body
-    .grid(ui-grid='paragraph.gridOptions' ui-grid-resize-columns ui-grid-exporter)
-
-mixin chart-result
-    div(ng-hide='paragraph.scanExplain()')
-        +chart-settings
-        .empty(ng-show='paragraph.chartColumns.length > 0 && !paragraph.chartColumnsConfigured()')
Cannot display chart. Please configure axis using #[b Chart settings]
-        .empty(ng-show='paragraph.chartColumns.length == 0') Cannot display chart. Result
set must contain Java build-in type columns. Please change query and execute it again.
-        div(ng-show='paragraph.chartColumnsConfigured()')
-            div(ng-show='paragraph.timeLineSupported() || !paragraph.chartTimeLineEnabled()')
-                div(ng-repeat='chart in paragraph.charts')
-                    nvd3(options='chart.options' data='chart.data' api='chart.api')
-            .empty(ng-show='!paragraph.timeLineSupported() && paragraph.chartTimeLineEnabled()')
Pie chart does not support 'TIME_LINE' column for X-axis. Please use another column for X-axis
or switch to another chart.
-    .empty(ng-show='paragraph.scanExplain()')
-        .row
-            .col-xs-4.col-xs-offset-4
-                +result-toolbar
-        label.margin-top-dflt Charts do not support #[b Explain] and #[b Scan] query
-
-mixin paragraph-scan
-    .panel-heading(bs-collapse-toggle)
-        .row
-            +paragraph-rename
-    .panel-collapse(role='tabpanel' bs-collapse-target)
-        .col-sm-12.sql-controls
-            .col-sm-3
-                +dropdown-required('Cache:', 'paragraph.cacheName', '"cache"', 'true', 'false',
'Choose cache', 'caches')
-            .col-sm-3
-                +text-enabled('Filter:', 'paragraph.filter', '"filter"', true, false, 'Enter
filter')
-                    label.btn.btn-default.ignite-form-field__btn(ng-click='paragraph.caseSensitive
= !paragraph.caseSensitive')
-                        input(type='checkbox' ng-model='paragraph.caseSensitive')
-                        span(bs-tooltip data-title='Select this checkbox for case sensitive
search') Cs
-            label.tipLabel(bs-tooltip data-placement='bottom' data-title='Max number of rows
to show in query result as one page') Page size:
-                button.btn.btn-default.select-toggle.tipLabel(ng-model='paragraph.pageSize'
bs-select bs-options='item for item in pageSizes')
-
-        .col-sm-12.sql-controls
-            button.btn.btn-primary(ng-disabled='!scanAvailable(paragraph)' ng-click='scan(paragraph)')
-                div
-                    i.fa.fa-fw.fa-play(ng-hide='paragraph.checkScanInProgress(false)')
-                    i.fa.fa-fw.fa-refresh.fa-spin(ng-show='paragraph.checkScanInProgress(false)')
-                    span.tipLabelExecute Scan
-
-            button.btn.btn-primary(ng-disabled='!scanAvailable(paragraph)' ng-click='scan(paragraph,
true)')
-                    i.fa.fa-fw.fa-play(ng-hide='paragraph.checkScanInProgress(true)')
-                    i.fa.fa-fw.fa-refresh.fa-spin(ng-show='paragraph.checkScanInProgress(true)')
-                    span.tipLabelExecute Scan on selected node
-
-        .col-sm-12.sql-result(ng-if='paragraph.queryExecuted()' ng-switch='paragraph.resultType()')
-            .error(ng-switch-when='error') Error: {{paragraph.error.message}}
-            .empty(ng-switch-when='empty') Result set is empty. Duration: #[b {{paragraph.duration
| duration}}]
-            .table(ng-switch-when='table')
-                +table-result-heading-scan
-                +table-result-body
-            .footer.clearfix()
-                .pull-left
-                    | Showing results for scan of #[b {{ paragraph.queryArgs.cacheName |
defaultName }}]
-                    span(ng-if='paragraph.queryArgs.filter') &nbsp; with filter: #[b
{{ paragraph.queryArgs.filter }}]
-                    span(ng-if='paragraph.queryArgs.localNid') &nbsp; on node: #[b {{
paragraph.queryArgs.localNid | limitTo:8 }}]
-
-                -var nextVisibleCondition = 'paragraph.resultType() != "error" &&
paragraph.queryId && paragraph.nonRefresh() && (paragraph.table() || paragraph.chart()
&& !paragraph.scanExplain())'
-
-                .pull-right(ng-show=`${nextVisibleCondition}` ng-class='{disabled: paragraph.loading}'
ng-click='!paragraph.loading && nextPage(paragraph)')
-                    i.fa.fa-chevron-circle-right
-                    a Next
-
-mixin paragraph-query
-    .row.panel-heading(bs-collapse-toggle)
-        +paragraph-rename
-    .panel-collapse(role='tabpanel' bs-collapse-target)
-        .col-sm-12
-            .col-xs-8.col-sm-9(style='border-right: 1px solid #eee')
-                .sql-editor(ignite-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:
-                    i.fa.fa-database.tipField(title='Click to show cache types metadata dialog'
bs-popover data-template-url='{{ $ctrl.cacheMetadataTemplateUrl }}' data-placement='bottom'
data-trigger='click' data-container='#{{ paragraph.id }}')
-                    .input-tip
-                        input.form-control(type='text' st-search='label' placeholder='Filter
caches...')
-                    table.links
-                        tbody.scrollable-y(style='max-height: 15em; display: block;')
-                            tr(ng-repeat='cache in displayedCaches track by cache.name')
-                                td(style='width: 100%')
-                                    input.labelField(id='cache_{{ [paragraph.id, $index].join("_")
}}' type='radio' value='{{cache.name}}' ng-model='paragraph.cacheName')
-                                    label(for='cache_{{ [paragraph.id, $index].join("_")
}} ' ng-bind-html='cache.label')
-                    .settings-row
-                        .row(ng-if='ddlAvailable(paragraph)')
-                            label.tipLabel.use-cache(bs-tooltip data-placement='bottom'
-                                data-title=
-                                    'Use selected cache as default schema name.<br/>\
-                                    This will allow to execute query on specified cache without
specify schema name.<br/>\
-                                    <b>NOTE:</b> In future version of Ignite
this feature will be removed.'
-                                data-trigger='hover')
-                                input(type='checkbox' ng-model='paragraph.useAsDefaultSchema')
-                                span Use selected cache as default schema 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.sql-controls
-            +query-actions
-
-            .pull-right
-                +query-settings
-        .col-sm-12.sql-result(ng-if='paragraph.queryExecuted()' ng-switch='paragraph.resultType()')
-            .error(ng-switch-when='error')
-                label Error: {{paragraph.error.message}}
-                br
-                a(ng-show='paragraph.resultType() === "error"' ng-click='showStackTrace(paragraph)')
Show more
-            .empty(ng-switch-when='empty') Result set is empty. Duration: #[b {{paragraph.duration
| duration}}]
-            .table(ng-switch-when='table')
-                +table-result-heading-query
-                +table-result-body
-            .chart(ng-switch-when='chart')
-                +chart-result
-            .footer.clearfix(ng-show='paragraph.resultType() !== "error"')
-                a.pull-left(ng-click='showResultQuery(paragraph)') Show query
-
-                -var nextVisibleCondition = 'paragraph.resultType() !== "error" &&
paragraph.queryId && paragraph.nonRefresh() && (paragraph.table() || paragraph.chart()
&& !paragraph.scanExplain())'
-
-                .pull-right(ng-show=`${nextVisibleCondition}` ng-class='{disabled: paragraph.loading}'
ng-click='!paragraph.loading && nextPage(paragraph)')
-                    i.fa.fa-chevron-circle-right
-                    a Next
-
-.row
-    .docs-content
-        .row(ng-if='notebook' bs-affix style='margin-bottom: 20px;')
-            +notebook-rename
-
-        ignite-information(data-title='With query notebook you can' style='margin-top: 0;
margin-bottom: 30px')
-            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
-
-        div(ng-if='notebookLoadFailed' style='text-align: center')
-            +notebook-error
-
-        div(ng-if='notebook' ignite-loading='sqlLoading' ignite-loading-text='{{ loadingText
}}' ignite-loading-position='top')
-            .docs-body.paragraphs
-                .panel-group(bs-collapse ng-model='notebook.expandedParagraphs' data-allow-multiple='true'
data-start-collapsed='false')
-
-                    .panel-paragraph(ng-repeat='paragraph in notebook.paragraphs' id='{{paragraph.id}}'
ng-form='form_{{paragraph.id}}')
-                        .panel.panel-default(ng-if='paragraph.qryType === "scan"')
-                            +paragraph-scan
-                        .panel.panel-default(ng-if='paragraph.qryType === "query"')
-                            +paragraph-query

http://git-wip-us.apache.org/repos/asf/ignite/blob/1367bc98/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/ClusterListener.java
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/ClusterListener.java
b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/ClusterListener.java
index 8eed3dd..86b9ea5 100644
--- a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/ClusterListener.java
+++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/ClusterListener.java
@@ -22,44 +22,51 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import io.socket.client.Socket;
 import io.socket.emitter.Emitter;
 import java.net.ConnectException;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.List;
+import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
+import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.console.agent.rest.RestExecutor;
 import org.apache.ignite.console.agent.rest.RestResult;
 import org.apache.ignite.internal.processors.rest.client.message.GridClientNodeBean;
 import org.apache.ignite.internal.processors.rest.protocols.http.jetty.GridJettyObjectMapper;
 import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.util.typedef.T2;
+import org.apache.ignite.internal.util.typedef.internal.LT;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteClosure;
 import org.apache.ignite.lang.IgniteProductVersion;
-import org.slf4j.Logger;
+import org.apache.ignite.logger.slf4j.Slf4jLogger;
 import org.slf4j.LoggerFactory;
 
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_CLUSTER_NAME;
 import static org.apache.ignite.console.agent.AgentUtils.toJSON;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_BUILD_VER;
+import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_CLIENT_MODE;
+import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_IPS;
 import static org.apache.ignite.internal.processors.rest.GridRestResponse.STATUS_SUCCESS;
+import static org.apache.ignite.internal.visor.util.VisorTaskUtils.sortAddresses;
+import static org.apache.ignite.internal.visor.util.VisorTaskUtils.splitAddresses;
 
 /**
  * API to transfer topology from Ignite cluster available by node-uri.
  */
 public class ClusterListener {
     /** */
-    private static final Logger log = LoggerFactory.getLogger(ClusterListener.class);
+    private static final IgniteLogger log = new Slf4jLogger(LoggerFactory.getLogger(ClusterListener.class));
 
     /** */
     private static final String EVENT_CLUSTER_CONNECTED = "cluster:connected";
 
     /** */
     private static final String EVENT_CLUSTER_TOPOLOGY = "cluster:topology";
-    
+
     /** */
     private static final String EVENT_CLUSTER_DISCONNECTED = "cluster:disconnected";
 
@@ -79,17 +86,6 @@ public class ClusterListener {
     private final BroadcastTask broadcastTask = new BroadcastTask();
 
     /** */
-    private static final IgniteClosure<GridClientNodeBean, UUID> NODE2ID = new IgniteClosure<GridClientNodeBean,
UUID>() {
-        @Override public UUID apply(GridClientNodeBean n) {
-            return n.getNodeId();
-        }
-
-        @Override public String toString() {
-            return "Node bean to node ID transformer closure.";
-        }
-    };
-
-    /** */
     private static final IgniteClosure<UUID, String> ID2ID8 = new IgniteClosure<UUID,
String>() {
         @Override public String apply(UUID nid) {
             return U.id8(nid).toUpperCase();
@@ -127,7 +123,7 @@ public class ClusterListener {
      * @param nids Cluster nodes IDs.
      */
     private void clusterConnect(Collection<UUID> nids) {
-        log.info("Connection successfully established to cluster with nodes: {}", F.viewReadOnly(nids,
ID2ID8));
+        log.info("Connection successfully established to cluster with nodes: " + F.viewReadOnly(nids,
ID2ID8));
 
         client.emit(EVENT_CLUSTER_CONNECTED, toJSON(nids));
     }
@@ -171,7 +167,7 @@ public class ClusterListener {
             @Override public void call(Object... args) {
                 safeStopRefresh();
 
-                final long timeout = args.length > 1  && args[1] instanceof Long
? (long)args[1] : DFLT_TIMEOUT;
+                final long timeout = args.length > 1 && args[1] instanceof Long
? (long)args[1] : DFLT_TIMEOUT;
 
                 refreshTask = pool.scheduleWithFixedDelay(broadcastTask, 0L, timeout, TimeUnit.MILLISECONDS);
             }
@@ -194,41 +190,107 @@ public class ClusterListener {
     /** */
     private static class TopologySnapshot {
         /** */
+        private String clusterName;
+
+        /** */
         private Collection<UUID> nids;
 
         /** */
-        private String clusterVer;
+        private Map<UUID, String> addrs;
+
+        /** */
+        private Map<UUID, Boolean> clients;
+
+        /** */
+        private String clusterVerStr;
+
+        /** */
+        private IgniteProductVersion clusterVer;
+
+        /** */
+        private boolean active;
+
+        /**
+         * Helper method to get attribute.
+         *
+         * @param attrs Map with attributes.
+         * @param name Attribute name.
+         * @return Attribute value.
+         */
+        private static <T> T attribute(Map<String, Object> attrs, String name)
{
+            return (T)attrs.get(name);
+        }
 
         /**
          * @param nodes Nodes.
          */
         TopologySnapshot(Collection<GridClientNodeBean> nodes) {
-            nids = F.viewReadOnly(nodes, NODE2ID);
+            int sz = nodes.size();
+
+            nids = new ArrayList<>(sz);
+            addrs = U.newHashMap(sz);
+            clients = U.newHashMap(sz);
+            active = false;
+
+            for (GridClientNodeBean node : nodes) {
+                UUID nid = node.getNodeId();
+
+                nids.add(nid);
 
-            Collection<T2<String, IgniteProductVersion>> vers = F.transform(nodes,
-                new IgniteClosure<GridClientNodeBean, T2<String, IgniteProductVersion>>()
{
-                    @Override public T2<String, IgniteProductVersion> apply(GridClientNodeBean
bean) {
-                        String ver = (String)bean.getAttributes().get(ATTR_BUILD_VER);
+                Map<String, Object> attrs = node.getAttributes();
 
-                        return new T2<>(ver, IgniteProductVersion.fromString(ver));
-                    }
-                });
+                if (F.isEmpty(clusterName))
+                    clusterName = attribute(attrs, IGNITE_CLUSTER_NAME);
 
-            T2<String, IgniteProductVersion> min = Collections.min(vers, new Comparator<T2<String,
IgniteProductVersion>>() {
-                @SuppressWarnings("ConstantConditions")
-                @Override public int compare(T2<String, IgniteProductVersion> o1, T2<String,
IgniteProductVersion> o2) {
-                    return o1.get2().compareTo(o2.get2());
+                Boolean client = attribute(attrs, ATTR_CLIENT_MODE);
+
+                clients.put(nid, client);
+
+                Collection<String> nodeAddrs = client
+                    ? splitAddresses((String)attribute(attrs, ATTR_IPS))
+                    : node.getTcpAddresses();
+
+                String firstIP = F.first(sortAddresses(nodeAddrs));
+
+                addrs.put(nid, firstIP);
+
+                String nodeVerStr = attribute(attrs, ATTR_BUILD_VER);
+
+                IgniteProductVersion nodeVer = IgniteProductVersion.fromString(nodeVerStr);
+
+                if (clusterVer == null || clusterVer.compareTo(nodeVer) > 0) {
+                    clusterVer = nodeVer;
+                    clusterVerStr = nodeVerStr;
                 }
-            });
+            }
+        }
 
-            clusterVer = min.get1();
+        /**
+         * @return Cluster name.
+         */
+        public String getClusterName() {
+            return clusterName;
         }
 
         /**
          * @return Cluster version.
          */
         public String getClusterVersion() {
-            return clusterVer;
+            return clusterVerStr;
+        }
+
+        /**
+         * @return Cluster active flag.
+         */
+        public boolean isActive() {
+            return active;
+        }
+
+        /**
+         * @param active New cluster active state.
+         */
+        public void setActive(boolean active) {
+            this.active = active;
         }
 
         /**
@@ -238,14 +300,40 @@ public class ClusterListener {
             return nids;
         }
 
-        /**  */
+        /**
+         * @return Cluster nodes with IPs.
+         */
+        public Map<UUID, String> getAddresses() {
+            return addrs;
+        }
+
+        /**
+         * @return Cluster nodes with client mode flag.
+         */
+        public Map<UUID, Boolean> getClients() {
+            return clients;
+        }
+
+        /**
+         * @return Cluster version.
+         */
+        public IgniteProductVersion clusterVersion() {
+            return clusterVer;
+        }
+
+        /**
+         * @return Collection of short UUIDs.
+         */
         Collection<String> nid8() {
             return F.viewReadOnly(nids, ID2ID8);
         }
 
-        /**  */
-        boolean differentCluster(TopologySnapshot old) {
-            return old == null || F.isEmpty(old.nids) || Collections.disjoint(nids, old.nids);
+        /**
+         * @param prev Previous topology.
+         * @return {@code true} in case if current topology is a new cluster.
+         */
+        boolean differentCluster(TopologySnapshot prev) {
+            return prev == null || F.isEmpty(prev.nids) || Collections.disjoint(nids, prev.nids);
         }
     }
 
@@ -264,7 +352,11 @@ public class ClusterListener {
                         TopologySnapshot newTop = new TopologySnapshot(nodes);
 
                         if (newTop.differentCluster(top))
-                            log.info("Connection successfully established to cluster with
nodes: {}", newTop.nid8());
+                            log.info("Connection successfully established to cluster with
nodes: " + newTop.nid8());
+
+                        boolean active = restExecutor.active(newTop.clusterVersion(), F.first(newTop.getNids()));
+
+                        newTop.setActive(active);
 
                         top = newTop;
 
@@ -273,7 +365,7 @@ public class ClusterListener {
                         break;
 
                     default:
-                        log.warn(res.getError());
+                        LT.warn(log, res.getError());
 
                         clusterDisconnect();
                 }
@@ -288,7 +380,7 @@ public class ClusterListener {
             }
         }
     }
-    
+
     /** */
     private class BroadcastTask implements Runnable {
         /** {@inheritDoc} */
@@ -306,7 +398,7 @@ public class ClusterListener {
                         if (top.differentCluster(newTop)) {
                             clusterDisconnect();
 
-                            log.info("Connection successfully established to cluster with
nodes: {}", newTop.nid8());
+                            log.info("Connection successfully established to cluster with
nodes: " + newTop.nid8());
 
                             watch();
                         }
@@ -318,7 +410,7 @@ public class ClusterListener {
                         break;
 
                     default:
-                        log.warn(res.getError());
+                        LT.warn(log, res.getError());
 
                         clusterDisconnect();
                 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1367bc98/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/rest/RestExecutor.java
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/rest/RestExecutor.java
b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/rest/RestExecutor.java
index 36f3885..7fbe6f9 100644
--- a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/rest/RestExecutor.java
+++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/rest/RestExecutor.java
@@ -30,6 +30,7 @@ import java.io.StringWriter;
 import java.net.ConnectException;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.UUID;
 import java.util.concurrent.TimeUnit;
 import okhttp3.Dispatcher;
 import okhttp3.FormBody;
@@ -44,6 +45,7 @@ import org.apache.ignite.console.demo.AgentClusterDemo;
 import org.apache.ignite.internal.processors.rest.protocols.http.jetty.GridJettyObjectMapper;
 import org.apache.ignite.internal.util.typedef.internal.LT;
 import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteProductVersion;
 import org.apache.ignite.logger.slf4j.Slf4jLogger;
 import org.slf4j.LoggerFactory;
 
@@ -59,6 +61,18 @@ import static org.apache.ignite.internal.processors.rest.GridRestResponse.STATUS
  */
 public class RestExecutor {
     /** */
+    private static final IgniteProductVersion IGNITE_2_1 = IgniteProductVersion.fromString("2.1.0");
+
+    /** */
+    private static final IgniteProductVersion IGNITE_2_3 = IgniteProductVersion.fromString("2.3.0");
+
+    /** Unique Visor key to get events last order. */
+    private static final String EVT_LAST_ORDER_KEY = "WEB_AGENT_" + UUID.randomUUID().toString();
+
+    /** Unique Visor key to get events throttle counter. */
+    private static final String EVT_THROTTLE_CNTR_KEY = "WEB_AGENT_" + UUID.randomUUID().toString();
+
+    /** */
     private static final IgniteLogger log = new Slf4jLogger(LoggerFactory.getLogger(RestExecutor.class));
 
     /** JSON object mapper. */
@@ -208,7 +222,9 @@ public class RestExecutor {
     }
 
     /**
-     * @param demo Is demo node request.
+     * @param demo {@code true} in case of demo mode.
+     * @param full Flag indicating whether to collect metrics or not.
+     * @throws IOException If failed to collect topology.
      */
     public RestResult topology(boolean demo, boolean full) throws IOException {
         Map<String, Object> params = new HashMap<>(3);
@@ -221,6 +237,51 @@ public class RestExecutor {
     }
 
     /**
+     * @param ver Cluster version.
+     * @param nid Node ID.
+     * @return Cluster active state.
+     * @throws IOException If failed to collect cluster active state.
+     */
+    public boolean active(IgniteProductVersion ver, UUID nid) throws IOException {
+        Map<String, Object> params = new HashMap<>();
+
+        boolean v23 = ver.compareTo(IGNITE_2_3) >= 0;
+
+        if (v23)
+            params.put("cmd", "currentState");
+        else {
+            params.put("cmd", "exe");
+            params.put("name", "org.apache.ignite.internal.visor.compute.VisorGatewayTask");
+            params.put("p1", nid);
+            params.put("p2", "org.apache.ignite.internal.visor.node.VisorNodeDataCollectorTask");
+            params.put("p3", "org.apache.ignite.internal.visor.node.VisorNodeDataCollectorTaskArg");
+            params.put("p4", false);
+            params.put("p5", EVT_LAST_ORDER_KEY);
+            params.put("p6", EVT_THROTTLE_CNTR_KEY);
+
+            if (ver.compareTo(IGNITE_2_1) >= 0)
+                params.put("p7", false);
+            else {
+                params.put("p7", 10);
+                params.put("p8", false);
+            }
+        }
+
+        RestResult res = sendRequest(false, "ignite", params, null, null);
+
+        switch (res.getStatus()) {
+            case STATUS_SUCCESS:
+                if (v23)
+                    return Boolean.valueOf(res.getData());
+
+                return res.getData().contains("\"active\":true");
+
+            default:
+                throw new IOException(res.getError());
+        }
+    }
+
+    /**
      * REST response holder Java bean.
      */
     private static class RestResponseHolder {


Mime
View raw message