Merge branch 'ignite-843' of https://git-wip-us.apache.org/repos/asf/incubator-ignite into ignite-1121
Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/6b621759 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/6b621759 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/6b621759 Branch: refs/heads/ignite-843 Commit: 6b621759a2fb23f0b8ab121db2e69ff74868ea05 Parents: 89220b1 9652287 Author: Andrey <anovi...@gridgain.com> Authored: Wed Jul 29 13:44:13 2015 +0700 Committer: Andrey <anovi...@gridgain.com> Committed: Wed Jul 29 13:44:13 2015 +0700 ---------------------------------------------------------------------- .../control-center-web/licenses/apache-2.0.txt | 202 +++ .../control-center-web/src/main/js/.gitignore | 4 + .../control-center-web/src/main/js/DEVNOTES.txt | 21 + modules/control-center-web/src/main/js/app.js | 158 +++ modules/control-center-web/src/main/js/bin/www | 110 ++ .../src/main/js/config/default.json | 17 + .../src/main/js/controllers/admin-controller.js | 68 + .../js/controllers/cache-viewer-controller.js | 77 ++ .../main/js/controllers/caches-controller.js | 349 +++++ .../main/js/controllers/clusters-controller.js | 308 +++++ .../src/main/js/controllers/common-module.js | 484 +++++++ .../main/js/controllers/metadata-controller.js | 709 ++++++++++ .../src/main/js/controllers/models/caches.json | 943 +++++++++++++ .../main/js/controllers/models/clusters.json | 909 +++++++++++++ .../main/js/controllers/models/metadata.json | 252 ++++ .../src/main/js/controllers/models/sql.json | 5 + .../src/main/js/controllers/models/summary.json | 163 +++ .../main/js/controllers/profile-controller.js | 51 + .../src/main/js/controllers/sql-controller.js | 129 ++ .../main/js/controllers/summary-controller.js | 170 +++ modules/control-center-web/src/main/js/db.js | 370 +++++ .../src/main/js/helpers/configuration-loader.js | 22 + .../src/main/js/helpers/data-structures.js | 84 ++ .../control-center-web/src/main/js/package.json | 50 + .../src/main/js/public/favicon.ico | Bin 0 -> 1150 bytes .../src/main/js/public/images/docker.png | Bin 0 -> 994 bytes .../src/main/js/public/images/java.png | Bin 0 -> 170 bytes .../src/main/js/public/images/logo.png | Bin 0 -> 8148 bytes .../src/main/js/public/images/xml.png | Bin 0 -> 232 bytes .../src/main/js/public/stylesheets/style.scss | 1270 ++++++++++++++++++ .../src/main/js/routes/admin.js | 79 ++ .../src/main/js/routes/caches.js | 105 ++ .../src/main/js/routes/clusters.js | 104 ++ .../src/main/js/routes/generator/common.js | 312 +++++ .../src/main/js/routes/generator/docker.js | 58 + .../src/main/js/routes/generator/java.js | 788 +++++++++++ .../src/main/js/routes/generator/xml.js | 736 ++++++++++ .../src/main/js/routes/metadata.js | 95 ++ .../src/main/js/routes/profile.js | 97 ++ .../src/main/js/routes/public.js | 123 ++ .../src/main/js/routes/sql.js | 24 + .../src/main/js/routes/summary.js | 108 ++ .../src/main/js/views/configuration/caches.jade | 74 + .../main/js/views/configuration/clusters.jade | 77 ++ .../main/js/views/configuration/metadata.jade | 121 ++ .../main/js/views/configuration/sidebar.jade | 39 + .../main/js/views/configuration/summary.jade | 113 ++ .../src/main/js/views/error.jade | 22 + .../src/main/js/views/includes/controls.jade | 350 +++++ .../src/main/js/views/includes/footer.jade | 22 + .../src/main/js/views/includes/header.jade | 39 + .../src/main/js/views/index.jade | 30 + .../src/main/js/views/login.jade | 55 + .../src/main/js/views/settings/admin.jade | 58 + .../src/main/js/views/settings/profile.jade | 58 + .../src/main/js/views/sql/sql.jade | 84 ++ .../src/main/js/views/templates/confirm.jade | 27 + .../src/main/js/views/templates/copy.jade | 31 + .../src/main/js/views/templates/layout.jade | 61 + .../src/main/js/views/templates/select.jade | 26 + .../src/main/js/views/templates/tab.jade | 26 + .../web-control-center/licenses/apache-2.0.txt | 202 --- .../web-control-center/src/main/js/.gitignore | 4 - .../web-control-center/src/main/js/DEVNOTES.txt | 21 - modules/web-control-center/src/main/js/app.js | 158 --- modules/web-control-center/src/main/js/bin/www | 110 -- .../src/main/js/config/default.json | 17 - .../src/main/js/controllers/admin-controller.js | 68 - .../js/controllers/cache-viewer-controller.js | 77 -- .../main/js/controllers/caches-controller.js | 349 ----- .../main/js/controllers/clusters-controller.js | 308 ----- .../src/main/js/controllers/common-module.js | 484 ------- .../main/js/controllers/metadata-controller.js | 709 ---------- .../src/main/js/controllers/models/caches.json | 943 ------------- .../main/js/controllers/models/clusters.json | 909 ------------- .../main/js/controllers/models/metadata.json | 252 ---- .../src/main/js/controllers/models/sql.json | 5 - .../src/main/js/controllers/models/summary.json | 163 --- .../main/js/controllers/profile-controller.js | 51 - .../src/main/js/controllers/sql-controller.js | 129 -- .../main/js/controllers/summary-controller.js | 170 --- modules/web-control-center/src/main/js/db.js | 370 ----- .../src/main/js/helpers/configuration-loader.js | 22 - .../src/main/js/helpers/data-structures.js | 84 -- .../web-control-center/src/main/js/package.json | 50 - .../src/main/js/public/favicon.ico | Bin 1150 -> 0 bytes .../src/main/js/public/images/docker.png | Bin 994 -> 0 bytes .../src/main/js/public/images/java.png | Bin 170 -> 0 bytes .../src/main/js/public/images/logo.png | Bin 8148 -> 0 bytes .../src/main/js/public/images/xml.png | Bin 232 -> 0 bytes .../src/main/js/public/stylesheets/style.scss | 1270 ------------------ .../src/main/js/routes/admin.js | 79 -- .../src/main/js/routes/caches.js | 105 -- .../src/main/js/routes/clusters.js | 104 -- .../src/main/js/routes/generator/common.js | 324 ----- .../src/main/js/routes/generator/docker.js | 58 - .../src/main/js/routes/generator/java.js | 626 --------- .../src/main/js/routes/generator/xml.js | 738 ---------- .../src/main/js/routes/metadata.js | 95 -- .../src/main/js/routes/profile.js | 97 -- .../src/main/js/routes/public.js | 123 -- .../src/main/js/routes/sql.js | 24 - .../src/main/js/routes/summary.js | 108 -- .../src/main/js/views/configuration/caches.jade | 74 - .../main/js/views/configuration/clusters.jade | 77 -- .../main/js/views/configuration/metadata.jade | 121 -- .../main/js/views/configuration/sidebar.jade | 39 - .../main/js/views/configuration/summary.jade | 113 -- .../src/main/js/views/error.jade | 22 - .../src/main/js/views/includes/controls.jade | 350 ----- .../src/main/js/views/includes/footer.jade | 22 - .../src/main/js/views/includes/header.jade | 39 - .../src/main/js/views/index.jade | 30 - .../src/main/js/views/login.jade | 55 - .../src/main/js/views/settings/admin.jade | 58 - .../src/main/js/views/settings/profile.jade | 58 - .../src/main/js/views/sql/sql.jade | 84 -- .../src/main/js/views/templates/confirm.jade | 27 - .../src/main/js/views/templates/copy.jade | 31 - .../src/main/js/views/templates/layout.jade | 61 - .../src/main/js/views/templates/select.jade | 26 - .../src/main/js/views/templates/tab.jade | 26 - 122 files changed, 10867 insertions(+), 10719 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/6b621759/modules/control-center-web/src/main/js/app.js ---------------------------------------------------------------------- diff --cc modules/control-center-web/src/main/js/app.js index 0000000,a67afc8..930c798 mode 000000,100644..100644 --- a/modules/control-center-web/src/main/js/app.js +++ b/modules/control-center-web/src/main/js/app.js @@@ -1,0 -1,156 +1,158 @@@ + /* + * 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 flash = require('connect-flash'); + var express = require('express'); + var path = require('path'); + var favicon = require('serve-favicon'); + var logger = require('morgan'); + var cookieParser = require('cookie-parser'); + var bodyParser = require('body-parser'); + var session = require('express-session'); + var mongoStore = require('connect-mongo')(session); + + var publicRoutes = require('./routes/public'); + var clustersRouter = require('./routes/clusters'); + var cachesRouter = require('./routes/caches'); + var metadataRouter = require('./routes/metadata'); + var summary = require('./routes/summary'); + var adminRouter = require('./routes/admin'); + var profileRouter = require('./routes/profile'); + var sqlRouter = require('./routes/sql'); ++var agentRouter = require('./routes/agent'); + + var passport = require('passport'); + + var db = require('./db'); + + var app = express(); + + // Views engine setup. + app.set('views', path.join(__dirname, 'views')); + app.set('view engine', 'jade'); + + // Site favicon. + app.use(favicon(__dirname + '/public/favicon.ico')); + + app.use(logger('dev')); + + app.use(bodyParser.json()); + app.use(bodyParser.urlencoded({extended: false})); + + app.use(require('node-sass-middleware')({ + /* Options */ + src: path.join(__dirname, 'public'), + dest: path.join(__dirname, 'public'), + debug: true, + outputStyle: 'nested' + })); + + app.use(express.static(path.join(__dirname, 'public'))); + app.use(express.static(path.join(__dirname, 'controllers'))); + app.use(express.static(path.join(__dirname, 'helpers'))); + + app.use(cookieParser('keyboard cat')); + + app.use(session({ + secret: 'keyboard cat', + resave: false, + saveUninitialized: true, + store: new mongoStore({ + mongooseConnection: db.mongoose.connection + }) + })); + + app.use(flash()); + + app.use(passport.initialize()); + app.use(passport.session()); + + passport.serializeUser(db.Account.serializeUser()); + passport.deserializeUser(db.Account.deserializeUser()); + + passport.use(db.Account.createStrategy()); + + var mustAuthenticated = function (req, res, next) { + req.isAuthenticated() ? next() : res.redirect('/'); + }; + + var adminOnly = function(req, res, next) { + req.isAuthenticated() && req.user.admin ? next() : res.sendStatus(403); + }; + + app.all('/configuration/*', mustAuthenticated); + + app.all('*', function(req, res, next) { + var becomeUsed = req.session.viewedUser && req.user.admin; + + res.locals.user = becomeUsed ? req.session.viewedUser : req.user; + res.locals.becomeUsed = becomeUsed; + + req.currentUserId = function() { + if (!req.user) + return null; + + if (req.session.viewedUser && req.user.admin) + return req.session.viewedUser._id; + + return req.user._id; + }; + + next(); + }); + + app.use('/', publicRoutes); + app.use('/admin', mustAuthenticated, adminOnly, adminRouter); + app.use('/profile', mustAuthenticated, profileRouter); + + app.use('/configuration/clusters', clustersRouter); + app.use('/configuration/caches', cachesRouter); + app.use('/configuration/metadata', metadataRouter); + app.use('/configuration/summary', summary); + app.use('/sql', sqlRouter); ++app.use('/agent', agentRouter); + + // Catch 404 and forward to error handler. + app.use(function (req, res, next) { + var err = new Error('Not Found: ' + req.originalUrl); + err.status = 404; + next(err); + }); + + // Error handlers. + + // Development error handler: will print stacktrace. + if (app.get('env') === 'development') { + app.use(function (err, req, res) { + res.status(err.status || 500); + res.render('error', { + message: err.message, + error: err + }); + }); + } + + // Production error handler: no stacktraces leaked to user. + app.use(function (err, req, res) { + res.status(err.status || 500); + res.render('error', { + message: err.message, + error: {} + }); + }); + + module.exports = app; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/6b621759/modules/control-center-web/src/main/js/bin/www ---------------------------------------------------------------------- diff --cc modules/control-center-web/src/main/js/bin/www index 0000000,4cf0583..cbc637a mode 000000,100644..100644 --- a/modules/control-center-web/src/main/js/bin/www +++ b/modules/control-center-web/src/main/js/bin/www @@@ -1,0 -1,85 +1,110 @@@ + #!/usr/bin/env node + + /** + * Module dependencies. + */ -var app = require('../app'); ++var http = require('http'); ++var https = require('https'); + var config = require('../helpers/configuration-loader.js'); ++var app = require('../app'); ++var agentManager = require('../agents/agent-manager'); ++ ++var fs = require('fs'); ++ + var debug = require('debug')('ignite-web-control-center:server'); -var http = require('http'); + + /** + * Get port from environment and store in Express. + */ + var port = normalizePort(process.env.PORT || config.get('express:port')); + app.set('port', port); + + /** + * Create HTTP server. + */ + var server = http.createServer(app); + + /** + * Listen on provided port, on all network interfaces. + */ + server.listen(port); + server.on('error', onError); + server.on('listening', onListening); + + /** ++ * Start agent server. ++ */ ++var agentServer; ++ ++if (config.get('monitor:server:ssl')) { ++ agentServer = https.createServer({ ++ key: fs.readFileSync(config.get('monitor:server:key')), ++ cert: fs.readFileSync(config.get('monitor:server:cert')), ++ passphrase: config.get('monitor:server:keyPassphrase') ++ }); ++} ++else { ++ agentServer = http.createServer(); ++} ++ ++agentServer.listen(config.get('monitor:server:port')); ++ ++agentManager.createManager(agentServer); ++ ++/** + * Normalize a port into a number, string, or false. + */ + function normalizePort(val) { + var port = parseInt(val, 10); + + if (isNaN(port)) { + // named pipe + return val; + } + + if (port >= 0) { + // port number + return port; + } + + return false; + } + + /** + * Event listener for HTTP server "error" event. + */ + function onError(error) { + if (error.syscall !== 'listen') { + throw error; + } + + var bind = typeof port === 'string' + ? 'Pipe ' + port + : 'Port ' + port; + + // handle specific listen errors with friendly messages + switch (error.code) { + case 'EACCES': + console.error(bind + ' requires elevated privileges'); + process.exit(1); + break; + case 'EADDRINUSE': + console.error(bind + ' is already in use'); + process.exit(1); + break; + default: + throw error; + } + } + + /** + * Event listener for HTTP server "listening" event. + */ + function onListening() { + var addr = server.address(); + var bind = typeof addr === 'string' + ? 'pipe ' + addr + : 'port ' + addr.port; + + debug('Listening on ' + bind); + } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/6b621759/modules/control-center-web/src/main/js/config/default.json ---------------------------------------------------------------------- diff --cc modules/control-center-web/src/main/js/config/default.json index 0000000,72dbd4e..f7f7a02 mode 000000,100644..100644 --- a/modules/control-center-web/src/main/js/config/default.json +++ b/modules/control-center-web/src/main/js/config/default.json @@@ -1,0 -1,8 +1,17 @@@ + { + "express": { + "port": 3000 + }, + "mongoDB": { + "url": "mongodb://localhost/web-control-center" ++ }, ++ "monitor": { ++ "server": { ++ "port": 3001, ++ "ssl": true, ++ "key": "keys/test.key", ++ "cert": "keys/test.crt", ++ "keyPassphrase": "password" ++ } + } -} ++} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/6b621759/modules/control-center-web/src/main/js/controllers/sql-controller.js ---------------------------------------------------------------------- diff --cc modules/control-center-web/src/main/js/controllers/sql-controller.js index 0000000,12772c6..b4b4335 mode 000000,100644..100644 --- a/modules/control-center-web/src/main/js/controllers/sql-controller.js +++ b/modules/control-center-web/src/main/js/controllers/sql-controller.js @@@ -1,0 -1,84 +1,129 @@@ + /* + * 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 demoResults = [ - { - id: 256, - firstName: 'Ivan', - lastName: 'Ivanov' - }, - { - id: 384, - firstName: 'Sergey', - lastName: 'Petrov' - }, - { - id: 923, - firstName: 'Andrey', - lastName: 'Sidorov' - } -]; - -var demoCaches = [{_id: '1', name: 'Users', mode: 'LOCAL'}, {_id: '2', name: 'Organizations', mode: 'REPLICATED'}, {_id: '3', name: 'Cities', mode: 'PARTITIONED'}]; - - - + controlCenterModule.controller('sqlController', ['$scope', '$http', '$common', function ($scope, $http, $common) { + $scope.joinTip = $common.joinTip; + + $scope.pageSizes = [50, 100, 200, 400, 800, 1000]; + - $scope.tabs = [ - { - query: "SELECT u.id, u.firstName, u.lastName FROM User u WHERE u.name LIKE 'aaaa'", - cols: Object.keys(demoResults[0]), - page: 1, - hasMore: true, - total: 0, - rows: demoResults - }, - {query: "SELECT * FROM Organization"} ++ $scope.modes = [ ++ {value: 'PARTITIONED', label: 'PARTITIONED'}, ++ {value: 'REPLICATED', label: 'REPLICATED'}, ++ {value: 'LOCAL', label: 'LOCAL'} + ]; + ++ $scope.tabs = []; ++ + $scope.addTab = function() { - console.log('addTab'); ++ var tab = {query: "", pageSize: $scope.pageSizes[0]}; ++ ++ if ($scope.caches.length > 0) ++ tab.selectedItem = $scope.caches[0]; + - $scope.tabs.push({query: "SELECT "}); ++ $scope.tabs.push(tab); + }; + + $scope.removeTab = function(idx) { - console.log('removeTab'); - + $scope.tabs.splice(idx, 1); + }; + - $scope.modes = [ - {value: 'PARTITIONED', label: 'PARTITIONED'}, - {value: 'REPLICATED', label: 'REPLICATED'}, - {value: 'LOCAL', label: 'LOCAL'} - ]; - + $http.get('/models/sql.json') + .success(function (data) { + $scope.screenTip = data.screenTip; + }) + .error(function (errMsg) { + $common.showError(errMsg); + }); + - $scope.caches = demoCaches; ++ $scope.caches = []; ++ ++ $http.post('/agent/topology') ++ .success(function (clusters) { ++ var node = clusters[0]; ++ ++ $scope.caches = node.caches; ++ ++ if ($scope.tabs.length == 0) ++ $scope.addTab(); ++ }) ++ .error(function (errMsg) { ++ $common.showError(errMsg); ++ }); ++ ++ $scope.execute = function(tab) { ++ $http.post('/agent/query', {query: tab.query, pageSize: tab.pageSize, cacheName: tab.selectedItem.name}) ++ .success(function (res) { ++ tab.meta = []; ++ ++ if (res.meta) ++ tab.meta = res.meta; ++ ++ tab.page = 1; ++ ++ tab.total = 0; ++ ++ tab.queryId = res.queryId; ++ ++ tab.rows = res.rows; ++ }) ++ .error(function (errMsg) { ++ $common.showError(errMsg); ++ }); ++ }; ++ ++ $scope.explain = function(tab) { ++ $http.post('/agent/query', {query: 'EXPLAIN ' + tab.query, pageSize: tab.pageSize, cacheName: tab.selectedItem.name}) ++ .success(function (res) { ++ tab.meta = []; ++ ++ if (res.meta) ++ tab.meta = res.meta; ++ ++ tab.page = 1; ++ ++ tab.total = 0; ++ ++ tab.queryId = res.queryId; ++ ++ tab.rows = res.rows; ++ }) ++ .error(function (errMsg) { ++ $common.showError(errMsg); ++ }); ++ }; ++ ++ $scope.nextPage = function(tab) { ++ $http.post('/agent/next_page', {queryId: tab.queryId, pageSize: tab.pageSize, cacheName: tab.selectedItem.name}) ++ .success(function (res) { ++ tab.page++; ++ ++ tab.total += tab.rows.length; ++ ++ tab.rows = res.rows; ++ ++ if (res.last) ++ delete tab.queryId; ++ }) ++ .error(function (errMsg) { ++ $common.showError(errMsg); ++ }); ++ }; ++ ++ $scope.getter = function (value) { ++ return value; ++ } + }]); http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/6b621759/modules/control-center-web/src/main/js/package.json ---------------------------------------------------------------------- diff --cc modules/control-center-web/src/main/js/package.json index 0000000,fd82196..f7926cf mode 000000,100644..100644 --- a/modules/control-center-web/src/main/js/package.json +++ b/modules/control-center-web/src/main/js/package.json @@@ -1,0 -1,49 +1,50 @@@ + { + "name": "ignite-web-control-center", + "version": "1.0.0", + "description": "Web application for configuration, monitoring Ignite Cluster", + "private": true, + "scripts": { + "start": "node ./bin/www" + }, + "author": "", + "contributors": [ + { + "name": "", + "email": "" + } + ], + "license": "Apache-2.0", + "keywords": "grid", + "homepage": "https://ignite.incubator.apache.org/", + "engines": { + "node": ">=0.12.4" + }, + "dependencies": { + "angular-ui-ace": "^0.2.3", + "archiver": "^0.14.4", + "body-parser": "~1.12.0", + "connect-flash": "^0.1.1", + "connect-mongo": "^0.8.1", + "cookie-parser": "~1.3.4", + "debug": "~2.1.1", + "express": "~4.12.2", + "express-session": "^1.11.1", + "jade": "~1.9.2", + "lodash": "3.10.0", + "mongoose": "^4.0.2", + "mongoose-deep-populate": "1.1.0", + "nconf": "^0.7.1", + "node-sass-middleware": "^0.9.0", + "passport": "^0.2.1", + "passport-local": "^1.0.0", + "passport-local-mongoose": "^1.0.0", - "serve-favicon": "~2.2.0" ++ "serve-favicon": "~2.2.0", ++ "ws": "~0.7.2" + }, + "devDependencies": { + "morgan": "~1.5.1", + "supertest": "^1.0.1", + "mocha": "~2.0.1", + "should": "~3.1.3" + } + } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/6b621759/modules/control-center-web/src/main/js/views/sql/sql.jade ---------------------------------------------------------------------- diff --cc modules/control-center-web/src/main/js/views/sql/sql.jade index 0000000,97d34de..2ce6958 mode 000000,100644..100644 --- a/modules/control-center-web/src/main/js/views/sql/sql.jade +++ b/modules/control-center-web/src/main/js/views/sql/sql.jade @@@ -1,0 -1,85 +1,84 @@@ + //- + 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='/sql-controller.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-sql.js') + script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ext-language_tools.js') + + block container + .row + .col-sm-12 + .docs-content + .docs-header + h1 Connect to Ignite and Execute SQL Queries + hr + .docs-body(ng-controller='sqlController') + - var tab = 'tabs[tabs.activeIdx]' + + .block-callout-parent.block-callout-border.margin-bottom-dflt + .block-callout + p(ng-bind-html='joinTip(screenTip)') + .tabs-below(bs-tabs bs-active-pane='tabs.activeIdx' data-template='/tab') + div(ng-repeat='tab in tabs' title='Query' bs-pane) + .row + .col-sm-9(style='border-right: 1px solid #eee') + div(style='height: 200px' ui-ace='{ theme: "chrome", mode: "sql",' + + 'require: ["ace/ext/language_tools"],' + + 'rendererOptions: {showPrintMargin: false, highlightGutterLine: false, fontSize: 14},' + + 'advanced: {enableSnippets: false, enableBasicAutocompletion: true, enableLiveAutocompletion: true}}' ng-model='#{tab}.query') + .col-sm-3 + div(ng-hide='caches.length == 0' style='margin-top: 0.65em') + lable.labelHeader Caches: + table.links(st-table='caches') + tbody - tr(ng-repeat='row in caches track by row._id') - td.col-sm-6(ng-class='{active: row._id == #{tab}.selectedItem._id}') - a(ng-click='#{tab}.selectedItem = row') {{$index + 1}}) {{row.name}}, {{row.mode | displayValue:modes:'Cache mode not set'}} ++ tr(ng-repeat='row in caches track by row.name') ++ td.col-sm-6(ng-class='{active: row.name == #{tab}.selectedItem.name}') ++ a(ng-click='#{tab}.selectedItem = row') {{$index + 1}}) {{::row.name}}, {{::row.mode}} + hr(style='margin: 0') + .settings-row + label Page Size: - button.btn.btn-default.base-control(ng-init='pageSize = pageSizes[0]' ng-model='pageSize' bs-options='item for item in pageSizes' bs-select) ++ button.btn.btn-default.base-control(ng-model='#{tab}.pageSize' bs-options='item for item in pageSizes' bs-select) + .settings-row - button.btn.btn-primary(ng-click='') Explain - button.btn.btn-primary(ng-click='') Execute - button.btn.btn-primary(ng-click='' disabled) Scan ++ button.btn.btn-primary(ng-click='explain(#{tab})') Explain ++ button.btn.btn-primary(ng-click='execute(#{tab})') Execute ++ button.btn.btn-primary(ng-click='scan(#{tab})' disabled) Scan + + div(ng-show='#{tab}.rows.length > 0' style='margin-top: 0.65em') + hr + div - table.table.table-striped.col-sm-12.sql-results(st-table='rows' st-safe-src='#{tab}.rows') ++ table.table.table-striped.col-sm-12.sql-results(st-table='displayedCollection' st-safe-src='#{tab}.rows') + thead + tr(style='border-size: 0') - td(colspan='{{#{tab}.cols.length}}') ++ td(colspan='{{#{tab}.meta.length}}') + .col-sm-8 + lable Page #: + b {{#{tab}.page}} + | Results: + b {{#{tab}.rows.length + #{tab}.total}} + .col-sm-4 - button.btn.btn-primary.fieldButton(ng-click='') Next page - .input-tip - input.form-control(type='text' st-search='' placeholder='Filter...') - ++ button.btn.btn-primary.fieldButton(ng-click='nextPage(#{tab})' ng-disabled='!#{tab}.queryId') Next page ++ //.input-tip ++ // input.form-control(st-search placeholder='Filter...' type='search') + tr - th(ng-repeat='column in #{tab}.cols' st-sort='{{column}}') {{column}} ++ th(ng-repeat='col in #{tab}.meta track by $index' st-sort='getter' data-ng-bind='::col.fieldName' bs-tooltip='col.schemaName + "." + col.typeName + "." + col.fieldName') + tbody + //tr + // td(colspan='{{#{tab}.cols.length}}') + // .loading-indicator - tr(ng-repeat='row in rows') - td(ng-repeat='column in #{tab}.cols') {{row[column]}} ++ tr(ng-repeat='row in displayedCollection track by $index') ++ td(ng-repeat='val in row track by $index') {{ val }} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/6b621759/modules/control-center-web/src/main/js/views/templates/layout.jade ---------------------------------------------------------------------- diff --cc modules/control-center-web/src/main/js/views/templates/layout.jade index 0000000,71d8936..8e92edb mode 000000,100644..100644 --- a/modules/control-center-web/src/main/js/views/templates/layout.jade +++ b/modules/control-center-web/src/main/js/views/templates/layout.jade @@@ -1,0 -1,61 +1,61 @@@ + //- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + doctype html + html(ng-app='ignite-web-control-center' ng-init='user = #{JSON.stringify(user)}; becomeUsed = #{becomeUsed}') + head + title= title + + block css + // Bootstrap + link(rel='stylesheet', href='//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.css') + + // Font Awesome Icons + link(rel='stylesheet', href='//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.css') + + // Font + link(rel='stylesheet', href='//fonts.googleapis.com/css?family=Roboto+Slab:700:serif|Roboto+Slab:400:serif') + + link(rel='stylesheet', href='/stylesheets/style.css') + + block scripts + script(src='//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js') + + script(src='//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js') + + script(src='//ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.js') + script(src='//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular-sanitize.js') + script(src='//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.3.0/angular-strap.js') + script(src='//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.3.0/angular-strap.tpl.min.js') + - script(src='//cdnjs.cloudflare.com/ajax/libs/angular-smart-table/2.0.3/smart-table.js') ++ script(src='//cdnjs.cloudflare.com/ajax/libs/angular-smart-table/2.1.1/smart-table.js') + + script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ace.js') + script(src='//angular-ui.github.io/ui-ace/dist/ui-ace.min.js') + + script(src='/common-module.js') + script(src='/data-structures.js') + + body.theme-line.body-overlap.greedy + .wrapper + include ../includes/header + + block main-container + .container.body-container + .main-content + block container + + include ../includes/footer