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 2016/09/13 09:53:31 UTC
[39/69] [abbrv] ignite git commit: Web Console beta-3.
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/helpers/jade/form/form-group.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/helpers/jade/form/form-group.jade b/modules/web-console/frontend/app/helpers/jade/form/form-group.jade
new file mode 100644
index 0000000..8fb7b1f
--- /dev/null
+++ b/modules/web-console/frontend/app/helpers/jade/form/form-group.jade
@@ -0,0 +1,23 @@
+//-
+ 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.
+
+mixin ignite-form-group()
+ .group-section(ignite-form-group)&attributes(attributes)
+ .group(ng-if='true' ng-init='group = {}')
+ .group-legend
+ label {{::group.label}}
+ if block
+ block
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/helpers/jade/mixins.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/helpers/jade/mixins.jade b/modules/web-console/frontend/app/helpers/jade/mixins.jade
new file mode 100644
index 0000000..c37ab15
--- /dev/null
+++ b/modules/web-console/frontend/app/helpers/jade/mixins.jade
@@ -0,0 +1,541 @@
+//-
+ 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 ./form.jade
+
+//- Mixin for advanced options toggle.
+mixin advanced-options-toggle(click, cond, showMessage, hideMessage)
+ .advanced-options
+ i.fa(ng-click='#{click}' ng-class='#{cond} ? "fa-chevron-circle-down" : "fa-chevron-circle-right"')
+ a(ng-click=click) {{#{cond} ? '#{hideMessage}' : '#{showMessage}'}}
+
+//- Mixin for advanced options toggle with default settings.
+mixin advanced-options-toggle-default
+ +advanced-options-toggle('toggleExpanded()', 'ui.expanded', 'Show advanced settings...', 'Hide advanced settings...')
+
+//- Mixin for main table on screen with list of items.
+mixin main-table(title, rows, focusId, click, rowTemplate, searchField)
+ .padding-bottom-dflt(ng-show='#{rows} && #{rows}.length > 0')
+ table.links(st-table='displayedRows' st-safe-src='#{rows}')
+ thead
+ tr
+ th
+ lable.labelHeader.labelFormField #{title}:
+ .col-sm-3.pull-right(style='padding: 0')
+ input.form-control(type='text' st-search='#{searchField}' placeholder='Filter #{title}...')
+ tbody
+ tr
+ td
+ .scrollable-y(ng-show='displayedRows.length > 0' style='max-height: 200px')
+ table
+ tbody
+ tr(ng-repeat='row in displayedRows track by row._id' ignite-bs-affix-update)
+ td
+ a(ng-class='{active: row._id == selectedItem._id}' ignite-on-click-focus=focusId ng-click=click) #{rowTemplate}
+ label.placeholder(ng-show='displayedRows.length == 0') No #{title} found
+
+//- Mixin with save, remove, clone and undo buttons.
+mixin save-remove-clone-undo-buttons(objectName)
+ -var removeTip = '"Remove current ' + objectName + '"'
+ -var cloneTip = '"Clone current ' + objectName + '"'
+ -var undoTip = '"Undo all changes for current ' + objectName + '"'
+
+ div(ng-show='contentVisible()' style='display: inline-block;')
+ .panel-tip-container(ng-hide='!backupItem || backupItem._id')
+ a.btn.btn-primary(ng-disabled='!ui.inputForm.$dirty' ng-click='ui.inputForm.$dirty && saveItem()' bs-tooltip='' data-title='{{saveBtnTipText(ui.inputForm.$dirty, "#{objectName}")}}' data-placement='bottom' data-trigger='hover') Save
+ .panel-tip-container(ng-show='backupItem._id')
+ a.btn.btn-primary(id='save-item' ng-disabled='!ui.inputForm.$dirty' ng-click='ui.inputForm.$dirty && saveItem()' bs-tooltip='' data-title='{{saveBtnTipText(ui.inputForm.$dirty, "#{objectName}")}}' data-placement='bottom' data-trigger='hover') Save
+ .panel-tip-container(ng-show='backupItem._id')
+ a.btn.btn-primary(id='clone-item' ng-click='cloneItem()' bs-tooltip=cloneTip data-placement='bottom' data-trigger='hover') Clone
+ .btn-group.panel-tip-container(ng-show='backupItem._id')
+ button.btn.btn-primary(id='remove-item' ng-click='removeItem()' bs-tooltip=removeTip data-placement='bottom' data-trigger='hover') Remove
+ button.btn.dropdown-toggle.btn-primary(id='remove-item-dropdown' data-toggle='dropdown' data-container='body' bs-dropdown='[{ text: "Remove All", click: "removeAllItems()" }]' data-placement='bottom-right')
+ span.caret
+ .panel-tip-container(ng-show='backupItem')
+ i.btn.btn-primary.fa.fa-undo(id='undo-item' ng-disabled='!ui.inputForm.$dirty' ng-click='ui.inputForm.$dirty && resetAll()' bs-tooltip=undoTip data-placement='bottom' data-trigger='hover')
+
+//- Mixin for feedback on specified error.
+mixin error-feedback(visible, error, errorMessage, name)
+ i.fa.fa-exclamation-triangle.form-control-feedback(
+ ng-if=visible
+ bs-tooltip='"#{errorMessage}"'
+ ignite-error=error
+ ignite-error-message=errorMessage
+ name=name
+ )
+
+//- Mixin for feedback on unique violation.
+mixin unique-feedback(name, errorMessage)
+ +form-field-feedback(name, 'igniteUnique', errorMessage)
+
+//- Mixin for feedback on IP address violation.
+mixin ipaddress-feedback(name)
+ +form-field-feedback(name, 'ipaddress', 'Invalid address!')
+
+//- Mixin for feedback on port of IP address violation.
+mixin ipaddress-port-feedback(name)
+ +form-field-feedback(name, 'ipaddressPort', 'Invalid port!')
+
+//- Mixin for feedback on port range violation.
+mixin ipaddress-port-range-feedback(name)
+ +form-field-feedback(name, 'ipaddressPortRange', 'Invalid port range!')
+
+//- Mixin for feedback on UUID violation.
+mixin uuid-feedback(name)
+ +form-field-feedback(name, 'uuid', 'Invalid node ID!')
+
+//- Mixin for checkbox.
+mixin checkbox(lbl, model, name, tip)
+ +form-field-checkbox(lbl, model, name, false, false, tip)
+
+//- Mixin for checkbox with enabled condition.
+mixin checkbox-enabled(lbl, model, name, enabled, tip)
+ if enabled === false || enabled === true
+ -var disabled = !enabled
+ else
+ -var disabled = '!('+enabled+')'
+
+ +form-field-checkbox(lbl, model, name, disabled, false, tip)
+
+//- Mixin for java name field with enabled condition.
+mixin java-class(lbl, model, name, enabled, required, tip)
+ -var errLbl = lbl.substring(0, lbl.length - 1)
+
+ if enabled === false || enabled === true
+ -var disabled = !enabled
+ else
+ -var disabled = '!('+enabled+')'
+
+ +ignite-form-field-text(lbl, model, name, disabled, required, 'Enter fully qualified class name', tip)(
+ data-java-identifier='true'
+ data-java-package-specified='true'
+ data-java-keywords='true'
+ data-java-built-in-class='true'
+ )
+ if block
+ block
+
+ +form-field-feedback(name, 'javaBuiltInClass', errLbl + ' should not be the Java built-in class!')
+ +form-field-feedback(name, 'javaKeywords', errLbl + ' could not contains reserved Java keyword!')
+ +form-field-feedback(name, 'javaPackageSpecified', errLbl + ' does not have package specified!')
+ +form-field-feedback(name, 'javaIdentifier', errLbl + ' is invalid Java identifier!')
+
+
+
+//- Mixin for text field with enabled condition with options.
+mixin java-class-typeahead(lbl, model, name, options, enabled, required, placeholder, tip)
+ -var errLbl = lbl.substring(0, lbl.length - 1)
+
+ +form-field-datalist(lbl, model, name, '!('+enabled+')', required, placeholder, options, tip)(
+ data-java-identifier='true'
+ data-java-package-specified='allow-built-in'
+ data-java-keywords='true'
+ )
+ +form-field-feedback(name, 'javaKeywords', errLbl + ' could not contains reserved Java keyword!')
+ +form-field-feedback(name, 'javaPackageSpecified', errLbl + ' does not have package specified!')
+ +form-field-feedback(name, 'javaIdentifier', errLbl + ' is invalid Java identifier!')
+
+//- Mixin for text field with IP address check.
+mixin text-ip-address(lbl, model, name, enabled, placeholder, tip)
+ +ignite-form-field-text(lbl, model, name, '!('+enabled+')', false, placeholder, tip)(data-ipaddress='true')
+ +ipaddress-feedback(name)
+
+//- Mixin for text field with IP address and port check.
+mixin text-ip-address-with-port(lbl, model, name, enabled, placeholder, tip)
+ +ignite-form-field-text(lbl, model, name, '!('+enabled+')', false, placeholder, tip)(data-ipaddress='true' data-ipaddress-with-port='true')
+ +ipaddress-feedback(name)
+ +ipaddress-port-feedback(name)
+
+//- Mixin for text field.
+mixin text-enabled(lbl, model, name, enabled, required, placeholder, tip)
+ if enabled === false || enabled === true
+ -var disabled = !enabled
+ else
+ -var disabled = '!('+enabled+')'
+
+ +ignite-form-field-text(lbl, model, name, disabled, required, placeholder, tip)
+ if block
+ block
+
+//- Mixin for text field.
+mixin text(lbl, model, name, required, placeholder, tip)
+ +ignite-form-field-text(lbl, model, name, false, required, placeholder, tip)
+ if block
+ block
+
+//- Mixin for text field with enabled condition with options.
+mixin text-options(lbl, model, name, options, enabled, required, placeholder, tip)
+ +form-field-datalist(lbl, model, name, '!('+enabled+')', required, placeholder, options, tip)
+
+//- Mixin for required numeric field.
+mixin number-required(lbl, model, name, enabled, required, placeholder, min, tip)
+ +ignite-form-field-number(lbl, model, name, '!('+enabled+')', required, placeholder, min, false, false, tip)
+
+//- Mixin for required numeric field with maximum and minimum limit.
+mixin number-min-max(lbl, model, name, enabled, placeholder, min, max, tip)
+ +ignite-form-field-number(lbl, model, name, '!('+enabled+')', false, placeholder, min, max, '1', tip)
+
+//- Mixin for required numeric field with maximum and minimum limit.
+mixin number-min-max-step(lbl, model, name, enabled, placeholder, min, max, step, tip)
+ +ignite-form-field-number(lbl, model, name, '!('+enabled+')', false, placeholder, min, max, step, tip)
+
+//- Mixin for numeric field.
+mixin number(lbl, model, name, enabled, placeholder, min, tip)
+ +ignite-form-field-number(lbl, model, name, '!('+enabled+')', false, placeholder, min, false, false, tip)
+
+//- Mixin for required dropdown field.
+mixin dropdown-required-empty(lbl, model, name, enabled, required, placeholder, placeholderEmpty, options, tip)
+ if enabled === false || enabled === true
+ -var disabled = !enabled
+ else
+ -var disabled = '!('+enabled+')'
+
+ +ignite-form-field-dropdown(lbl, model, name, disabled, required, false, placeholder, placeholderEmpty, options, tip)
+ if block
+ block
+
+//- Mixin for required dropdown field.
+mixin dropdown-required(lbl, model, name, enabled, required, placeholder, options, tip)
+ if enabled === false || enabled === true
+ -var disabled = !enabled
+ else
+ -var disabled = '!('+enabled+')'
+
+ +ignite-form-field-dropdown(lbl, model, name, disabled, required, false, placeholder, '', options, tip)
+ if block
+ block
+
+//- Mixin for dropdown field.
+mixin dropdown(lbl, model, name, enabled, placeholder, options, tip)
+ if enabled === false || enabled === true
+ -var disabled = !enabled
+ else
+ -var disabled = '!('+enabled+')'
+
+ +ignite-form-field-dropdown(lbl, model, name, disabled, false, false, placeholder, '', options, tip)
+ if block
+ block
+
+//- Mixin for dropdown-multiple field.
+mixin dropdown-multiple(lbl, model, name, enabled, placeholder, placeholderEmpty, options, tip)
+ if enabled === false || enabled === true
+ -var disabled = !enabled
+ else
+ -var disabled = '!('+enabled+')'
+
+ +ignite-form-field-dropdown(lbl, model, name, disabled, false, true, placeholder, placeholderEmpty, options, tip)
+ if block
+ block
+
+//- Mixin for table text field.
+mixin table-text-field(name, model, items, valid, save, placeholder, newItem)
+ -var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
+ -var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
+
+ -var onEscape = newItem ? 'group.add = []' : 'field.edit = false'
+
+ -var resetOnBlur = newItem ? '!stopblur && (group.add = [])' : 'field.edit = false'
+ -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
+
+ if block
+ block
+
+ .input-tip
+ +ignite-form-field-input(name, model, false, 'true', placeholder)(
+ data-ignite-unique=items
+ data-ignite-form-field-input-autofocus='true'
+ ng-blur=onBlur
+ ignite-on-enter=onEnter
+ ignite-on-escape=onEscape
+ )
+
+//- Mixin for table java class field.
+mixin table-java-class-field(lbl, name, model, items, valid, save, newItem)
+ -var errLbl = lbl.substring(0, lbl.length - 1)
+
+ -var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
+ -var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
+
+ -var onEscape = newItem ? 'group.add = []' : 'field.edit = false'
+
+ -var resetOnBlur = newItem ? '!stopblur && (group.add = [])' : 'field.edit = false'
+ -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
+
+ if block
+ block
+
+ +form-field-feedback(name, 'javaBuiltInClass', errLbl + ' should not be the Java built-in class!')
+ +form-field-feedback(name, 'javaKeywords', errLbl + ' could not contains reserved Java keyword!')
+ +form-field-feedback(name, 'javaPackageSpecified', errLbl + ' does not have package specified!')
+ +form-field-feedback(name, 'javaIdentifier', errLbl + ' is invalid Java identifier!')
+
+ if block
+ block
+
+ .input-tip
+ +ignite-form-field-input(name, model, false, 'true', 'Enter fully qualified class name')(
+ data-java-identifier='true'
+ data-java-package-specified='true'
+ data-java-keywords='true'
+ data-java-built-in-class='true'
+
+ data-ignite-unique=items
+ data-ignite-form-field-input-autofocus='true'
+
+ ng-blur=onBlur
+ ignite-on-enter=onEnter
+ ignite-on-escape=onEscape
+ )
+
+//- Mixin for table java package field.
+mixin table-java-package-field(name, model, items, valid, save, newItem)
+ -var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
+ -var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
+
+ -var onEscape = newItem ? 'group.add = []' : 'field.edit = false'
+
+ -var resetOnBlur = newItem ? '!stopblur && (group.add = [])' : 'field.edit = false'
+ -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
+
+ +form-field-feedback(name, 'javaKeywords', 'Package name could not contains reserved Java keyword!')
+ +form-field-feedback(name, 'javaPackageName', 'Package name is invalid!')
+
+ if block
+ block
+
+ .input-tip
+ +ignite-form-field-input(name, model, false, 'true', 'Enter package name')(
+ data-java-keywords='true'
+ data-java-package-name='true'
+
+ data-ignite-unique=items
+ data-ignite-form-field-input-autofocus='true'
+
+ ng-blur=onBlur
+ ignite-on-enter=onEnter
+ ignite-on-escape=onEscape
+ )
+
+
+//- Mixin for table address field.
+mixin table-address-field(name, model, items, valid, save, newItem, portRange)
+ -var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
+ -var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
+
+ -var onEscape = newItem ? 'group.add = []' : 'field.edit = false'
+
+ -var resetOnBlur = newItem ? '!stopblur && (group.add = [])' : 'field.edit = false'
+ -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
+
+ +ipaddress-feedback(name)
+ +ipaddress-port-feedback(name)
+ +ipaddress-port-range-feedback(name)
+
+ if block
+ block
+
+ .input-tip
+ +ignite-form-field-input(name, model, false, 'true', 'IP address:port')(
+ data-ipaddress='true'
+ data-ipaddress-with-port='true'
+ data-ipaddress-with-port-range=portRange ? 'true' : null
+ data-ignite-unique=items
+ data-ignite-form-field-input-autofocus='true'
+ ng-blur=onBlur
+ ignite-on-enter=onEnter
+ ignite-on-escape=onEscape
+ )
+
+//- Mixin for table UUID field.
+mixin table-uuid-field(name, model, items, valid, save, newItem, portRange)
+ -var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
+ -var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
+
+ -var onEscape = newItem ? 'group.add = []' : 'field.edit = false'
+
+ -var resetOnBlur = newItem ? '!stopblur && (group.add = [])' : 'field.edit = false'
+ -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
+
+ if block
+ block
+
+ .input-tip
+ +ignite-form-field-input(name, model, false, 'true', 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx')(
+ data-uuid='true'
+ data-ignite-unique=items
+ data-ignite-form-field-input-autofocus='true'
+ ng-blur=onBlur
+ ignite-on-enter=onEnter
+ ignite-on-escape=onEscape
+ )
+
+//- Mixin for table save button.
+ "||" used instead of "&&" to workaround escaping of "&&" to "&&"
+mixin table-save-button(valid, save, newItem)
+ -var reset = newItem ? 'group.add = []' : 'field.edit = false'
+
+ i.fa.fa-floppy-o.form-field-save(
+ ng-show=valid
+ ng-click='!(#{valid}) || (#{save}); !(#{valid}) || (#{reset});'
+ bs-tooltip
+ data-title='Click icon or press [Enter] to save item'
+ )
+
+//- Mixin for table remove button.
+mixin table-remove-conditional-button(items, show, tip)
+ i.tipField.fa.fa-remove(
+ ng-hide='!#{show} || field.edit'
+ bs-tooltip
+ data-title=tip
+ ng-click='#{items}.splice(#{items}.indexOf(model), 1)'
+ )
+
+//- Mixin for table remove button.
+mixin table-remove-button(items, tip)
+ +table-remove-conditional-button(items, 'true', tip)
+
+//- Mixin for cache mode.
+mixin cacheMode(lbl, model, name, placeholder)
+ +dropdown(lbl, model, name, 'true', placeholder,
+ '[\
+ {value: "LOCAL", label: "LOCAL"},\
+ {value: "REPLICATED", label: "REPLICATED"},\
+ {value: "PARTITIONED", label: "PARTITIONED"}\
+ ]',
+ 'Cache modes:\
+ <ul>\
+ <li>PARTITIONED - in this mode the overall key set will be divided into partitions and all partitions will be split equally between participating nodes</li>\
+ <li>REPLICATED - in this mode all the keys are distributed to all participating nodes</li>\
+ <li>LOCAL - in this mode caches residing on different grid nodes will not know about each other</li>\
+ </ul>'
+ )
+
+//- Mixin for eviction policy.
+mixin evictionPolicy(model, name, enabled, required, tip)
+ -var kind = model + '.kind'
+ -var policy = model + '[' + kind + ']'
+
+ +dropdown-required('Eviction policy:', kind, name + '+ "Kind"', enabled, required, 'Not set',
+ '[\
+ {value: "LRU", label: "LRU"},\
+ {value: "FIFO", label: "FIFO"},\
+ {value: "SORTED", label: "Sorted"},\
+ {value: undefined, label: "Not set"}\
+ ]', tip)
+ span(ng-if=kind ng-init='__ = {};')
+ a.customize(ng-show='__.expanded' ng-click='__.expanded = false') Hide settings
+ a.customize(ng-hide='__.expanded' ng-click='__.expanded = true') Show settings
+ .panel-details(ng-if='__.expanded')
+ .details-row
+ +number('Batch size', policy + '.batchSize', name + '+ "batchSize"', enabled, '1', '0',
+ 'Number of entries to remove on shrink')
+ .details-row
+ +number('Max memory size', policy + '.maxMemorySize', name + '+ "maxMemorySize"', enabled, '0', '0',
+ 'Maximum allowed cache size in bytes')
+ .details-row
+ +number('Max size', policy + '.maxSize', name + '+ "maxSize"', enabled, '100000', '0',
+ 'Maximum allowed size of cache before entry will start getting evicted')
+
+//- Mixin for clusters dropdown.
+mixin clusters(model, tip)
+ +dropdown-multiple('<span>Clusters:</span>' + '<a ui-sref="base.configuration.clusters({linkId: linkId()})"> (add)</a>',
+ model + '.clusters', '"clusters"', true, 'Choose clusters', 'No clusters configured', 'clusters', tip)
+
+//- Mixin for caches dropdown.
+mixin caches(model, tip)
+ +dropdown-multiple('<span>Caches:</span>' + '<a ui-sref="base.configuration.caches({linkId: linkId()})"> (add)</a>',
+ model + '.caches', '"caches"', true, 'Choose caches', 'No caches configured', 'caches', tip)
+
+//- Mixin for XML and Java preview.
+mixin preview-xml-java(master, generator, detail)
+ ignite-ui-ace-tabs
+ .preview-panel
+ .preview-legend
+ a(ng-class='{active: !mode, inactive: mode}' ng-click='mode = false') XML
+ |
+ a(ng-class='{active: mode, inactive: !mode}' ng-click='mode = true') Java
+ .preview-content(ng-if='mode')
+ ignite-ui-ace-java(data-master=master data-generator=generator ng-model='$parent.data' data-detail=detail)
+ .preview-content(ng-if='!mode')
+ ignite-ui-ace-xml(data-master=master data-generator=generator ng-model='$parent.data' data-detail=detail)
+ .preview-content-empty(ng-if='!data')
+ label All Defaults
+
+//- LEGACY mixin for LEGACY tables.
+mixin btn-save(show, click)
+ i.tipField.fa.fa-floppy-o(ng-show=show ng-click=click bs-tooltip='' data-title='Click icon or press [Enter] to save item' data-trigger='hover')
+
+//- LEGACY mixin for LEGACY tables.
+mixin btn-add(click, tip)
+ i.tipField.fa.fa-plus(ng-click=click bs-tooltip=tip data-trigger = 'hover')
+
+//- LEGACY mixin for LEGACY tables.
+mixin btn-remove(click, tip)
+ i.tipField.fa.fa-remove(ng-click=click bs-tooltip=tip data-trigger='hover')
+
+//- LEGACY mixin for LEGACY tables.
+mixin btn-remove-cond(cond, click, tip)
+ i.tipField.fa.fa-remove(ng-show=cond ng-click=click bs-tooltip=tip data-trigger='hover')
+
+//- LEGACY mixin for LEGACY pair values tables.
+mixin table-pair-edit(tbl, prefix, keyPlaceholder, valPlaceholder, keyJavaBuiltInTypes, valueJavaBuiltInTypes, focusId, index, divider)
+ -var keyModel = tbl + '.' + prefix + 'Key'
+ -var valModel = tbl +'.' + prefix + 'Value'
+
+ -var keyFocusId = prefix + 'Key' + focusId
+ -var valFocusId = prefix + 'Value' + focusId
+
+ .col-xs-6.col-sm-6.col-md-6
+ .fieldSep !{divider}
+ .input-tip
+ if keyJavaBuiltInTypes
+ input.form-control(id=keyFocusId ignite-on-enter-focus-move=valFocusId type='text' ng-model=keyModel placeholder=keyPlaceholder bs-typeahead container='body' ignite-retain-selection data-min-length='1' bs-options='javaClass for javaClass in javaBuiltInClasses' ignite-on-escape='tableReset()')
+ else
+ input.form-control(id=keyFocusId ignite-on-enter-focus-move=valFocusId type='text' ng-model=keyModel placeholder=keyPlaceholder ignite-on-escape='tableReset()')
+ .col-xs-6.col-sm-6.col-md-6
+ -var arg = keyModel + ', ' + valModel
+ -var btnVisible = 'tablePairSaveVisible(' + tbl + ', ' + index + ')'
+ -var btnSave = 'tablePairSave(tablePairValid, backupItem, ' + tbl + ', ' + index + ')'
+ -var btnVisibleAndSave = btnVisible + ' && ' + btnSave
+
+ +btn-save(btnVisible, btnSave)
+ .input-tip
+ if valueJavaBuiltInTypes
+ input.form-control(id=valFocusId type='text' ng-model=valModel placeholder=valPlaceholder bs-typeahead container='body' ignite-retain-selection data-min-length='1' bs-options='javaClass for javaClass in javaBuiltInClasses' ignite-on-enter=btnVisibleAndSave ignite-on-escape='tableReset()')
+ else
+ input.form-control(id=valFocusId type='text' ng-model=valModel placeholder=valPlaceholder ignite-on-enter=btnVisibleAndSave ignite-on-escape='tableReset()')
+
+//- Mixin for DB dialect.
+mixin dialect(lbl, model, name, required, tipTitle, genericDialectName, placeholder)
+ +dropdown(lbl, model, name, required, placeholder, '[\
+ {value: "Generic", label: "' + genericDialectName + '"},\
+ {value: "Oracle", label: "Oracle"},\
+ {value: "DB2", label: "IBM DB2"},\
+ {value: "SQLServer", label: "Microsoft SQL Server"},\
+ {value: "MySQL", label: "MySQL"},\
+ {value: "PostgreSQL", label: "PostgreSQL"},\
+ {value: "H2", label: "H2 database"}\
+ ]',
+ tipTitle +
+ '<ul>\
+ <li>' + genericDialectName + '</li>\
+ <li>Oracle database</li>\
+ <li>IBM DB2</li>\
+ <li>Microsoft SQL Server</li>\
+ <li>MySQL</li>\
+ <li>PostgreSQL</li>\
+ <li>H2 database</li>\
+ </ul>')
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/Demo/Demo.module.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/Demo/Demo.module.js b/modules/web-console/frontend/app/modules/Demo/Demo.module.js
new file mode 100644
index 0000000..83d55ed
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/Demo/Demo.module.js
@@ -0,0 +1,166 @@
+/*
+ * 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.
+ */
+
+import angular from 'angular';
+
+import DEMO_INFO from 'app/data/demo-info.json';
+
+angular
+.module('ignite-console.demo', [
+ 'ignite-console.socket'
+])
+.config(['$stateProvider', ($stateProvider) => {
+ $stateProvider
+ .state('demo', {
+ abstract: true,
+ template: '<ui-view></ui-view>'
+ })
+ .state('demo.resume', {
+ url: '/demo',
+ controller: ['$state', ($state) => {
+ $state.go('base.configuration.clusters');
+ }],
+ metaTags: {
+ }
+ })
+ .state('demo.reset', {
+ url: '/demo/reset',
+ controller: ['$state', '$http', 'IgniteMessages', ($state, $http, Messages) => {
+ $http.post('/api/v1/demo/reset')
+ .success(() => $state.go('base.configuration.clusters'))
+ .error((err) => {
+ $state.go('base.configuration.clusters');
+
+ Messages.showError(err);
+ });
+ }],
+ metaTags: {}
+ });
+}])
+.provider('Demo', ['$stateProvider', '$httpProvider', 'igniteSocketFactoryProvider', function($state, $http, socketFactory) {
+ if (/(\/demo.*)/ig.test(location.pathname))
+ sessionStorage.setItem('IgniteDemoMode', 'true');
+
+ const enabled = sessionStorage.getItem('IgniteDemoMode') === 'true';
+
+ if (enabled) {
+ socketFactory.set({query: 'IgniteDemoMode=true'});
+
+ $http.interceptors.push('demoInterceptor');
+ }
+
+ this.$get = ['$rootScope', ($root) => {
+ $root.IgniteDemoMode = enabled;
+
+ return {enabled};
+ }];
+}])
+.factory('demoInterceptor', ['Demo', (Demo) => {
+ const isApiRequest = (url) => /\/api\/v1/ig.test(url);
+
+ return {
+ request(cfg) {
+ if (Demo.enabled && isApiRequest(cfg.url))
+ cfg.headers.IgniteDemoMode = true;
+
+ return cfg;
+ }
+ };
+}])
+.controller('demoController', ['$scope', '$state', '$window', 'IgniteConfirm', ($scope, $state, $window, Confirm) => {
+ const _openTab = (stateName) => $window.open($state.href(stateName), '_blank');
+
+ $scope.startDemo = () => {
+ if (!$scope.user.demoCreated)
+ return _openTab('demo.reset');
+
+ Confirm.confirm('Would you like to continue with previous demo session?', true, false)
+ .then((resume) => {
+ if (resume)
+ return _openTab('demo.resume');
+
+ _openTab('demo.reset');
+ });
+ };
+
+ $scope.closeDemo = () => {
+ $window.close();
+ };
+}])
+.provider('igniteDemoInfo', [function() {
+ const items = DEMO_INFO;
+
+ this.update = (data) => items[0] = data;
+
+ this.$get = [() => {
+ return items;
+ }];
+}])
+.service('DemoInfo', ['$rootScope', '$modal', '$state', '$q', 'igniteDemoInfo', 'IgniteAgentMonitor', ($rootScope, $modal, $state, $q, igniteDemoInfo, agentMonitor) => {
+ const scope = $rootScope.$new();
+
+ let closePromise = null;
+
+ function _fillPage() {
+ const model = igniteDemoInfo;
+
+ scope.title = model[0].title;
+ scope.message = model[0].message.join(' ');
+ }
+
+ const dialog = $modal({
+ templateUrl: '/templates/demo-info.html',
+ scope,
+ placement: 'center',
+ show: false,
+ backdrop: 'static'
+ });
+
+ scope.close = () => {
+ dialog.hide();
+
+ closePromise && closePromise.resolve();
+ };
+
+ scope.downloadAgent = () => {
+ const lnk = document.createElement('a');
+
+ lnk.setAttribute('href', '/api/v1/agent/download/zip');
+ lnk.setAttribute('target', '_self');
+ lnk.setAttribute('download', null);
+ lnk.style.display = 'none';
+
+ document.body.appendChild(lnk);
+
+ lnk.click();
+
+ document.body.removeChild(lnk);
+ };
+
+ return {
+ show: () => {
+ closePromise = $q.defer();
+
+ _fillPage();
+
+ return dialog.$promise
+ .then(dialog.show)
+ .then(() => Promise.race([agentMonitor.awaitAgent(), closePromise.promise]))
+ .then(() => scope.hasAgents = true);
+ }
+ };
+}]);
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/ace.module.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/ace.module.js b/modules/web-console/frontend/app/modules/ace.module.js
new file mode 100644
index 0000000..4920a6f
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/ace.module.js
@@ -0,0 +1,269 @@
+/*
+ * 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.
+ */
+
+import angular from 'angular';
+
+angular
+ .module('ignite-console.ace', [])
+ .constant('igniteAceConfig', {})
+ .directive('igniteAce', ['igniteAceConfig', (aceConfig) => {
+ if (angular.isUndefined(window.ace))
+ throw new Error('ignite-ace need ace to work... (o rly?)');
+
+ /**
+ * Sets editor options such as the wrapping mode or the syntax checker.
+ *
+ * The supported options are:
+ *
+ * <ul>
+ * <li>showGutter</li>
+ * <li>useWrapMode</li>
+ * <li>onLoad</li>
+ * <li>theme</li>
+ * <li>mode</li>
+ * </ul>
+ *
+ * @param acee
+ * @param session ACE editor session.
+ * @param {object} opts Options to be set.
+ */
+ const setOptions = (acee, session, opts) => {
+ // Sets the ace worker path, if running from concatenated or minified source.
+ if (angular.isDefined(opts.workerPath)) {
+ const config = window.ace.acequire('ace/config');
+
+ config.set('workerPath', opts.workerPath);
+ }
+
+ // Ace requires loading.
+ _.forEach(opts.require, (n) => window.ace.acequire(n));
+
+ // Boolean options.
+ if (angular.isDefined(opts.showGutter))
+ acee.renderer.setShowGutter(opts.showGutter);
+
+ if (angular.isDefined(opts.useWrapMode))
+ session.setUseWrapMode(opts.useWrapMode);
+
+ if (angular.isDefined(opts.showInvisibles))
+ acee.renderer.setShowInvisibles(opts.showInvisibles);
+
+ if (angular.isDefined(opts.showIndentGuides))
+ acee.renderer.setDisplayIndentGuides(opts.showIndentGuides);
+
+ if (angular.isDefined(opts.useSoftTabs))
+ session.setUseSoftTabs(opts.useSoftTabs);
+
+ if (angular.isDefined(opts.showPrintMargin))
+ acee.setShowPrintMargin(opts.showPrintMargin);
+
+ // Commands.
+ if (angular.isDefined(opts.disableSearch) && opts.disableSearch) {
+ acee.commands.addCommands([{
+ name: 'unfind',
+ bindKey: {
+ win: 'Ctrl-F',
+ mac: 'Command-F'
+ },
+ exec: _.constant(false),
+ readOnly: true
+ }]);
+ }
+
+ // Base options.
+ if (angular.isString(opts.theme))
+ acee.setTheme('ace/theme/' + opts.theme);
+
+ if (angular.isString(opts.mode))
+ session.setMode('ace/mode/' + opts.mode);
+
+ if (angular.isDefined(opts.firstLineNumber)) {
+ if (angular.isNumber(opts.firstLineNumber))
+ session.setOption('firstLineNumber', opts.firstLineNumber);
+ else if (angular.isFunction(opts.firstLineNumber))
+ session.setOption('firstLineNumber', opts.firstLineNumber());
+ }
+
+ // Advanced options.
+ if (angular.isDefined(opts.advanced)) {
+ for (const key in opts.advanced) {
+ if (opts.advanced.hasOwnProperty(key)) {
+ // Create a javascript object with the key and value.
+ const obj = {name: key, value: opts.advanced[key]};
+
+ // Try to assign the option to the ace editor.
+ acee.setOption(obj.name, obj.value);
+ }
+ }
+ }
+
+ // Advanced options for the renderer.
+ if (angular.isDefined(opts.rendererOptions)) {
+ for (const key in opts.rendererOptions) {
+ if (opts.rendererOptions.hasOwnProperty(key)) {
+ // Create a javascript object with the key and value.
+ const obj = {name: key, value: opts.rendererOptions[key]};
+
+ // Try to assign the option to the ace editor.
+ acee.renderer.setOption(obj.name, obj.value);
+ }
+ }
+ }
+
+ // onLoad callbacks.
+ _.forEach(opts.callbacks, (cb) => {
+ if (angular.isFunction(cb))
+ cb(acee);
+ });
+ };
+
+ return {
+ restrict: 'EA',
+ require: ['?ngModel', '?^form'],
+ link: (scope, elm, attrs, [ngModel, form]) => {
+ /**
+ * Corresponds the igniteAceConfig ACE configuration.
+ *
+ * @type object
+ */
+ const options = aceConfig.ace || {};
+
+ /**
+ * IgniteAceConfig merged with user options via json in attribute or data binding.
+ *
+ * @type object
+ */
+ let opts = angular.extend({}, options, scope.$eval(attrs.igniteAce));
+
+ /**
+ * ACE editor.
+ *
+ * @type object
+ */
+ const acee = window.ace.edit(elm[0]);
+
+ /**
+ * ACE editor session.
+ *
+ * @type object
+ * @see [EditSession]{@link http://ace.c9.io/#nav=api&api=edit_session}
+ */
+ const session = acee.getSession();
+
+ /**
+ * Reference to a change listener created by the listener factory.
+ *
+ * @function
+ * @see listenerFactory.onChange
+ */
+ let onChangeListener;
+
+ /**
+ * Creates a change listener which propagates the change event and the editor session
+ * to the callback from the user option onChange.
+ * It might be exchanged during runtime, if this happens the old listener will be unbound.
+ *
+ * @param callback Callback function defined in the user options.
+ * @see onChangeListener
+ */
+ const onChangeFactory = (callback) => {
+ return (e) => {
+ const newValue = session.getValue();
+
+ if (ngModel && newValue !== ngModel.$viewValue &&
+ // HACK make sure to only trigger the apply outside of the
+ // digest loop 'cause ACE is actually using this callback
+ // for any text transformation !
+ !scope.$$phase && !scope.$root.$$phase)
+ scope.$eval(() => ngModel.$setViewValue(newValue));
+
+ if (angular.isDefined(callback)) {
+ scope.$evalAsync(() => {
+ if (angular.isFunction(callback))
+ callback([e, acee]);
+ else
+ throw new Error('ignite-ace use a function as callback');
+ });
+ }
+ };
+ };
+
+ attrs.$observe('readonly', (value) => acee.setReadOnly(!!value || value === ''));
+
+ // Value Blind.
+ if (ngModel) {
+ // Remove "ngModel" controller from parent form for correct dirty checks.
+ form && form.$removeControl(ngModel);
+
+ ngModel.$formatters.push((value) => {
+ if (angular.isUndefined(value) || value === null)
+ return '';
+
+ if (angular.isObject(value) || angular.isArray(value))
+ throw new Error('ignite-ace cannot use an object or an array as a model');
+
+ return value;
+ });
+
+ ngModel.$render = () => session.setValue(ngModel.$viewValue);
+
+ acee.on('change', () => ngModel.$setViewValue(acee.getValue()));
+ }
+
+ // Listen for option updates.
+ const updateOptions = (current, previous) => {
+ if (current === previous)
+ return;
+
+ opts = angular.extend({}, options, scope.$eval(attrs.igniteAce));
+
+ opts.callbacks = [opts.onLoad];
+
+ // Also call the global onLoad handler.
+ if (opts.onLoad !== options.onLoad)
+ opts.callbacks.unshift(options.onLoad);
+
+ // Unbind old change listener.
+ session.removeListener('change', onChangeListener);
+
+ // Bind new change listener.
+ onChangeListener = onChangeFactory(opts.onChange);
+
+ session.on('change', onChangeListener);
+
+ setOptions(acee, session, opts);
+ };
+
+ scope.$watch(attrs.igniteAce, updateOptions, /* deep watch */ true);
+
+ // Set the options here, even if we try to watch later,
+ // if this line is missing things go wrong (and the tests will also fail).
+ updateOptions(options);
+
+ elm.on('$destroy', () => {
+ acee.session.$stopWorker();
+ acee.destroy();
+ });
+
+ scope.$watch(() => [elm[0].offsetWidth, elm[0].offsetHeight],
+ () => {
+ acee.resize();
+ acee.renderer.updateFull();
+ }, true);
+ }
+ };
+ }]);
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/agent/agent.module.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/agent/agent.module.js b/modules/web-console/frontend/app/modules/agent/agent.module.js
new file mode 100644
index 0000000..22ced13
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/agent/agent.module.js
@@ -0,0 +1,341 @@
+/*
+ * 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.
+ */
+
+import angular from 'angular';
+import io from 'socket.io-client'; // eslint-disable-line no-unused-vars
+
+const maskNull = (val) => _.isEmpty(val) ? 'null' : val;
+
+class IgniteAgentMonitor {
+ constructor(socketFactory, $root, $q, $state, $modal, Messages) {
+ this._scope = $root.$new();
+
+ $root.$watch('user', () => {
+ this._scope.user = $root.user;
+ });
+
+ $root.$on('$stateChangeStart', () => {
+ this.stopWatch();
+ });
+
+ // Pre-fetch modal dialogs.
+ this._downloadAgentModal = $modal({
+ scope: this._scope,
+ templateUrl: '/templates/agent-download.html',
+ show: false,
+ backdrop: 'static',
+ keyboard: false
+ });
+
+ const _modalHide = this._downloadAgentModal.hide;
+
+ /**
+ * Special dialog hide function.
+ */
+ this._downloadAgentModal.hide = () => {
+ Messages.hideAlert();
+
+ _modalHide();
+ };
+
+ /**
+ * Close dialog and go by specified link.
+ */
+ this._scope.back = () => {
+ this.stopWatch();
+
+ if (this._scope.backState)
+ this._scope.$$postDigest(() => $state.go(this._scope.backState));
+ };
+
+ this._scope.downloadAgent = () => {
+ const lnk = document.createElement('a');
+
+ lnk.setAttribute('href', '/api/v1/agent/download/zip');
+ lnk.setAttribute('target', '_self');
+ lnk.setAttribute('download', null);
+ lnk.style.display = 'none';
+
+ document.body.appendChild(lnk);
+
+ lnk.click();
+
+ document.body.removeChild(lnk);
+ };
+
+ this._scope.hasAgents = null;
+ this._scope.showModal = false;
+
+ /**
+ * @type {Socket}
+ */
+ this._socket = null;
+
+ this._socketFactory = socketFactory;
+
+ this._$q = $q;
+
+ this.Messages = Messages;
+ }
+
+ /**
+ * @private
+ */
+ checkModal() {
+ if (this._scope.showModal && !this._scope.hasAgents)
+ this._downloadAgentModal.$promise.then(this._downloadAgentModal.show);
+ else if ((this._scope.hasAgents || !this._scope.showModal) && this._downloadAgentModal.$isShown)
+ this._downloadAgentModal.hide();
+ }
+
+ /**
+ * @returns {Promise}
+ */
+ awaitAgent() {
+ if (this._scope.hasAgents)
+ return this._$q.when();
+
+ const latch = this._$q.defer();
+
+ const offConnected = this._scope.$on('agent:watch', (event, state) => {
+ if (state !== 'DISCONNECTED')
+ offConnected();
+
+ if (state === 'CONNECTED')
+ return latch.resolve();
+
+ if (state === 'STOPPED')
+ return latch.reject('Agent watch stopped.');
+ });
+
+ return latch.promise;
+ }
+
+ init() {
+ if (this._socket)
+ return;
+
+ this._socket = this._socketFactory();
+
+ const disconnectFn = () => {
+ this._scope.hasAgents = false;
+
+ this.checkModal();
+
+ this._scope.$broadcast('agent:watch', 'DISCONNECTED');
+ };
+
+ this._socket.on('connect_error', disconnectFn);
+ this._socket.on('disconnect', disconnectFn);
+
+ this._socket.on('agent:count', ({count}) => {
+ this._scope.hasAgents = count > 0;
+
+ this.checkModal();
+
+ this._scope.$broadcast('agent:watch', this._scope.hasAgents ? 'CONNECTED' : 'DISCONNECTED');
+ });
+ }
+
+ /**
+ * @param {Object} back
+ * @returns {Promise}
+ */
+ startWatch(back) {
+ this._scope.backState = back.state;
+ this._scope.backText = back.text;
+
+ this._scope.agentGoal = back.goal;
+
+ if (back.onDisconnect) {
+ this._scope.offDisconnect = this._scope.$on('agent:watch', (e, state) =>
+ state === 'DISCONNECTED' && back.onDisconnect());
+ }
+
+ this._scope.showModal = true;
+
+ // Remove blinking on init.
+ if (this._scope.hasAgents !== null)
+ this.checkModal();
+
+ return this.awaitAgent();
+ }
+
+ /**
+ *
+ * @param {String} event
+ * @param {Object} [args]
+ * @returns {Promise}
+ * @private
+ */
+ _emit(event, ...args) {
+ if (!this._socket)
+ return this._$q.reject('Failed to connect to server');
+
+ const latch = this._$q.defer();
+
+ const onDisconnect = () => {
+ this._socket.removeListener('disconnect', onDisconnect);
+
+ latch.reject('Connection to server was closed');
+ };
+
+ this._socket.on('disconnect', onDisconnect);
+
+ args.push((err, res) => {
+ this._socket.removeListener('disconnect', onDisconnect);
+
+ if (err)
+ latch.reject(err);
+
+ latch.resolve(res);
+ });
+
+ this._socket.emit(event, ...args);
+
+ return latch.promise;
+ }
+
+ drivers() {
+ return this._emit('schemaImport:drivers');
+ }
+
+ /**
+ *
+ * @param {Object} preset
+ * @returns {Promise}
+ */
+ schemas(preset) {
+ return this._emit('schemaImport:schemas', preset);
+ }
+
+ /**
+ *
+ * @param {Object} preset
+ * @returns {Promise}
+ */
+ tables(preset) {
+ return this._emit('schemaImport:tables', preset);
+ }
+
+ /**
+ * @param {Object} err
+ */
+ showNodeError(err) {
+ if (this._scope.showModal) {
+ this._downloadAgentModal.$promise.then(this._downloadAgentModal.show);
+
+ this.Messages.showError(err);
+ }
+ }
+
+ /**
+ *
+ * @param {String} event
+ * @param {Object} [args]
+ * @returns {Promise}
+ * @private
+ */
+ _rest(event, ...args) {
+ return this._downloadAgentModal.$promise
+ .then(() => this._emit(event, ...args));
+ }
+
+ /**
+ * @param {Boolean} [attr]
+ * @param {Boolean} [mtr]
+ * @returns {Promise}
+ */
+ topology(attr, mtr) {
+ return this._rest('node:topology', !!attr, !!mtr);
+ }
+
+ /**
+ * @param {String} nid Node id.
+ * @param {int} [queryId]
+ * @returns {Promise}
+ */
+ queryClose(nid, queryId) {
+ return this._rest('node:query:close', nid, queryId);
+ }
+
+ /**
+ * @param {String} nid Node id.
+ * @param {String} cacheName Cache name.
+ * @param {String} [query] Query if null then scan query.
+ * @param {Boolean} local Flag whether to execute query locally.
+ * @param {int} pageSize
+ * @returns {Promise}
+ */
+ query(nid, cacheName, query, local, pageSize) {
+ return this._rest('node:query', nid, maskNull(cacheName), maskNull(query), local, pageSize)
+ .then(({result}) => {
+ if (_.isEmpty(result.key))
+ return result.value;
+
+ return Promise.reject(result.key);
+ });
+ }
+
+ /**
+ * @param {String} nid Node id.
+ * @param {String} cacheName Cache name.
+ * @param {String} [query] Query if null then scan query.
+ * @param {Boolean} local Flag whether to execute query locally.
+ * @returns {Promise}
+ */
+ queryGetAll(nid, cacheName, query, local) {
+ return this._rest('node:query:getAll', nid, maskNull(cacheName), maskNull(query), local);
+ }
+
+ /**
+ * @param {String} nid Node id.
+ * @param {int} queryId
+ * @param {int} pageSize
+ * @returns {Promise}
+ */
+ next(nid, queryId, pageSize) {
+ return this._rest('node:query:fetch', nid, queryId, pageSize)
+ .then(({result}) => result);
+ }
+
+ /**
+ * @param {String} [cacheName] Cache name.
+ * @returns {Promise}
+ */
+ metadata(cacheName) {
+ return this._rest('node:cache:metadata', maskNull(cacheName));
+ }
+
+ stopWatch() {
+ this._scope.showModal = false;
+
+ this.checkModal();
+
+ this._scope.offDisconnect && this._scope.offDisconnect();
+
+ this._scope.$broadcast('agent:watch', 'STOPPED');
+ }
+}
+
+IgniteAgentMonitor.$inject = ['igniteSocketFactory', '$rootScope', '$q', '$state', '$modal', 'IgniteMessages'];
+
+angular
+ .module('ignite-console.agent', [
+
+ ])
+ .service('IgniteAgentMonitor', IgniteAgentMonitor);
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/branding/branding.module.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/branding/branding.module.js b/modules/web-console/frontend/app/modules/branding/branding.module.js
new file mode 100644
index 0000000..cae7c91
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/branding/branding.module.js
@@ -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.
+ */
+
+import angular from 'angular';
+
+import IgniteBranding from './branding.provider';
+
+import igniteHeaderLogo from './header-logo.directive';
+import igniteHeaderTitle from './header-title.directive';
+import igniteTerms from './terms.directive';
+import igniteFeatures from './features.directive';
+import igniteFooter from './footer.directive';
+import ignitePoweredByApache from './powered-by-apache.directive';
+
+angular
+.module('ignite-console.branding', [
+ 'ui.router.metatags'
+])
+.provider(...IgniteBranding)
+.config(['UIRouterMetatagsProvider', (UIRouterMetatagsProvider) => {
+ UIRouterMetatagsProvider
+ .setDefaultTitle('Apache Ignite - Management Tool and Configuration Wizard')
+ .setTitleSuffix(' \u2013 Apache Ignite Web Console')
+ .setDefaultDescription('The Apache Ignite Web Console is an interactive management tool and configuration wizard which walks you through the creation of config files. Try it now.');
+}])
+.directive(...ignitePoweredByApache)
+.directive(...igniteHeaderLogo)
+.directive(...igniteHeaderTitle)
+.directive(...igniteTerms)
+.directive(...igniteFeatures)
+.directive(...igniteFooter);
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/branding/branding.provider.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/branding/branding.provider.js b/modules/web-console/frontend/app/modules/branding/branding.provider.js
new file mode 100644
index 0000000..ce14b34
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/branding/branding.provider.js
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+export default ['IgniteBranding', [function() {
+ let titleSuffix = ' \u2013 Apache Ignite Web Console';
+
+ let headerLogo = '/images/ignite-logo.png';
+
+ let headerText = 'Management console for Apache Ignite';
+
+ let showIgniteLogo = false;
+
+ let footerHtml = [
+ '<p>Apache Ignite Web Console</p>',
+ '<p>� 2016 The Apache Software Foundation.</p>',
+ '<p>Apache, Apache Ignite, the Apache feather and the Apache Ignite logo are trademarks of The Apache Software Foundation.</p>'
+ ];
+
+ let termsState;
+
+ let featuresHtml = [
+ '<p>Web Console is an interactive management tool which allows to:</p>',
+ '<ul>',
+ ' <li>Create and download cluster configurations</li>',
+ ' <li>Automatically import domain model from any RDBMS</li>',
+ ' <li>Connect to cluster and run SQL analytics on it</li>',
+ '</ul>'
+ ];
+
+ /**
+ * Change title suffix.
+ *
+ * @param {String} suffix.
+ */
+ this.titleSuffix = (suffix) => {
+ titleSuffix = suffix;
+ };
+
+ /**
+ * Change logo in header.
+ *
+ * @param {String} url Logo path.
+ */
+ this.headerLogo = (url) => {
+ headerLogo = url;
+
+ showIgniteLogo = true;
+ };
+
+ /**
+ * Change text in header.
+ *
+ * @param {String} text Header text.
+ */
+ this.headerText = (text) => {
+ headerText = text;
+ };
+
+ /**
+ * Change text in features.
+ *
+ * @param {Array.<String>} rows Features text.
+ */
+ this.featuresHtml = (rows) => {
+ featuresHtml = rows;
+ };
+
+ /**
+ * Change text in footer.
+ *
+ * @param {Array.<String>} rows Footer text.
+ */
+ this.footerHtml = (rows) => {
+ footerHtml = rows;
+ };
+
+ /**
+ * Set terms and conditions stage.
+ *
+ * @param {String} state
+ */
+ this.termsState = (state) => {
+ termsState = state;
+ };
+
+ this.$get = [() => {
+ return {
+ titleSuffix,
+ headerLogo,
+ headerText,
+ featuresHtml: featuresHtml.join('\n'),
+ footerHtml: footerHtml.join('\n'),
+ showIgniteLogo,
+ termsState
+ };
+ }];
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/branding/features.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/branding/features.directive.js b/modules/web-console/frontend/app/modules/branding/features.directive.js
new file mode 100644
index 0000000..9226a3f
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/branding/features.directive.js
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+const template = '<div class="features" ng-bind-html="features.html"></div>';
+
+export default ['igniteFeatures', ['IgniteBranding', (branding) => {
+ function controller() {
+ const ctrl = this;
+
+ ctrl.html = branding.featuresHtml;
+ }
+
+ return {
+ restrict: 'E',
+ template,
+ controller,
+ controllerAs: 'features',
+ replace: true
+ };
+}]];
+
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/branding/footer.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/branding/footer.directive.js b/modules/web-console/frontend/app/modules/branding/footer.directive.js
new file mode 100644
index 0000000..f0b1994
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/branding/footer.directive.js
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+const template = '<div class="footer" ng-bind-html="footer.html"></div>';
+
+export default ['igniteFooter', ['IgniteBranding', (branding) => {
+ function controller() {
+ const ctrl = this;
+
+ ctrl.html = branding.footerHtml;
+ }
+
+ return {
+ restrict: 'E',
+ template,
+ controller,
+ controllerAs: 'footer',
+ replace: true
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/branding/header-logo.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/branding/header-logo.directive.js b/modules/web-console/frontend/app/modules/branding/header-logo.directive.js
new file mode 100644
index 0000000..423de9c
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/branding/header-logo.directive.js
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+import templateUrl from './header-logo.jade';
+
+export default ['igniteHeaderLogo', ['IgniteBranding', (branding) => {
+ function controller() {
+ const ctrl = this;
+
+ ctrl.url = branding.headerLogo;
+ }
+
+ return {
+ restrict: 'E',
+ templateUrl,
+ controller,
+ controllerAs: 'logo',
+ replace: true
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/branding/header-logo.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/branding/header-logo.jade b/modules/web-console/frontend/app/modules/branding/header-logo.jade
new file mode 100644
index 0000000..b58f670
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/branding/header-logo.jade
@@ -0,0 +1,18 @@
+//-
+ 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.
+
+a(ui-sref='signin')
+ img.navbar-brand(ng-src='{{logo.url}}' height='40')
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/branding/header-title.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/branding/header-title.directive.js b/modules/web-console/frontend/app/modules/branding/header-title.directive.js
new file mode 100644
index 0000000..d560e0a
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/branding/header-title.directive.js
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+const template = '<h1 class="title">{{::title.text}}</h1>';
+
+export default ['igniteHeaderTitle', ['IgniteBranding', (branding) => {
+ function controller() {
+ const ctrl = this;
+
+ ctrl.text = branding.headerText;
+ }
+
+ return {
+ restrict: 'E',
+ template,
+ controller,
+ controllerAs: 'title',
+ replace: true
+ };
+}]];
+
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/branding/powered-by-apache.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/branding/powered-by-apache.directive.js b/modules/web-console/frontend/app/modules/branding/powered-by-apache.directive.js
new file mode 100644
index 0000000..2f02446
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/branding/powered-by-apache.directive.js
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+import templateUrl from './powered-by-apache.jade';
+
+export default ['ignitePoweredByApache', ['IgniteBranding', (branding) => {
+ function controller() {
+ const ctrl = this;
+
+ ctrl.show = branding.showIgniteLogo;
+ }
+
+ return {
+ restrict: 'E',
+ templateUrl,
+ controller,
+ controllerAs: 'poweredBy',
+ replace: true
+ };
+}]];
+
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/branding/powered-by-apache.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/branding/powered-by-apache.jade b/modules/web-console/frontend/app/modules/branding/powered-by-apache.jade
new file mode 100644
index 0000000..af9aadf
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/branding/powered-by-apache.jade
@@ -0,0 +1,18 @@
+//-
+ 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.
+
+a(ng-if='poweredBy.show' href='//ignite.apache.org' target='_blank')
+ img(ng-src='/images/pb-ignite.png' height='65')
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/branding/terms.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/branding/terms.directive.js b/modules/web-console/frontend/app/modules/branding/terms.directive.js
new file mode 100644
index 0000000..0207745
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/branding/terms.directive.js
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+export default ['igniteTerms', ['IgniteBranding', (branding) => {
+ function controller() {
+ const ctrl = this;
+
+ ctrl.termsState = branding.termsState;
+ }
+
+ return {
+ restrict: 'A',
+ controller,
+ controllerAs: 'terms'
+ };
+}]];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/configuration/EventGroups.provider.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/configuration/EventGroups.provider.js b/modules/web-console/frontend/app/modules/configuration/EventGroups.provider.js
new file mode 100644
index 0000000..61f3188
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/configuration/EventGroups.provider.js
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+// Events groups.
+import GROUPS from 'app/data/event-types.json';
+
+export default ['igniteEventGroups', function() {
+ const groups = GROUPS;
+
+ this.push = (data) => groups.push(data);
+
+ this.$get = [() => {
+ return groups;
+ }];
+}];
+
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/configuration/Sidebar.provider.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/configuration/Sidebar.provider.js b/modules/web-console/frontend/app/modules/configuration/Sidebar.provider.js
new file mode 100644
index 0000000..8bd5ba3
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/configuration/Sidebar.provider.js
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+import angular from 'angular';
+
+export default ['igniteSidebar', function() {
+ const items = [
+ { text: 'Clusters', sref: 'base.configuration.clusters' },
+ { text: 'Model', sref: 'base.configuration.domains' },
+ { text: 'Caches', sref: 'base.configuration.caches' },
+ { text: 'IGFS', sref: 'base.configuration.igfs' }
+ ];
+
+ this.push = function(data) {
+ items.push(data);
+ };
+
+ this.$get = [function() {
+ const r = angular.copy(items);
+
+ r.push({ text: 'Summary', sref: 'base.configuration.summary' });
+
+ return r;
+ }];
+}];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/configuration/configuration.module.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/configuration/configuration.module.js b/modules/web-console/frontend/app/modules/configuration/configuration.module.js
new file mode 100644
index 0000000..99830b0
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/configuration/configuration.module.js
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+import angular from 'angular';
+
+import igniteEventGroups from './EventGroups.provider';
+import igniteSidebar from './Sidebar.provider';
+
+import GeneratorXml from './generator/Xml.service';
+import GeneratorJava from './generator/Java.service';
+import GeneratorDocker from './generator/Docker.service';
+import GeneratorPom from './generator/Pom.service';
+
+import igniteSidebarDirective from './sidebar.directive';
+
+// Ignite events groups.
+angular
+.module('ignite-console.configuration', [
+
+])
+.provider(...igniteEventGroups)
+.provider(...igniteSidebar)
+.directive(...igniteSidebarDirective)
+.service(...GeneratorXml)
+.service(...GeneratorJava)
+.service(...GeneratorDocker)
+.service(...GeneratorPom);
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/configuration/generator/Docker.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/configuration/generator/Docker.service.js b/modules/web-console/frontend/app/modules/configuration/generator/Docker.service.js
new file mode 100644
index 0000000..f9776a2
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/configuration/generator/Docker.service.js
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+/**
+ * Docker file generation entry point.
+ */
+class GeneratorDocker {
+ /**
+ * Generate from section.
+ *
+ * @param {Object} cluster Cluster.
+ * @param {String} ver Ignite version.
+ * @returns {String}
+ */
+ from(cluster, ver) {
+ return [
+ '# Start from Apache Ignite image.',
+ `FROM apacheignite/ignite:${ver}`
+ ].join('\n');
+ }
+
+ /**
+ * Generate Docker file for cluster.
+ *
+ * @param {Object} cluster Cluster.
+ * @param {String} ver Ignite version.
+ */
+ generate(cluster, ver) {
+ return [
+ this.from(cluster, ver),
+ '',
+ '# Set config uri for node.',
+ `ENV CONFIG_URI config/${cluster.name}-server.xml`,
+ '',
+ '# Copy ignite-http-rest from optional.',
+ 'ENV OPTION_LIBS ignite-rest-http',
+ '',
+ '# Update packages and install maven.',
+ 'RUN \\',
+ ' apt-get update &&\\',
+ ' apt-get install -y maven',
+ '',
+ '# Append project to container.',
+ `ADD . ${cluster.name}`,
+ '',
+ '# Build project in container.',
+ `RUN mvn -f ${cluster.name}/pom.xml clean package -DskipTests`,
+ '',
+ '# Copy project jars to node classpath.',
+ `RUN mkdir $IGNITE_HOME/libs/${cluster.name} && \\`,
+ ` find ${cluster.name}/target -name "*.jar" -type f -exec cp {} $IGNITE_HOME/libs/${cluster.name} \\; && \\`,
+ ` cp -r ${cluster.name}/config/* $IGNITE_HOME/config`
+ ].join('\n');
+ }
+
+ ignoreFile() {
+ return [
+ 'target',
+ 'Dockerfile'
+ ].join('\n');
+ }
+}
+
+export default ['GeneratorDocker', GeneratorDocker];
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/configuration/generator/Java.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/configuration/generator/Java.service.js b/modules/web-console/frontend/app/modules/configuration/generator/Java.service.js
new file mode 100644
index 0000000..67e19b9
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/configuration/generator/Java.service.js
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+// TODO IGNITE-2054: need move $generatorJava to services.
+export default ['GeneratorJava', () => {
+ return $generatorJava;
+}];