http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8a335724/modules/web-control-center/src/main/js/routes/metadata.js ---------------------------------------------------------------------- diff --git a/modules/web-control-center/src/main/js/routes/metadata.js b/modules/web-control-center/src/main/js/routes/metadata.js new file mode 100644 index 0000000..64b8763 --- /dev/null +++ b/modules/web-control-center/src/main/js/routes/metadata.js @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var router = require('express').Router(); +var db = require('../db'); + +/* GET metadata page. */ +router.get('/', function (req, res) { + res.render('configuration/metadata'); +}); + +/** + * Get spaces and metadata accessed for user account. + * + * @param req Request. + * @param res Response. + */ +router.post('/list', function (req, res) { + var user_id = req.currentUserId(); + + // Get owned space and all accessed space. + db.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) { + if (err) + return res.status(500).send(err.message); + + var space_ids = spaces.map(function (value) { + return value._id; + }); + + // Get all metadata for spaces. + db.CacheTypeMetadata.find({space: {$in: space_ids}}).sort('name').exec(function (err, metadatas) { + if (err) + return res.status(500).send(err.message); + + res.json({spaces: spaces, metadatas: metadatas}); + }); + }); +}); + +/** + * Save metadata. + */ +router.post('/save', function (req, res) { + if (req.body._id) + db.CacheTypeMetadata.update({_id: req.body._id}, req.body, {upsert: true}, function (err) { + if (err) + return res.status(500).send(err.message); + + res.send(req.body._id); + }); + else { + db.CacheTypeMetadata.findOne({name: req.body.name}, function (err, metadata) { + if (err) + return res.status(500).send(err.message); + + if (metadata) + return res.status(500).send('Cache type metadata with name: "' + metadata.name + '" already exist.'); + + (new db.CacheTypeMetadata(req.body)).save(function (err, metadata) { + if (err) + return res.status(500).send(err.message); + + res.send(metadata._id); + }); + }); + } +}); + +/** + * Remove metadata by ._id. + */ +router.post('/remove', function (req, res) { + db.CacheTypeMetadata.remove(req.body, function (err) { + if (err) + return res.status(500).send(err.message); + + res.sendStatus(200); + }) +}); + +module.exports = router; \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8a335724/modules/web-control-center/src/main/js/routes/profile.js ---------------------------------------------------------------------- diff --git a/modules/web-control-center/src/main/js/routes/profile.js b/modules/web-control-center/src/main/js/routes/profile.js new file mode 100644 index 0000000..0269e7d --- /dev/null +++ b/modules/web-control-center/src/main/js/routes/profile.js @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var router = require('express').Router(); +var db = require('../db'); + +router.all('/profile/*', function (req, res, next) { + var userId = req.body._id; + + if (userId != req.currentUserId() && userId != req.user._id) + return res.sendStatus(403); + else + next(); +}); + +/** + * Get user profile page. + */ +router.get('/', function (req, res) { + var user_id = req.currentUserId(); + + db.Account.findById(user_id, function (err) { + if (err) + return res.status(500).send(err.message); + + res.render('settings/profile'); + }); +}); + +/** + * Save user profile. + */ +router.post('/saveUser', function (req, res) { + var params = req.body; + + if (params.newPassword) { + var newPassword = params.newPassword; + + if (!newPassword || newPassword.length == 0) + return res.status(500).send('Wrong value for new password'); + + db.Account.findById(params._id, function (err, user) { + if (err) + return res.status(500).send(err); + + user.setPassword(newPassword, function (err, updatedUser) { + if (err) + return res.status(500).send(err.message); + + if (params.userName) + updatedUser.username = params.userName; + + if (params.email) + updatedUser.email = params.email; + + updatedUser.save(function (err) { + if (err) + return res.status(500).send(err.message); + + res.json(user); + }); + }); + }); + } + else if (params.userName || params.email) { + var upd = {}; + + if (params.userName) + upd.username = params.userName; + + if (params.email) + upd.email = params.email; + + db.Account.findByIdAndUpdate(params._id, upd, {new: true}, function (err, val) { + if (err) + return res.status(500).send(err.message); + + res.json(val); + }) + } +}); + +module.exports = router; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8a335724/modules/web-control-center/src/main/js/routes/public.js ---------------------------------------------------------------------- diff --git a/modules/web-control-center/src/main/js/routes/public.js b/modules/web-control-center/src/main/js/routes/public.js new file mode 100644 index 0000000..290ba90 --- /dev/null +++ b/modules/web-control-center/src/main/js/routes/public.js @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var router = require('express').Router(); +var passport = require('passport'); +var db = require('../db'); + +// GET dropdown-menu template. +router.get('/select', function (req, res) { + res.render('templates/select', {}); +}); + +// GET tabs template. +router.get('/tab', function (req, res) { + res.render('templates/tab', {}); +}); + +// GET confirmation dialog. +router.get('/confirm', function (req, res) { + res.render('templates/confirm', {}); +}); + +// GET save as dialog. +router.get('/copy', function (req, res) { + res.render('templates/copy', {}); +}); + +/* GET login page. */ +router.get('/login', function (req, res) { + res.render('login'); +}); + +/** + * Register new account. + */ +router.post('/register', function (req, res) { + db.Account.count(function (err, cnt) { + if (err) + return res.status(401).send(err.message); + + req.body.admin = cnt == 0; + + db.Account.register(new db.Account(req.body), req.body.password, function (err, account) { + if (err) + return res.status(401).send(err.message); + + if (!account) + return res.status(500).send('Failed to create account.'); + + new db.Space({name: 'Personal space', owner: account._id}).save(); + + req.logIn(account, {}, function (err) { + if (err) + return res.status(401).send(err.message); + + return res.redirect('/configuration/clusters'); + }); + }); + }); +}); + +/** + * Login in exist account. + */ +router.post('/login', function (req, res, next) { + passport.authenticate('local', function (err, user) { + if (err) + return res.status(401).send(err.message); + + if (!user) + return res.status(401).send('Invalid email or password'); + + req.logIn(user, {}, function (err) { + if (err) + return res.status(401).send(err.message); + + res.redirect('/configuration/clusters'); + }); + })(req, res, next); +}); + +/** + * Logout. + */ +router.get('/logout', function (req, res) { + req.logout(); + + res.redirect('/'); +}); + +/* GET home page. */ +router.get('/', function (req, res) { + if (req.isAuthenticated()) + res.redirect('/configuration/clusters'); + else + res.render('index'); +}); + +///* GET sql page. */ +//router.get('/sql', function(req, res) { +// res.render('sql', { user: req.user }); +//}); +// +///* GET clients page. */ +//router.get('/clients', function(req, res) { +// res.render('clients', { user: req.user }); +//}); + +module.exports = router; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8a335724/modules/web-control-center/src/main/js/routes/sql.js ---------------------------------------------------------------------- diff --git a/modules/web-control-center/src/main/js/routes/sql.js b/modules/web-control-center/src/main/js/routes/sql.js new file mode 100644 index 0000000..ce4565d --- /dev/null +++ b/modules/web-control-center/src/main/js/routes/sql.js @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var router = require('express').Router(); +var db = require('../db'); +router.get('/', function(req, res) { + res.render('sql/sql'); +}); + +module.exports = router; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8a335724/modules/web-control-center/src/main/js/routes/summary.js ---------------------------------------------------------------------- diff --git a/modules/web-control-center/src/main/js/routes/summary.js b/modules/web-control-center/src/main/js/routes/summary.js new file mode 100644 index 0000000..f766945 --- /dev/null +++ b/modules/web-control-center/src/main/js/routes/summary.js @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var db = require('../db'); + +var router = require('express').Router(); + +var generatorXml = require('./generator/xml'); +var generatorJava = require('./generator/java'); +var generatorDocker = require('./generator/docker'); + +/* GET summary page. */ +router.get('/', function (req, res) { + res.render('configuration/summary'); +}); + +router.post('/generator', function (req, res) { + // Get cluster. + db.Cluster.findById(req.body._id).populate('caches').exec(function (err, cluster) { + if (err) + return res.status(500).send(err.message); + + if (!cluster) + return res.sendStatus(404); + + var clientCache = req.body.clientNearConfiguration; + + if (clientCache) + return res.send({ + xmlClient: generatorXml.generateClusterConfiguration(cluster, clientCache), + javaClient: generatorJava.generateClusterConfiguration(cluster, req.body.javaClass, clientCache) + }); + + return res.send({ + xmlServer: generatorXml.generateClusterConfiguration(cluster), + javaSnippetServer: generatorJava.generateClusterConfiguration(cluster, false), + javaClassServer: generatorJava.generateClusterConfiguration(cluster, true), + docker: generatorDocker.generateClusterConfiguration(cluster, '%OS%') + }); + }); +}); + +router.post('/download', function (req, res) { + // Get cluster. + db.Cluster.findById(req.body._id).populate('caches').exec(function (err, cluster) { + if (err) + return res.status(500).send(err.message); + + if (!cluster) + return res.sendStatus(404); + + var clientNearConfiguration = req.body.clientNearConfiguration; + + var archiver = require('archiver'); + + // Creating archive. + var zip = archiver('zip'); + + zip.on('error', function (err) { + res.status(500).send({error: err.message}); + }); + + // On stream closed we can end the request. + res.on('close', function () { + return res.status(200).send('OK').end(); + }); + + // Set the archive name. + res.attachment(cluster.name + (clientNearConfiguration ? '-client' : '') + '-configuration.zip'); + + var generatorCommon = require('./generator/common'); + + // Send the file to the page output. + zip.pipe(res); + + var javaClass = req.body.javaClass; + + if (!clientNearConfiguration) { + zip.append(generatorDocker.generateClusterConfiguration(cluster, req.body.os), {name: "Dockerfile"}); + + var props = generatorCommon.generateProperties(cluster); + + if (props) + zip.append(props, {name: "secret.properties"}); + } + + zip.append(generatorXml.generateClusterConfiguration(cluster, clientNearConfiguration), {name: cluster.name + ".xml"}) + .append(generatorJava.generateClusterConfiguration(cluster, javaClass, clientNearConfiguration), + {name: javaClass ? 'ConfigurationFactory.java' : cluster.name + '.snipplet.java'}) + .finalize(); + }); +}); + +module.exports = router; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8a335724/modules/web-control-center/src/main/js/views/configuration/caches.jade ---------------------------------------------------------------------- diff --git a/modules/web-control-center/src/main/js/views/configuration/caches.jade b/modules/web-control-center/src/main/js/views/configuration/caches.jade new file mode 100644 index 0000000..3a011fc --- /dev/null +++ b/modules/web-control-center/src/main/js/views/configuration/caches.jade @@ -0,0 +1,74 @@ +//- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +extends sidebar + +append scripts + script(src='/caches-controller.js') + +include ../includes/controls + +block content + .docs-header + h1 Create and Configure Ignite Caches + hr + .docs-body(ng-controller='cachesController') + +block-callout('{{screenTip.workflowTitle}}', 'joinTip(screenTip.workflowContent)', '{{screenTip.whatsNextTitle}}', 'joinTip(screenTip.whatsNextContent)') + .links(ng-hide='caches.length == 0') + .padding-dflt + lable.labelHeader Caches: + table(st-table='caches') + tbody + tr(ng-repeat='row in caches track by row._id') + td.col-sm-6(ng-class='{active: row._id == selectedItem._id}') + a(ng-click='selectItem(row)') {{$index + 1}}) {{row.name}}, {{row.mode | displayValue:modes:'Cache mode not set'}}, {{row.atomicityMode | displayValue:atomicities:'Cache atomicity not set'}} + .padding-top-dflt + button.btn.btn-primary(ng-click='createItem()') Add cache + hr + form.form-horizontal(name='inputForm' ng-if='backupItem' novalidate) + div(bs-collapse data-start-collapsed='false') + .panel.panel-default + .panel-heading + h3 + a(bs-collapse-toggle) General + .panel-collapse(bs-collapse-target) + .panel-body + .settings-row(ng-repeat='field in general') + +form-row(['col-sm-3'], ['col-sm-3']) + .panel-group(bs-collapse data-allow-multiple="true") + div(bs-collapse data-start-collapsed='true') + .panel-title(ng-show='expanded') + h3 + a(bs-collapse-toggle='0' ng-click='expanded = !expanded;') {{expanded ? 'Hide advanced settings...' : 'Show advanced settings...'}} + .panel-collapse(bs-collapse-target) + .span(bs-collapse data-start-collapsed='true' data-allow-multiple='true') + .panel.panel-default(ng-repeat='group in advanced') + .panel-heading + h3 + a(bs-collapse-toggle) {{group.label}} + i.tipLabel.fa.fa-question-circle(ng-if='group.tip' bs-tooltip='joinTip(group.tip)' type='button') + i.tipLabel.fa.fa-question-circle.blank(ng-if='!group.tip') + .panel-collapse(bs-collapse-target) + .panel-body + .settings-row(ng-repeat='field in group.fields') + +form-row + .panel-title + h3 + a(bs-collapse-toggle='0' ng-click='expanded = !expanded;') {{expanded ? 'Hide advanced settings...' : 'Show advanced settings...'}} + div + button.btn.btn-primary(ng-disabled='inputForm.$invalid' ng-click='saveItem()') Save + button.btn.btn-primary(ng-show='backupItem._id' ng-disabled='inputForm.$invalid' ng-click='saveItemAs()') Copy + button.btn.btn-primary.btn-second(ng-show='backupItem._id' ng-click='removeItem()') Remove http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8a335724/modules/web-control-center/src/main/js/views/configuration/clusters.jade ---------------------------------------------------------------------- diff --git a/modules/web-control-center/src/main/js/views/configuration/clusters.jade b/modules/web-control-center/src/main/js/views/configuration/clusters.jade new file mode 100644 index 0000000..81acfed --- /dev/null +++ b/modules/web-control-center/src/main/js/views/configuration/clusters.jade @@ -0,0 +1,77 @@ +//- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +extends sidebar + +append scripts + script(src='/clusters-controller.js') + +include ../includes/controls + +block content + .docs-header + h1 Create and Configure Ignite Clusters + hr + .docs-body(ng-controller='clustersController') + +block-callout('{{screenTip.workflowTitle}}', 'joinTip(screenTip.workflowContent)', '{{screenTip.whatsNextTitle}}', 'joinTip(screenTip.whatsNextContent)') + .links(ng-hide='clusters.length == 0') + .padding-dflt + lable.labelHeader Clusters: + table(st-table='clusters') + tbody + tr(ng-repeat='row in clusters track by row._id') + td.col-sm-6(ng-class='{active: row._id == selectedItem._id}') + a(ng-click='selectItem(row)') {{$index + 1}}) {{row.name}}, {{row.discovery.kind | displayValue:discoveries:'Discovery not set'}} + .padding-top-dflt + button.btn.btn-primary(ng-click='createItem()')  Add cluster + label(style='margin-left: 10px; margin-right: 10px') Use template: + button.btn.btn-default.base-control(ng-init='create.template = templates[0].value' ng-model='create.template' data-template='/select' data-placeholder='Choose cluster template' bs-options='item.value as item.label for item in templates' bs-select) + i.tiplabel.fa.fa-question-circle(bs-tooltip data-title='{{joinTip(templateTip)}}' type='button') + hr + form.form-horizontal(name='inputForm' ng-if='backupItem' novalidate) + div(bs-collapse data-start-collapsed='false') + .panel.panel-default + .panel-heading + h3 + a(bs-collapse-toggle) General + .panel-collapse(bs-collapse-target) + .panel-body + .settings-row(ng-repeat='field in general') + +form-row + .panel-group(bs-collapse data-allow-multiple="true") + div(bs-collapse data-start-collapsed='true') + .panel-title(ng-show='expanded') + h3 + a(bs-collapse-toggle='0' ng-click='expanded = !expanded;') {{expanded ? 'Hide advanced settings...' : 'Show advanced settings...'}} + .panel-collapse(bs-collapse-target) + .span(bs-collapse data-start-collapsed='true' data-allow-multiple='true') + .panel.panel-default(ng-repeat='group in advanced') + .panel-heading + h3 + a(bs-collapse-toggle) {{group.label}} + i.tipLabel.fa.fa-question-circle(ng-if='group.tip' bs-tooltip='joinTip(group.tip)' type='button') + i.tipLabel.fa.fa-question-circle.blank(ng-if='!group.tip') + .panel-collapse(bs-collapse-target) + .panel-body + .settings-row(ng-repeat='field in group.fields') + +form-row + .panel-title + h3 + a(bs-collapse-toggle='0' ng-click='expanded = !expanded;') {{expanded ? 'Hide advanced settings...' : 'Show advanced settings...'}} + div + button.btn.btn-primary(ng-disabled='inputForm.$invalid' ng-click='saveItem()') Save + button.btn.btn-primary(ng-show='backupItem._id' ng-disabled='inputForm.$invalid' ng-click='saveItemAs()') Copy + button.btn.btn-primary(ng-show='backupItem._id' ng-click='removeItem()') Remove \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8a335724/modules/web-control-center/src/main/js/views/configuration/metadata.jade ---------------------------------------------------------------------- diff --git a/modules/web-control-center/src/main/js/views/configuration/metadata.jade b/modules/web-control-center/src/main/js/views/configuration/metadata.jade new file mode 100644 index 0000000..d5bac06 --- /dev/null +++ b/modules/web-control-center/src/main/js/views/configuration/metadata.jade @@ -0,0 +1,121 @@ +//- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +extends sidebar + +append scripts + script(src='/metadata-controller.js') + +include ../includes/controls + +block content + .docs-header + h1 Create and Configure Cache Type Metadata + hr + .docs-body(ng-controller='metadataController') + +block-callout('{{screenTip.workflowTitle}}', 'joinTip(screenTip.workflowContent)', '{{screenTip.whatsNextTitle}}', 'joinTip(screenTip.whatsNextContent)') + .links(ng-hide='metadatas.length == 0') + .padding-dflt + lable.labelHeader Types metadata: + table(st-table='metadatas') + tbody + tr(ng-repeat='row in metadatas track by row._id') + td.col-sm-6(ng-class='{active: row._id == selectedItem._id}') + a(ng-click='selectItem(row)') {{$index + 1}}) {{row.name}} + .padding-top-dflt + button.btn.btn-primary(ng-click='panels.activePanel = [0]; createItem()')  Add metadata + label(style='margin-left: 6px; margin-right: 10px') For: + button.btn.btn-default(ng-model='template' data-template='/select' data-placeholder='Choose metadata type' bs-options='item.value as item.label for item in templates' bs-select) + i.tiplabel.fa.fa-question-circle(bs-tooltip data-title='{{joinTip(templateTip)}}' type='button') + hr + .panel-group(bs-collapse ng-model='panels.activePanel' data-allow-multiple="false") + .panel.panel-default + .panel-heading + h3 + a(bs-collapse-toggle) Manual + .panel-collapse(role="tabpanel" bs-collapse-target) + .panel-body + form.form-horizontal(name='manualForm' ng-if='backupItem' novalidate) + .settings-row(ng-repeat='field in metadataManual') + +form-row + button.btn.btn-primary(ng-disabled='manualForm.$invalid' ng-click='saveItem()') Save + button.btn.btn-primary(ng-show='backupItem._id' ng-disabled='inputForm.$invalid' ng-click='saveItemAs()') Copy + button.btn.btn-primary.btn-second(ng-show='backupItem._id' ng-click='removeItem()') Remove + .panel.panel-default + .panel-heading + h3 + a(bs-collapse-toggle) Load from database + .panel-collapse(bs-collapse-target) + .panel-body + form.form-horizontal(name='dbForm' novalidate) + .settings-row(ng-repeat='field in metadataDb') + +form-row + div(ng-hide='data.tables.length == 0') + table.table-bordered.table-condensed.links-edit-small-padding.col-sm-12(st-table='data.tables') + thead + tr + th.col-sm-3 Schema/Table + th Key class + th Value class + tbody + tr(ng-repeat='row in data.tables') + td(colspan='{{row.tableName ? 1 : 3}}') + div.checkbox(ng-if='!row.tableName') + label(ng-click='selectSchema($index)') + input(type='checkbox' ng-checked='row.use') + | {{row.schemaName}} + div.checkbox(ng-if='row.tableName') + label(style='padding-left: 30px' ng-click='selectTable($index)') + input(type='checkbox' ng-checked = 'row.use') + | {{row.tableName}} + td(ng-if='row.tableName') + a(ng-show='data.curTableIdx != $index' ng-click='selectTable($index)') {{row.keyClass}} + input.form-control(type='text' ng-show='data.curTableIdx == $index' ng-model='data.curKeyClass' placeholder='Key class full name') + td(ng-if='row.tableName') + a(ng-show='data.curTableIdx != $index' ng-click='selectTable($index)') {{row.valueClass}} + input.form-control(type='text' ng-show='data.curTableIdx == $index' ng-model='data.curValueClass' placeholder='Value class full name') + //div(ng-hide='data.curTableIdx < 0') + // table.table-bordered.table-condensed.links-edit-small-padding.col-sm-12(st-table='data.tables[data.curTableIdx].fields') + // thead + // tr + // th(style='width:45px') Use + // th(style='width:45px') Key + // th(style='width:45px') Ak + // th DB Name + // th DB Type + // th Java Name + // th Java Type + // tbody + // tr(ng-repeat='row in data.tables[data.curTableIdx].fields') + // td + // +dbcheck('row.use') + // td + // +dbcheck('row.key') + // td + // +dbcheck('row.ak') + // td + // label {{row.dbName}} + // td + // label {{row.dbType}} + // td + // a(ng-show='data.curFieldIdx != $index' ng-click='selectField($index)') {{row.javaName}} + // input.form-control(type='text' ng-show='data.curFieldIdx == $index' ng-model='data.curJavaName' placeholder='Field Java name') + // td + // a(ng-show='data.curFieldIdx != $index' ng-click='selectField($index)') {{row.javaType}} + // input.form-control(type='text' ng-show='data.curFieldIdx == $index' ng-model='data.curJavaType' placeholder='Field Java type') + button.btn.btn-primary(ng-disabled='dbForm.$invalid' ng-click='saveItem()') Save + button.btn.btn-primary.btn-second(ng-show='backupItem._id' ng-click='removeItem()') Remove + button.btn.btn-primary.btn-second(ng-click='reloadMetadata()') Reload \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8a335724/modules/web-control-center/src/main/js/views/configuration/sidebar.jade ---------------------------------------------------------------------- diff --git a/modules/web-control-center/src/main/js/views/configuration/sidebar.jade b/modules/web-control-center/src/main/js/views/configuration/sidebar.jade new file mode 100644 index 0000000..7289f3e --- /dev/null +++ b/modules/web-control-center/src/main/js/views/configuration/sidebar.jade @@ -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. + +extends ../templates/layout + +mixin sidebar-item(ref, num, txt) + li + a(ng-class='{active: isActive("#{ref}")}' href='#{ref}') + span.fa-stack + i.fa.fa-circle-thin.fa-stack-2x + i.fa.fa-stack-1x #{num} + | #{txt} + +block container + .row + .col-sm-2.border-right.section-left.greedy + .sidebar-nav(bs-affix) + ul.menu(ng-controller='activeLink') + +sidebar-item('/configuration/clusters', 1, 'Clusters') + +sidebar-item('/configuration/metadata', 2, 'Metadata') + +sidebar-item('/configuration/caches', 3, 'Caches') + +sidebar-item('/configuration/summary', 4, 'Summary') + + .col-sm-10.border-left.section-right + .docs-content + block content \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8a335724/modules/web-control-center/src/main/js/views/configuration/summary.jade ---------------------------------------------------------------------- diff --git a/modules/web-control-center/src/main/js/views/configuration/summary.jade b/modules/web-control-center/src/main/js/views/configuration/summary.jade new file mode 100644 index 0000000..6f2f6d8 --- /dev/null +++ b/modules/web-control-center/src/main/js/views/configuration/summary.jade @@ -0,0 +1,117 @@ +//- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +extends sidebar + +append scripts + script(src='/summary-controller.js') + + script(src="//cdn.jsdelivr.net/angularjs/1.3.15/angular-animate.min.js") + script(src="//cdn.jsdelivr.net/angularjs/1.3.15/angular-sanitize.min.js") + + script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/theme-chrome.js') + script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/mode-xml.js') + script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/mode-java.js') + script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/mode-dockerfile.js') + +append css + +include ../includes/controls + +mixin hard-link(ref, txt) + a(style='color:#ec1c24' href=ref target="_blank") #{txt} + +block content + .docs-header + h1 Configurations Summary + hr + .docs-body(ng-controller='summaryController') + +block-callout('{{screenTip.workflowTitle}}', 'joinTip(screenTip.workflowContent)', '{{screenTip.whatsNextTitle}}', 'joinTip(screenTip.whatsNextContent)') + .padding-dflt(ng-if='clusters.length == 0') + | No cluster configured. You can + a(href='clusters') configure + | it. + .padding-dflt(ng-if='clusters.length > 0') + lable.labelHeader Clusters: + .links + table(st-table='clusters') + tbody + tr(ng-repeat='row in clusters track by row._id') + td.col-sm-6(ng-class='{active: row._id == selectedItem._id}') + a(ng-click='selectItem(row)') {{$index + 1}}) {{row.name}} + div(ng-show='selectedItem' role="tab" method='post' action='summary/download') + .padding-dflt(bs-collapse data-start-collapsed='false') + .panel.panel-default + form.panel-heading(role='tab' method='post' action='summary/download') + input(type="hidden" name="_id" value="{{selectedItem._id}}") + input(type="hidden" name="os" value="{{os}}") + input(type="hidden" name="javaClass" value="{{javaClassServer}}") + h3 + a(bs-collapse-toggle) Server + button.btn.btn-primary.pull-right(type='submit' style='margin-top: -5px') Download + .panel-collapse(role="tabpanel" bs-collapse-target) + .panel-body + .configBox(ng-show='selectedItem' bs-tabs) + div(title='<img src="/images/xml.png" width="16px" height="16px"/> XML' bs-pane) + .configBox(ui-ace='{ onLoad: aceInit, mode: "xml" }' ng-model='xmlServer' style='margin: 0.65em 0;') + div(title='<img src="/images/java.png" width="16px" height="16px"/> Java' bs-pane) + .settings-row + .col-sm-1 + label Generate: + .col-sm-3 + button.form-control(type='button' ng-model='configServer.javaClassServer' bs-select data-placeholder='{{detail.placeholder}}' bs-options='item.value as item.label for item in javaClassItems' data-sort='false') + .configBox(ui-ace='{ onLoad: aceInit, mode: "java" }' ng-model='javaServer') + div(title='<img src="/images/docker.png" width="16px" height="16px"/> Dockerfile' bs-pane) + .settings-row + p + +hard-link('https://docs.docker.com/reference/builder', 'Docker') + | file is a text file with instructions to create Docker image.<br/> + | To build image you have to store following Docker file with your Ignite XML configuration to the same directory.<br> + | Also you could use predefined + +hard-link('https://ignite.incubator.apache.org/download.html#docker', 'Apache Ignite docker image') + | . For more information about using Ignite with Docker please read + +hard-link('http://apacheignite.readme.io/docs/docker-deployment', 'documentation') + |. + .col-sm-2 + label(for='os') Operation System: + .col-sm-4 + input#os.form-control(type='text', ng-model='configServer.os' placeholder='debian:8' data-min-length="0" data-html="1" data-auto-select="true" data-animation="am-flip-x" bs-typeahead bs-options='os for os in oss') + div(ui-ace='{ onLoad: aceInit, mode: "dockerfile" }' ng-model='dockerServer') + .padding-dflt(bs-collapse data-start-collapsed='false') + .panel.panel-default + form.panel-heading(role='tab' method='post' action='summary/download') + input(type="hidden" name="_id" value="{{selectedItem._id}}") + input(type="hidden" name="javaClass" value="{{javaClassClient}}") + input(type="hidden" name="clientNearConfiguration" value="{{backupItem}}") + + h3 + a(bs-collapse-toggle) Client + button.btn.btn-primary.pull-right(type='submit' style='margin-top: -5px') Download + .panel-collapse(role="tabpanel" bs-collapse-target) + .panel-body + div(ng-show='selectedItem') + .settings-row(ng-repeat='field in clientFields') + +form-row-custom(['col-sm-3'], ['col-sm-3']) + .configBox(bs-tabs) + div(title='<img src="/images/xml.png" width="16px" height="16px"/> XML' bs-pane) + .configBox(ui-ace='{ onLoad: aceInit, mode: "xml" }' ng-model='xmlClient' style='margin: 0.65em 0;') + div(title='<img src="/images/java.png" width="16px" height="16px"/> Java' bs-pane) + .settings-row + .col-sm-1 + label Generate: + .col-sm-4 + button.form-control(type='button' ng-model='backupItem.javaClassClient' bs-select data-placeholder='{{detail.placeholder}}' bs-options='item.value as item.label for item in javaClassItems' data-sort='false') + div(ui-ace='{ onLoad: aceInit, mode: "java" }' ng-model='javaClient') http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8a335724/modules/web-control-center/src/main/js/views/error.jade ---------------------------------------------------------------------- diff --git a/modules/web-control-center/src/main/js/views/error.jade b/modules/web-control-center/src/main/js/views/error.jade new file mode 100644 index 0000000..b458fb7 --- /dev/null +++ b/modules/web-control-center/src/main/js/views/error.jade @@ -0,0 +1,22 @@ +//- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +extends templates/layout + +block container + h1= message + h2= error.status + pre #{error.stack} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8a335724/modules/web-control-center/src/main/js/views/includes/controls.jade ---------------------------------------------------------------------- diff --git a/modules/web-control-center/src/main/js/views/includes/controls.jade b/modules/web-control-center/src/main/js/views/includes/controls.jade new file mode 100644 index 0000000..4a618fa --- /dev/null +++ b/modules/web-control-center/src/main/js/views/includes/controls.jade @@ -0,0 +1,322 @@ +//- + 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 block-callout(titleWorkflow, contentWorkflow, whatsNextWorkflow, whatsNextContent) + .block-callout-parent.block-callout-border.margin-bottom-dflt + .block-callout + i.fa.fa-check-square + label #{titleWorkflow} + p(ng-bind-html=contentWorkflow) + .block-callout + i.fa.fa-check-square + label #{whatsNextWorkflow} + p(ng-bind-html=whatsNextContent) + + +mixin tipField(lines) + i.tipField.fa.fa-question-circle(ng-if=lines bs-tooltip='joinTip(#{lines})' type='button') + i.tipField.fa.fa-question-circle.blank(ng-if='!#{lines}') + +mixin tipLabel(lines) + i.tipLabel.fa.fa-question-circle(ng-if=lines bs-tooltip='joinTip(#{lines})' type='button') + i.tipLabel.fa.fa-question-circle.blank(ng-if='!#{lines}') + +mixin ico-exclamation(mdl, err, msg) + i.fa.fa-exclamation-triangle.form-control-feedback(ng-show='inputForm["#{mdl}"].$error.#{err}' bs-tooltip data-title='#{msg}' type='button') + +mixin btn-save(show, click) + i.tipField.fa.fa-floppy-o(ng-show=show ng-click=click) + +mixin btn-add(click) + i.tipField.fa.fa-plus(ng-click=click) + +mixin btn-remove(click) + i.tipField.fa.fa-remove(ng-click=click) + +mixin btn-up(show, click) + i.tipField.fa.fa-arrow-up(ng-show=show ng-click=click) + +mixin btn-down(show, click) + i.tipField.fa.fa-arrow-down(ng-show=show ng-click=click) + +mixin table-pair-edit(keyModel, valModel, keyPlaceholder, valPlaceholder) + .col-sm-6(style='float: right') + input.form-control(type='text' ng-model=valModel placeholder=valPlaceholder) + label.fieldSep / + .input-tip + input.form-control(type='text' ng-model=keyModel placeholder=keyPlaceholder) + +mixin table-pair(header, tblMdl, keyFld, valFld, keyPlaceholder, valPlaceholder) + .col-sm-6 + label.table-header #{header}: + +tipLabel('field.tip') + button.btn.btn-primary.fieldButton(ng-click='tableNewItem(field)') Add + table.links-edit.col-sm-12(st-table=tblMdl) + tbody + tr.col-sm-12(ng-repeat='item in #{tblMdl}') + td.col-sm-6 + div(ng-show='!tableEditing(field, $index)') + a.labelFormField(ng-click='curPair = tableStartEdit(backupItem, field, $index); curKey = curPair.#{keyFld}; curValue = curPair.#{valFld}') {{$index + 1}}) {{item.#{keyFld}}} / {{item.#{valFld}}} + +btn-remove('tableRemove(backupItem, field, $index)') + div(ng-show='tableEditing(field, $index)') + label.labelField {{$index + 1}}) + +btn-save('tablePairSaveVisible(curKey, curValue)', 'tablePairSave(tablePairValid, backupItem, field, curKey, curValue, $index)') + +table-pair-edit('curKey', 'curValue', keyPlaceholder, valPlaceholder) + tr.col-sm-12(ng-show='tableNewItemActive(field)') + td.col-sm-6 + +btn-save('tablePairSaveVisible(newKey, newValue)', 'tablePairSave(tablePairValid, backupItem, field, newKey, newValue, -1)') + +table-pair-edit('newKey', 'newValue', keyPlaceholder, valPlaceholder) + +mixin details-row + - var lblDetailClasses = ['col-sm-4', 'details-label'] + + - var detailMdl = 'getModel(backupItem, detail)[detail.model]'; + - var detailCommon = {'ng-model': detailMdl, 'ng-required': 'detail.required'}; + + - var customValidators = {'ng-attr-ipaddress': '{{detail.ipaddress}}'} + + div(ng-switch='detail.type') + div(ng-switch-when='label') + label {{detail.label}} + div.checkbox(ng-switch-when='check') + label + input(type='checkbox')&attributes(detailCommon) + |{{detail.label}} + +tipLabel('detail.tip') + div(ng-switch-when='text') + label(class=lblDetailClasses ng-class='{required: detail.required}') {{detail.label}}: + .col-sm-8 + +tipField('detail.tip') + .input-tip + input.form-control(type='text' placeholder='{{detail.placeholder}}')&attributes(detailCommon) + div(ng-switch-when='number' ) + label(class=lblDetailClasses ng-class='{required: detail.required}') {{detail.label}}: + .col-sm-8 + +tipField('detail.tip') + .input-tip + input.form-control(name='{{detail.model}}' type='number' placeholder='{{detail.placeholder}}' min='{{detail.min ? detail.min : 0}}' max='{{detail.max ? detail.max : Number.MAX_VALUE}}')&attributes(detailCommon) + +ico-exclamation('{{detail.model}}', 'min', 'Value is less than allowable minimum.') + +ico-exclamation('{{detail.model}}', 'max', 'Value is more than allowable maximum.') + +ico-exclamation('{{detail.model}}', 'number', 'Invalid value. Only numbers allowed.') + div(ng-switch-when='dropdown') + label(class=lblDetailClasses ng-class='{required: detail.required}') {{detail.label}}: + .col-sm-8 + +tipField('detail.tip') + .input-tip + button.form-control(bs-select data-placeholder='{{detail.placeholder}}' bs-options='item.value as item.label for item in {{detail.items}}')&attributes(detailCommon) + div(ng-switch-when='dropdown-multiple') + label(class=lblDetailClasses ng-class='{required: detail.required}') {{detail.label}}: + .col-sm-8 + button.form-control(bs-select data-multiple='1' data-placeholder='{{detail.placeholder}}' bs-options='item.value as item.label for item in {{detail.items}}')&attributes(detailCommon) + +tipField('detail.tip') + div(ng-switch-when='table-simple')&attributes(detailCommon) + div(ng-if='detail.label') + label.table-header {{detail.label}}: + +tipLabel('detail.tableTip') + table.col-sm-12.links-edit-details(st-table='#{detailMdl}') + tbody + tr(ng-repeat='item in #{detailMdl} track by $index') + td + div(ng-show='!tableEditing(detail, $index)') + a.labelFormField(ng-click='curValue = tableStartEdit(backupItem, detail, $index)') {{$index + 1}}) {{item}} + +btn-remove('tableRemove(backupItem, detail, $index)') + +btn-down('detail.reordering && tableSimpleDownVisible(backupItem, detail, $index)', 'tableSimpleDown(backupItem, detail, $index)') + +btn-up('detail.reordering && $index > 0', 'tableSimpleUp(backupItem, detail, $index)') + div(ng-show='tableEditing(detail, $index)') + label.labelField {{$index + 1}}) + +btn-save('tableSimpleSaveVisible(curValue)', 'tableSimpleSave(tableSimpleValid, backupItem, detail, curValue, $index)') + .input-tip.form-group.has-feedback + input.form-control(name='{{detail.model}}.edit' type='text' ng-model='curValue' placeholder='{{detail.placeholder}}')&attributes(customValidators) + +ico-exclamation('{{detail.model}}.edit', 'ipaddress', 'Invalid address, see help for format description.') + button.btn.btn-primary.fieldButton(ng-disabled='!newValue' ng-click='tableSimpleSave(tableSimpleValid, backupItem, detail, newValue, -1)') Add + +tipField('detail.tip') + .input-tip.form-group.has-feedback + input.form-control(name='{{detail.model}}' type='text' ng-model='newValue' ng-focus='tableNewItem(detail)' placeholder='{{detail.placeholder}}')&attributes(customValidators) + +ico-exclamation('{{detail.model}}', 'ipaddress', 'Invalid address, see help for format description.') + +mixin table-db-field-edit(dbName, dbType, javaName, javaType) + div(style='width: 22%; float: right') + button.form-control(ng-model=javaType bs-select data-placeholder='Java type' bs-options='item.value as item.label for item in {{javaTypes}}') + label.fieldSep / + div(style='width: 20%; float: right') + input.form-control(type='text' ng-model=javaName placeholder='Java name') + label.fieldSep / + div(style='width: 22%; float: right') + button.form-control(ng-model=dbType bs-select data-placeholder='JDBC type' bs-options='item.value as item.label for item in {{jdbcTypes}}') + label.fieldSep / + .input-tip + input.form-control(type='text' ng-model=dbName placeholder='DB name') + +mixin table-group-item-edit(fieldName, className, direction) + div(style='width: 15%; float: right') + button.form-control(ng-model=direction bs-select data-placeholder='Sort' bs-options='item.value as item.label for item in {{sortDirections}}') + label.fieldSep / + div(style='width: 38%; float: right') + input.form-control(type='text' ng-model=className placeholder='Class name') + label.fieldSep / + .input-tip + input.form-control(type='text' ng-model=fieldName placeholder='Field name') + +mixin form-row + +form-row-custom(['col-sm-2'], ['col-sm-4']) + +mixin form-row-custom(lblClasses, fieldClasses) + - var fieldMdl = 'getModel(backupItem, field)[field.model]'; + - var fieldCommon = {'ng-model': fieldMdl, 'ng-required': 'field.required || required(field)'}; + - var fieldRequiredClass = '{true: "required"}[field.required || required(field)]' + - var fieldHide = '{{field.hide}}' + + div(ng-switch='field.type') + div.col-sm-6(ng-switch-when='label') + label {{field.label}} + div.checkbox.col-sm-6(ng-switch-when='check' ng-hide=fieldHide) + label + input(type='checkbox')&attributes(fieldCommon) + | {{field.label}} + +tipLabel('field.tip') + div(ng-switch-when='text' ng-hide=fieldHide) + label(class=lblClasses ng-class=fieldRequiredClass) {{field.label}}: + div(class=fieldClasses) + +tipField('field.tip') + .input-tip + input.form-control(type='text' placeholder='{{field.placeholder}}')&attributes(fieldCommon) + div(ng-switch-when='password' ng-hide=fieldHide) + label(class=lblClasses ng-class=fieldRequiredClass) {{field.label}}: + div(class=fieldClasses) + +tipField('field.tip') + .input-tip + input.form-control(type='password' placeholder='{{field.placeholder}}')&attributes(fieldCommon) + div(ng-switch-when='number' ng-hide=fieldHide) + label(class=lblClasses ng-class=fieldRequiredClass) {{field.label}}: + div(class=fieldClasses) + +tipField('field.tip') + .input-tip + input.form-control(name='{{field.model}}' type='number' placeholder='{{field.placeholder}}' min='{{field.min ? field.min : 0}}' max='{{field.max ? field.max : Number.MAX_VALUE}}')&attributes(fieldCommon) + +ico-exclamation('{{field.model}}', 'min', 'Value is less than allowable minimum.') + +ico-exclamation('{{field.model}}', 'max', 'Value is more than allowable maximum.') + +ico-exclamation('{{field.model}}', 'number', 'Invalid value. Only numbers allowed.') + div(ng-switch-when='dropdown' ng-hide=fieldHide) + label(class=lblClasses ng-class=fieldRequiredClass) {{field.label}}: + div(class=fieldClasses) + +tipField('field.tip') + .input-tip + button.form-control(bs-select data-placeholder='{{field.placeholder}}' bs-options='item.value as item.label for item in {{field.items}}')&attributes(fieldCommon) + div(ng-switch-when='dropdown-multiple' ng-hide=fieldHide) + label(class=lblClasses ng-class=fieldRequiredClass) {{field.label}}: + div(class=fieldClasses) + +tipField('field.tip') + .input-tip + button.form-control(bs-select ng-disabled='{{field.items}}.length == 0' data-multiple='1' data-placeholder='{{field.placeholder}}' bs-options='item.value as item.label for item in {{field.items}}')&attributes(fieldCommon) + a.customize(ng-show='field.addLink' ng-href='{{field.addLink.ref}}') {{field.addLink.label}} + div(ng-switch-when='dropdown-details' ng-hide=fieldHide) + - var expanded = 'field.details[' + fieldMdl + '].expanded' + + label(class=lblClasses ng-class=fieldRequiredClass) {{field.label}}: + div(class=fieldClasses) + +tipField('field.tip') + .input-tip + button.form-control(bs-select data-placeholder='{{field.placeholder}}' bs-options='item.value as item.label for item in {{field.items}}')&attributes(fieldCommon) + a.customize(ng-show='#{fieldMdl} && field.details[#{fieldMdl}].fields' ng-click='#{expanded} = !#{expanded}') {{#{expanded} ? "Hide settings" : "Show settings"}} + .col-sm-6.panel-details(ng-show='#{expanded} && #{fieldMdl}') + .details-row(ng-repeat='detail in field.details[#{fieldMdl}].fields') + +details-row + div(ng-switch-when='table-simple' ng-hide=fieldHide)&attributes(fieldCommon) + .col-sm-6 + label.table-header {{field.label}}: + +tipLabel('field.tableTip') + button.btn.btn-primary.fieldButton(ng-click='tableNewItem(field)') Add + table.links-edit.col-sm-12(st-table='#{fieldMdl}') + tbody + tr.col-sm-12(ng-repeat='item in #{fieldMdl} track by $index') + td.col-sm-6 + div(ng-show='!tableEditing(field, $index)') + a.labelFormField(ng-click='curValue = tableStartEdit(backupItem, field, $index)') {{$index + 1}}) {{item | compact}} + +btn-remove('tableRemove(backupItem, field, $index)') + +btn-down('field.reordering && tableSimpleDownVisible(backupItem, field, $index)', 'tableSimpleDown(backupItem, field, $index)') + +btn-up('field.reordering && $index > 0', 'tableSimpleUp(backupItem, field, $index)') + div(ng-show='tableEditing(field, $index)') + label.labelField {{$index + 1}}) + +btn-save('tableSimpleSaveVisible(curValue)', 'tableSimpleSave(tableSimpleValid, backupItem, field, curValue, $index)') + .input-tip + input.form-control(type='text' ng-model='curValue' placeholder='{{field.placeholder}}') + tr.col-sm-12(ng-show='tableNewItemActive(field)') + td.col-sm-6 + +btn-save('tableSimpleSaveVisible(newValue)', 'tableSimpleSave(tableSimpleValid, backupItem, field, newValue, -1)') + .input-tip + input.form-control(type='text' ng-model='newValue' placeholder='{{field.placeholder}}') + div(ng-switch-when='indexedTypes') + +table-pair('Index key-value type pairs', fieldMdl, 'keyClass', 'valueClass', 'Key class full name', 'Value class full name') + div(ng-switch-when='queryFields' ng-hide=fieldHide) + +table-pair('{{field.label}}', fieldMdl, 'name', 'className', 'Field name', 'Field class full name') + div(ng-switch-when='dbFields' ng-hide=fieldHide) + .col-sm-6 + label.table-header {{field.label}}: + +tipLabel('field.tip') + button.btn.btn-primary.fieldButton(ng-click='tableNewItem(field)') Add + table.links-edit.col-sm-12(st-table=fieldMdl) + tbody + tr.col-sm-12(ng-repeat='item in #{fieldMdl}') + td.col-sm-6 + div(ng-show='!tableEditing(field, $index)') + a.labelFormField(ng-click='curField = tableStartEdit(backupItem, field, $index); curDbName = curField.dbName; curDbType = curField.dbType; curJavaName = curField.javaName; curJavaType = curField.javaType') {{$index + 1}}) {{item.dbName}} / {{item.dbType}} / {{item.javaName}} / {{item.javaType}} + +btn-remove('tableRemove(backupItem, field, $index)') + div(ng-if='tableEditing(field, $index)') + label.labelField {{$index + 1}}) + +btn-save('tableDbFieldSaveVisible(curDbName, curDbType, curJavaName, curJavaType)', 'tableDbFieldSave(field, curDbName, curDbType, curJavaName, curJavaType, $index)') + +table-db-field-edit('curDbName', 'curDbType', 'curJavaName', 'curJavaType') + tr(ng-show='tableNewItemActive(field)') + td.col-sm-6 + +btn-save('tableDbFieldSaveVisible(newDbName, newDbType, newJavaName, newJavaType)', 'tableDbFieldSave(field, newDbName, newDbType, newJavaName, newJavaType, -1)') + +table-db-field-edit('newDbName', 'newDbType', 'newJavaName', 'newJavaType') + div(ng-switch-when='queryGroups' ng-hide=fieldHide) + .col-sm-6 + label.table-header {{field.label}}: + +tipLabel('field.tip') + button.btn.btn-primary.fieldButton(ng-click='tableNewItem(field)') Add + table.links-edit.col-sm-12(st-table=fieldMdl) + tbody + tr.col-sm-12(ng-repeat='group in #{fieldMdl}') + td.col-sm-6 + div + .col-sm-12(ng-show='!tableEditing(field, $index)') + a.labelFormField(ng-click='curGroup = tableStartEdit(backupItem, field, $index); curGroupName = curGroup.name; curFields = curGroup.fields') {{$index + 1}}) {{group.name}} + +btn-remove('tableRemove(backupItem, field, $index)') + +btn-add('tableGroupNewItem($index); newDirection = "ASC"') + div(ng-show='tableEditing(field, $index)') + label.labelField {{$index + 1}}) + +btn-save('tableGroupSaveVisible(curGroupName)', 'tableGroupSave(curGroupName, $index)') + .input-tip + input.form-control(type='text' ng-model='curGroupName' placeholder='Index name') + div + table.links-edit.col-sm-12(st-table='group.fields' ng-init='groupIndex = $index') + tr(ng-repeat='groupItem in group.fields') + td + div(ng-show='!tableGroupItemEditing(groupIndex, $index)') + a.labelFormField(ng-click='curGroupItem = tableGroupItemStartEdit(groupIndex, $index); curFieldName = curGroupItem.name; curClassName = curGroupItem.className; curDirection = curGroupItem.direction') {{$index + 1}}) {{groupItem.name}} / {{groupItem.className}} / {{groupItem.direction}} + +btn-remove('tableRemoveGroupItem(group, $index)') + div(ng-show='tableGroupItemEditing(groupIndex, $index)') + label.labelField {{$index + 1}}) + +btn-save('tableGroupItemSaveVisible(curFieldName, curClassName)', 'tableGroupItemSave(curFieldName, curClassName, curDirection, groupIndex, $index)') + +table-group-item-edit('curFieldName', 'curClassName', 'curDirection') + tr.col-sm-12(style='padding-left: 18px' ng-show='tableGroupNewItemActive(groupIndex)') + td + +btn-save('tableGroupItemSaveVisible(newFieldName, newClassName)', 'tableGroupItemSave(newFieldName, newClassName, newDirection, groupIndex, -1)') + +table-group-item-edit('newFieldName', 'newClassName', 'newDirection') + tr.col-sm-12(ng-show='tableNewItemActive(field)') + td.col-sm-6 + +btn-save('tableGroupSaveVisible(newGroupName)', 'tableGroupSave(newGroupName, -1)') + .input-tip + input.form-control(type='text' ng-model='newGroupName' placeholder='Group name') \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8a335724/modules/web-control-center/src/main/js/views/includes/footer.jade ---------------------------------------------------------------------- diff --git a/modules/web-control-center/src/main/js/views/includes/footer.jade b/modules/web-control-center/src/main/js/views/includes/footer.jade new file mode 100644 index 0000000..d8ff5d7 --- /dev/null +++ b/modules/web-control-center/src/main/js/views/includes/footer.jade @@ -0,0 +1,22 @@ +//- + 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. + +.container.container-footer + footer + center + p Apache Ignite Control Center, version 1.0.0 + p © 2015 The Apache Software Foundation. + p Apache, Apache Ignite, the Apache feather and the Apache Ignite logo are trademarks of The Apache Software Foundation. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8a335724/modules/web-control-center/src/main/js/views/includes/header.jade ---------------------------------------------------------------------- diff --git a/modules/web-control-center/src/main/js/views/includes/header.jade b/modules/web-control-center/src/main/js/views/includes/header.jade new file mode 100644 index 0000000..ab2d31e --- /dev/null +++ b/modules/web-control-center/src/main/js/views/includes/header.jade @@ -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. +mixin header-item(active, ref, txt) + li + a(ng-class='{active: isActive("#{active}")}' href='#{ref}') #{txt} + +header.header(id='header') + .viewedUser(ng-show='becomeUsed') Currently assuming " + strong {{user.username}} + | ", + a(href='/admin/become') revert to your identity. + .container + h1.navbar-brand + a(href='/') Apache Ignite Web Configurator + .navbar-collapse.collapse(ng-controller='auth') + ul.nav.navbar-nav(ng-controller='activeLink' ng-show='user') + +header-item('/configuration', '/configuration/clusters', 'Configuration') + //+header-item('/monitoring', '/monitoring', 'Monitoring') + //+header-item('/sql', '/sql', 'SQL') + //+header-item('/deploy', '/deploy', 'Deploy') + ul.nav.navbar-nav.pull-right + li(ng-if='user') + a.dropdown-toggle(data-toggle='dropdown' bs-dropdown='userDropdown' data-placement='bottom-right') {{user.username}} + span.caret + li.nav-login(ng-if='!user') + a(ng-click='login()' href='#') Log In \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8a335724/modules/web-control-center/src/main/js/views/index.jade ---------------------------------------------------------------------- diff --git a/modules/web-control-center/src/main/js/views/index.jade b/modules/web-control-center/src/main/js/views/index.jade new file mode 100644 index 0000000..999c4f8 --- /dev/null +++ b/modules/web-control-center/src/main/js/views/index.jade @@ -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. + +extends templates/layout + +block container + .row + .docs-content + div + p + | Apache Ignite<sup>tm</sup> In-Memory Data Fabric is a high-performance, + | integrated and distributed in-memory platform for computing and transacting on large-scale data + | sets in real-time, orders of magnitude faster than possible with traditional disk-based or flash technologies. + .block-image.block-display-image + img(ng-src='https://www.filepicker.io/api/file/lydEeGB6Rs9hwbpcQxiw' alt='Apache Ignite stack') + .text-center(ng-controller='auth') + button.btn.btn-primary(ng-click='login()' href='#') Configure Now http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8a335724/modules/web-control-center/src/main/js/views/login.jade ---------------------------------------------------------------------- diff --git a/modules/web-control-center/src/main/js/views/login.jade b/modules/web-control-center/src/main/js/views/login.jade new file mode 100644 index 0000000..5bb39dd --- /dev/null +++ b/modules/web-control-center/src/main/js/views/login.jade @@ -0,0 +1,55 @@ +//- + 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 lbl(txt) + label.col-sm-3.required #{txt} + +.modal.center(role='dialog') + .modal-dialog + .modal-content + .modal-header.header + div(id='errors-container') + button.close(type='button', ng-click='$hide()', aria-hidden='true') × + h1.navbar-brand + a(href='/') Apache Ignite Web Configurator + h4.modal-title(style='padding-right: 55px') Authentication + p(style='padding-right: 55px') Log in or register in order to collaborate + form.form-horizontal(name='loginForm') + .modal-body.row + .col-sm-9.login.col-sm-offset-1 + .details-row(ng-show='action == "register"') + +lbl('Full Name:') + .col-sm-9 + input.form-control(type='text', ng-model='user_info.username', placeholder='John Smith', focus-me='action=="register"', ng-required='action=="register"') + .details-row + +lbl('Email:') + .col-sm-9 + input.form-control(type='email', ng-model='user_info.email', placeholder='y...@domain.com', focus-me='action=="login"', required) + .details-row + +lbl('Password:') + .col-sm-9 + input.form-control(type='password', ng-model='user_info.password', placeholder='Password', required, ng-keyup='action == "login" && $event.keyCode == 13 ? auth(action, user_info) : null') + .details-row(ng-show='action == "register"') + +lbl('Confirm:') + .col-sm-9.input-tip.has-feedback + input.form-control(type='password', ng-model='user_info.confirm', match="user_info.password" placeholder='Confirm password', required, ng-keyup='$event.keyCode == 13 ? auth(action, user_info) : null') + + .modal-footer + a.show-signup.ng-hide(ng-show='action != "login"', ng-click='action = "login";') log in + a.show-signup(ng-show="action != 'register'", ng-click='action = "register";') sign up + | or + button.btn.btn-primary(ng-show='action == "login"' ng-click='auth(action, user_info)') Log In + button.btn.btn-primary(ng-show='action == "register"' ng-disabled='loginForm.$invalid || user_info.password != user_info.confirm' ng-click='auth(action, user_info)') Sign Up http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8a335724/modules/web-control-center/src/main/js/views/settings/admin.jade ---------------------------------------------------------------------- diff --git a/modules/web-control-center/src/main/js/views/settings/admin.jade b/modules/web-control-center/src/main/js/views/settings/admin.jade new file mode 100644 index 0000000..4d50631 --- /dev/null +++ b/modules/web-control-center/src/main/js/views/settings/admin.jade @@ -0,0 +1,58 @@ +//- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +extends ../templates/layout + +append scripts + script(src='/admin-controller.js') + +block container + .row(ng-controller='adminController') + .docs-content + .docs-header + h1 List of registered users + hr + .docs-body + table.table.table-striped.admin(st-table='displayedUsers' st-safe-src='users') + thead + tr + th.header(colspan='5') + .col-sm-2.pull-right + input.form-control(type='text' st-search='' placeholder='Filter users...') + tr + th(st-sort='username') User name + th(st-sort='email') Email + th.col-sm-2(st-sort='lastLogin') Last login + th(width='1%' st-sort='admin') Admin + th(width='1%') Actions + tbody + tr(ng-repeat='row in displayedUsers') + td {{row.username}} + td + a(ng-href='mailto:{{row.email}}') {{row.email}} + td + span {{row.lastLogin | date:'medium'}} + td(style='text-align: center;') + input(type='checkbox' ng-disabled='row.adminChanging || row._id == user._id' + ng-model='row.admin' ng-change='toggleAdmin(row)') + td(style='text-align: center;') + a(ng-click='removeUser(row)' ng-show='row._id != user._id' bs-tooltip data-title='Remove user') + i.fa.fa-remove + a(style='margin-left: 5px' ng-href='admin/become?viewedUserId={{row._id}}' ng-show='row._id != user._id' bs-tooltip data-title='Become this user') + i.fa.fa-eye + tfoot + tr + td(colspan='5' class="text-right") + div(st-pagination st-items-by-page='15' st-displayed-pages='5') + http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8a335724/modules/web-control-center/src/main/js/views/settings/profile.jade ---------------------------------------------------------------------- diff --git a/modules/web-control-center/src/main/js/views/settings/profile.jade b/modules/web-control-center/src/main/js/views/settings/profile.jade new file mode 100644 index 0000000..dbc6dea --- /dev/null +++ b/modules/web-control-center/src/main/js/views/settings/profile.jade @@ -0,0 +1,58 @@ +//- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +extends ../templates/layout + +mixin lbl(txt) + label.col-sm-2.required.labelFormField #{txt} + +append scripts + script(src='/profile-controller.js') + +block container + .row(ng-controller='profileController') + .docs-content + .docs-header + h1 User profile + hr + .docs-body + form.form-horizontal(name='profileForm' novalidate) + .col-sm-10(style='padding: 0') + .details-row + +lbl('User name:') + .col-sm-4 + input.form-control(type='text' ng-model='profileUser.username' placeholder='Input name' required) + .details-row + +lbl('Email:') + .col-sm-4 + input.form-control(type='email' ng-model='profileUser.email' placeholder='y...@domain.com' required) + .details-row + .checkbox + label + input(type="checkbox" ng-model='profileUser.changePassword') + | Change password + div(ng-show='profileUser.changePassword') + .details-row + +lbl('New password:') + .col-sm-4 + input.form-control(type='password', ng-model='profileUser.newPassword' placeholder='New password' ng-required='profileUser.changePassword') + .details-row + +lbl('Confirm:') + .col-sm-4 + input.form-control(type='password', ng-model='profileUser.confirmPassword' match='profileUser.newPassword' placeholder='Confirm new password' ng-required='profileUser.changePassword') + .col-sm-12.details-row + button.btn.btn-primary(ng-disabled='profileForm.$invalid' ng-click='saveUser()') Save + http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8a335724/modules/web-control-center/src/main/js/views/templates/confirm.jade ---------------------------------------------------------------------- diff --git a/modules/web-control-center/src/main/js/views/templates/confirm.jade b/modules/web-control-center/src/main/js/views/templates/confirm.jade new file mode 100644 index 0000000..bdaf9bf --- /dev/null +++ b/modules/web-control-center/src/main/js/views/templates/confirm.jade @@ -0,0 +1,27 @@ +//- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +.modal(tabindex='-1' role='dialog') + .modal-dialog + .modal-content + .modal-header + button.close(type="button" ng-click="$hide()") × + h4.modal-title Confirmation + .modal-body(ng-show='content') + p(ng-bind-html='content' style='text-align: center;') + .modal-footer + button.btn.btn-default(type="button" ng-click="$hide()") Cancel + button.btn.btn-primary(type="button" ng-click="ok()") Confirm \ No newline at end of file