http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-console/src/main/js/serve/routes/public.js ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/serve/routes/public.js b/modules/web-console/src/main/js/serve/routes/public.js new file mode 100644 index 0000000..0009e6a --- /dev/null +++ b/modules/web-console/src/main/js/serve/routes/public.js @@ -0,0 +1,228 @@ +/* + * 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. + */ + +'use strict'; + +// Fire me up! + +module.exports = { + implements: 'public-routes', + inject: ['require(express)', 'require(passport)', 'require(nodemailer)', 'settings', 'mail', 'mongo'] +}; + +module.exports.factory = function(express, passport, nodemailer, settings, mail, mongo) { + return new Promise((factoryResolve) => { + const router = new express.Router(); + + const _randomString = () => { + const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + const possibleLen = possible.length; + + let res = ''; + + for (let i = 0; i < settings.tokenLength; i++) + res += possible.charAt(Math.floor(Math.random() * possibleLen)); + + return res; + }; + + // GET user. + router.post('/user', (req, res) => { + const becomeUsed = req.session.viewedUser && req.user.admin; + + let user = req.user; + + if (becomeUsed) { + user = req.session.viewedUser; + + user.becomeUsed = true; + } + else if (user) + user = user.toJSON(); + else + return res.json(user); + + mongo.Space.findOne({owner: user._id, demo: true}).exec() + .then((demoSpace) => { + if (user && demoSpace) + user.demoCreated = true; + + res.json(user); + }) + .catch((err) => { + res.status(401).send(err.message); + }); + }); + + /** + * Register new account. + */ + router.post('/signup', (req, res) => { + mongo.Account.count().exec() + .then((cnt) => { + req.body.admin = cnt === 0; + + req.body.token = _randomString(); + + return new mongo.Account(req.body); + }) + .then((account) => { + return new Promise((resolve, reject) => { + mongo.Account.register(account, req.body.password, (err, _account) => { + if (err) + reject(err); + + if (!_account) + reject(new Error('Failed to create account.')); + + resolve(_account); + }); + }); + }) + .then((account) => new mongo.Space({name: 'Personal space', owner: account._id}).save() + .then(() => account) + ) + .then((account) => { + return new Promise((resolve, reject) => { + req.logIn(account, {}, (err) => { + if (err) + reject(err); + + resolve(account); + }); + }); + }) + .then((account) => { + res.sendStatus(200); + + account.resetPasswordToken = _randomString(); + + return account.save() + .then(() => mail.send(account, `Thanks for signing up for ${settings.smtp.username}.`, + `Hello ${account.firstName} ${account.lastName}!<br><br>` + + `You are receiving this email because you have signed up to use <a href="http://${req.headers.host}">${settings.smtp.username}</a>.<br><br>` + + 'If you have not done the sign up and do not know what this email is about, please ignore it.<br>' + + 'You may reset the password by clicking on the following link, or paste this into your browser:<br><br>' + + `http://${req.headers.host}/password/reset?token=${account.resetPasswordToken}`)); + }) + .catch((err) => { + res.status(401).send(err.message); + }); + }); + + /** + * Sign in into exist account. + */ + router.post('/signin', (req, res, next) => { + passport.authenticate('local', (errAuth, user) => { + if (errAuth) + return res.status(401).send(errAuth.message); + + if (!user) + return res.status(401).send('Invalid email or password'); + + req.logIn(user, {}, (errLogIn) => { + if (errLogIn) + return res.status(401).send(errLogIn.message); + + return res.sendStatus(200); + }); + })(req, res, next); + }); + + /** + * Logout. + */ + router.post('/logout', (req, res) => { + req.logout(); + + res.sendStatus(200); + }); + + /** + * Send e-mail to user with reset token. + */ + router.post('/password/forgot', (req, res) => { + mongo.Account.findOne({email: req.body.email}).exec() + .then((user) => { + if (!user) + throw new Error('Account with that email address does not exists!'); + + user.resetPasswordToken = _randomString(); + + return user.save(); + }) + .then((user) => mail.send(user, 'Password Reset', + `Hello ${user.firstName} ${user.lastName}!<br><br>` + + 'You are receiving this because you (or someone else) have requested the reset of the password for your account.<br><br>' + + 'Please click on the following link, or paste this into your browser to complete the process:<br><br>' + + 'http://' + req.headers.host + '/password/reset?token=' + user.resetPasswordToken + '<br><br>' + + 'If you did not request this, please ignore this email and your password will remain unchanged.', + 'Failed to send email with reset link!') + ) + .then(() => res.status(200).send('An email has been sent with further instructions.')) + .catch((err) => { + // TODO IGNITE-843 Send email to admin + return res.status(401).send(err.message); + }); + }); + + /** + * Change password with given token. + */ + router.post('/password/reset', (req, res) => { + mongo.Account.findOne({resetPasswordToken: req.body.token}).exec() + .then((user) => { + if (!user) + throw new Error('Failed to find account with this token! Please check link from email.'); + + return new Promise((resolve, reject) => { + user.setPassword(req.body.password, (err, _user) => { + if (err) + return reject(new Error('Failed to reset password: ' + err.message)); + + _user.resetPasswordToken = undefined; // eslint-disable-line no-undefined + + resolve(_user.save()); + }); + }); + }) + .then((user) => mail.send(user, 'Your password has been changed', + `Hello ${user.firstName} ${user.lastName}!<br><br>` + + `This is a confirmation that the password for your account on <a href="http://${req.headers.host}">${settings.smtp.username}</a> has just been changed.<br><br>`, + 'Password was changed, but failed to send confirmation email!')) + .then((user) => res.status(200).send(user.email)) + .catch((err) => res.status(401).send(err.message)); + }); + + /* GET reset password page. */ + router.post('/password/validate/token', (req, res) => { + const token = req.body.token; + + mongo.Account.findOne({resetPasswordToken: token}).exec() + .then((user) => { + if (!user) + throw new Error('Invalid token for password reset!'); + + return res.json({token, email: user.email}); + }) + .catch((err) => res.status(401).send(err.message)); + }); + + factoryResolve(router); + }); +};
http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-console/src/main/js/serve/routes/routes.js ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/serve/routes/routes.js b/modules/web-console/src/main/js/serve/routes/routes.js new file mode 100644 index 0000000..cbee8bb --- /dev/null +++ b/modules/web-console/src/main/js/serve/routes/routes.js @@ -0,0 +1,103 @@ +/* + * 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. + */ + +'use strict'; + +// Fire me up! + +module.exports = { + implements: 'routes', + inject: [ + 'public-routes', + 'admin-routes', + 'profile-routes', + 'demo-routes', + 'clusters-routes', + 'domains-routes', + 'caches-routes', + 'igfs-routes', + 'notebooks-routes', + 'agent-routes', + 'ignite_modules/routes:*' // Loads all routes modules of all plugins + ] +}; + +module.exports.factory = function(publicRoutes, adminRoutes, profileRoutes, demoRoutes, + clusterRoutes, domainRoutes, cacheRoutes, igfsRoutes, notebookRoutes, agentRoutes, pluginRoutes) { + return { + register: (app) => { + app.all('*', (req, res, next) => { + req.currentUserId = () => { + if (!req.user) + return null; + + if (req.session.viewedUser && req.user.admin) + return req.session.viewedUser._id; + + return req.user._id; + }; + + next(); + }); + + const _mustAuthenticated = (req, res, next) => req.isAuthenticated() ? next() : res.redirect('/'); + + const _adminOnly = (req, res, next) => req.isAuthenticated() && req.user.admin ? next() : res.sendStatus(403); + + // Registering the standard routes + app.use('/', publicRoutes); + app.use('/admin', _mustAuthenticated, _adminOnly, adminRoutes); + app.use('/profile', _mustAuthenticated, profileRoutes); + app.use('/demo', _mustAuthenticated, demoRoutes); + + app.all('/configuration/*', _mustAuthenticated); + + app.use('/configuration/clusters', clusterRoutes); + app.use('/configuration/domains', domainRoutes); + app.use('/configuration/caches', cacheRoutes); + app.use('/configuration/igfs', igfsRoutes); + + app.use('/notebooks', _mustAuthenticated, notebookRoutes); + app.use('/agent', _mustAuthenticated, agentRoutes); + + // Registering the routes of all plugin modules + for (const name in pluginRoutes) { + if (pluginRoutes.hasOwnProperty(name)) + pluginRoutes[name].register(app, _mustAuthenticated, _adminOnly); + } + + // Catch 404 and forward to error handler. + app.use((req, res, next) => { + const err = new Error('Not Found: ' + req.originalUrl); + + err.status = 404; + + next(err); + }); + + // Production error handler: no stacktraces leaked to user. + app.use((err, req, res) => { + res.status(err.status || 500); + + res.render('error', { + message: err.message, + error: {} + }); + }); + } + }; +}; http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-console/src/main/js/serve/settings.js ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/serve/settings.js b/modules/web-console/src/main/js/serve/settings.js new file mode 100644 index 0000000..5b14bcc --- /dev/null +++ b/modules/web-console/src/main/js/serve/settings.js @@ -0,0 +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. + */ + +'use strict'; + +// Fire me up! + +/** + * Module with server-side configuration. + */ +module.exports = { + implements: 'settings', + inject: ['require(nconf)', 'require(fs)'] +}; + +module.exports.factory = function(nconf, fs) { + nconf.file({file: './serve/config/settings.json'}); + + /** + * Normalize a port into a number, string, or false. + */ + const _normalizePort = function(val) { + const port = parseInt(val, 10); + + // named pipe + if (isNaN(port)) + return val; + + // port number + if (port >= 0) + return port; + + return false; + }; + + return { + agent: { + dists: 'serve/agent_dists', + port: _normalizePort(nconf.get('agent-server:port') || 3002), + legacyPort: _normalizePort(nconf.get('agent-server:legacyPort')), + SSLOptions: nconf.get('agent-server:ssl') && { + key: fs.readFileSync(nconf.get('agent-server:key')), + cert: fs.readFileSync(nconf.get('agent-server:cert')), + passphrase: nconf.get('agent-server:keyPassphrase') + } + }, + server: { + port: _normalizePort(nconf.get('server:port') || 3000), + SSLOptions: nconf.get('server:ssl') && { + enable301Redirects: true, + trustXFPHeader: true, + key: fs.readFileSync(nconf.get('server:key')), + cert: fs.readFileSync(nconf.get('server:cert')), + passphrase: nconf.get('server:keyPassphrase') + } + }, + smtp: { + service: nconf.get('smtp:service'), + username: nconf.get('smtp:username'), + sign: nconf.get('smtp:sign'), + email: nconf.get('smtp:email'), + password: nconf.get('smtp:password'), + address: (username, email) => username ? '"' + username + '" <' + email + '>' : email + }, + mongoUrl: nconf.get('mongoDB:url') || 'mongodb://localhost/console', + cookieTTL: 3600000 * 24 * 30, + sessionSecret: 'keyboard cat', + tokenLength: 20 + }; +}; http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-console/src/main/js/views/base.jade ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/views/base.jade b/modules/web-console/src/main/js/views/base.jade new file mode 100644 index 0000000..a910d1b --- /dev/null +++ b/modules/web-console/src/main/js/views/base.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. + +include includes/header + +.container.body-container + .main-content(ui-view='') + +include includes/footer http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-console/src/main/js/views/configuration/caches.jade ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/views/configuration/caches.jade b/modules/web-console/src/main/js/views/configuration/caches.jade new file mode 100644 index 0000000..a5b331f --- /dev/null +++ b/modules/web-console/src/main/js/views/configuration/caches.jade @@ -0,0 +1,52 @@ +//- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +include ../../app/helpers/jade/mixins.jade + +.docs-header + h1 Configure Ignite Caches +.docs-body(ng-controller='cachesController') + ignite-information + ul + li Configure #[a(href='https://apacheignite.readme.io/docs/data-grid' target='_blank') memory] settings + li Configure persistence + div(ignite-loading='loadingCachesScreen' ignite-loading-text='Loading caches...' ignite-loading-position='top') + div(ng-show='ui.ready') + hr + +main-table('caches', 'caches', 'cacheName', 'selectItem(row)', '{{$index + 1}}) {{row.label}}', 'label') + .padding-top-dflt(bs-affix) + .panel-tip-container(data-placement='bottom' bs-tooltip='' data-title='Create new cache') + button.btn.btn-primary(id='new-item' ng-click='createItem()') Add cache + +save-remove-clone-undo-buttons('cache') + hr + .bs-affix-fix + div(bs-collapse='' data-allow-multiple='true' ng-model='ui.activePanels') + form.form-horizontal(name='ui.inputForm' ng-show='contentVisible()' novalidate) + .panel-group + ignite-configuration-caches-general + ignite-configuration-caches-memory + ignite-configuration-caches-query + ignite-configuration-caches-store + + +advanced-options-toggle-default + + div(ng-show='ui.expanded') + ignite-configuration-caches-concurrency + ignite-configuration-caches-rebalance + ignite-configuration-caches-server-near-cache + ignite-configuration-caches-statistics + + +advanced-options-toggle-default http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-console/src/main/js/views/configuration/clusters.jade ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/views/configuration/clusters.jade b/modules/web-console/src/main/js/views/configuration/clusters.jade new file mode 100644 index 0000000..6e29d86 --- /dev/null +++ b/modules/web-console/src/main/js/views/configuration/clusters.jade @@ -0,0 +1,60 @@ +//- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +include ../../app/helpers/jade/mixins.jade + +.docs-header + h1 Configure Ignite Clusters +.docs-body(ng-controller='clustersController') + ignite-information + ul + li Configure #[a(href='https://apacheignite.readme.io/docs/clustering' target='_blank') clusters] properties + li Associate clusters with caches and in-memory file systems + div(ignite-loading='loadingClustersScreen' ignite-loading-text='Loading clusters...' ignite-loading-position='top') + div(ng-show='ui.ready') + hr + +main-table('clusters', 'clusters', 'clusterName', 'selectItem(row)', '{{$index + 1}}) {{row.label}}', 'label') + .padding-top-dflt(bs-affix) + .panel-tip-container(data-placement='bottom' bs-tooltip='' data-title='Create new cluster') + button.btn.btn-primary(id='new-item' ng-click='createItem()') Add cluster + +save-remove-clone-undo-buttons('cluster') + hr + .bs-affix-fix + div(bs-collapse='' data-allow-multiple='true' ng-model='ui.activePanels') + form.form-horizontal(name='ui.inputForm' ng-show='contentVisible()' novalidate) + .panel-group + ignite-configuration-clusters-general + + +advanced-options-toggle-default + + div(ng-show='ui.expanded') + ignite-configuration-clusters-atomic + ignite-configuration-clusters-binary + ignite-configuration-clusters-communication + ignite-configuration-clusters-connector + ignite-configuration-clusters-deployment + ignite-configuration-clusters-discovery + ignite-configuration-clusters-events + ignite-configuration-clusters-igfs + ignite-configuration-clusters-marshaller + ignite-configuration-clusters-metrics + ignite-configuration-clusters-ssl + ignite-configuration-clusters-swap + ignite-configuration-clusters-thread + ignite-configuration-clusters-time + ignite-configuration-clusters-transactions + + +advanced-options-toggle-default http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-console/src/main/js/views/configuration/domains-import.jade ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/views/configuration/domains-import.jade b/modules/web-console/src/main/js/views/configuration/domains-import.jade new file mode 100644 index 0000000..46385f9 --- /dev/null +++ b/modules/web-console/src/main/js/views/configuration/domains-import.jade @@ -0,0 +1,196 @@ +//- + 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 chk(mdl, change, tip) + input(type='checkbox' ng-model=mdl ng-change=change bs-tooltip='' data-title=tip data-trigger='hover' data-placement='top') + +mixin td-ellipses-lbl(w, lbl) + td.td-ellipsis(width='#{w}' style='min-width: #{w}; max-width: #{w}') + label #{lbl} + +.modal.modal-domain-import.center(role='dialog') + .modal-dialog + .modal-content(ignite-loading='importDomainFromDb' ignite-loading-text='{{importDomain.loadingOptions.text}}') + #errors-container.modal-header.header + button.close(ng-click='$hide()' aria-hidden='true') × + h4.modal-title(ng-if='!importDomain.demo') Import domain models from database + h4.modal-title(ng-if='importDomain.demo') Import domain models from demo database + .import-domain-model-wizard-page(ng-if='importDomain.action == "drivers" && !importDomain.jdbcDriversNotFound' style='margin-bottom: 321px') + .import-domain-model-wizard-page(ng-if='importDomain.action == "drivers" && importDomain.jdbcDriversNotFound' style='margin-bottom: 220px') + | Domain model could not be imported + ul + li Agent failed to find JDBC drivers + li Copy required JDBC drivers into agent '\jdbc-drivers' folder and try again + li Refer to agent README.txt for more information + .import-domain-model-wizard-page(ng-show='importDomain.action == "connect" && importDomain.demo' style='margin-bottom: 211px') + div(ng-if='demoConnection.db == "H2"') + label Demo description: + ul + li In-memory H2 database server will be started inside agent + li Database will be populated with sample tables + li You could test domain model generation with this demo database + li Click "Next" to continue + div(ng-if='demoConnection.db != "H2"') + label Demo could not be started + ul + li Agent failed to resolve H2 database jar + li Copy h2-x.x.x.jar into agent '\jdbc-drivers' folder and try again + li Refer to agent README.txt for more information + .import-domain-model-wizard-page(ng-show='importDomain.action == "connect" && !importDomain.demo' style='margin-bottom: 90px') + form.form-horizontal(name='connectForm' novalidate) + .settings-row + label.col-xs-4.col-sm-2.col-md-2 Driver JAR: + .col-xs-8.col-sm-10.col-md-10 + i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='Select appropriate JAR with JDBC driver<br> To add another driver you need to place it into "/jdbc-drivers" folder of Ignite Web Agent<br> Refer to Ignite Web Agent README.txt for for more information') + .input-tip + button.select-toggle.form-control(id='jdbcDriverJar' bs-select data-container='.modal-domain-import' ng-model='ui.selectedJdbcDriverJar' ng-class='{placeholder: !(jdbcDriverJars && jdbcDriverJars.length > 0)}' placeholder='Choose JDBC driver' bs-options='item.value as item.label for item in jdbcDriverJars') + .settings-row + label.col-xs-4.col-sm-2.col-md-2 JDBC Driver: + .col-xs-8.col-sm-10.col-md-10 + i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='Fully qualified class name of JDBC driver that will be used to connect to database') + .input-tip + input.form-control(id='jdbcDriverClass' type='text' ng-model='selectedPreset.jdbcDriverClass' placeholder='JDBC driver fully qualified class name' required=true) + .settings-row + label.col-xs-4.col-sm-2.col-md-2 JDBC URL: + .col-xs-8.col-sm-10.col-md-10 + i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='JDBC URL for connecting to database<br>Refer to your database documentation for details') + .input-tip + input.form-control(id='jdbcUrl' type='text' ng-model='selectedPreset.jdbcUrl' placeholder='JDBC URL' required=true) + .settings-row + label.col-xs-4.col-sm-2.col-md-2 User: + .col-xs-8.col-sm-10.col-md-10 + i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='User name for connecting to database') + .input-tip + input.form-control(id='user' type='text' ng-model='selectedPreset.user') + .settings-row + label.col-xs-4.col-sm-2.col-md-2 Password: + .col-xs-8.col-sm-10.col-md-10 + i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='Password for connecting to database<br>Note, password would not be saved in preferences for security reasons') + .input-tip + input.form-control(id='password' type='password' ng-model='selectedPreset.password' on-enter='importDomainNext()') + .settings-row + .checkbox + label + input(id='tablesOnly' type='checkbox' ng-model='selectedPreset.tablesOnly') + | Tables only + i.tipLabel.fa.fa-question-circle(bs-tooltip='' data-title='If selected, then only tables metadata will be parsed<br>Otherwise table and view metadata will be parsed') + .import-domain-model-wizard-page(ng-show='importDomain.action == "schemas"') + table.table.metadata(st-table='importDomain.displayedSchemas' st-safe-src='importDomain.schemas') + thead + tr + th.header(colspan='2') + .col-sm-4.pull-right(style='margin-bottom: 5px') + input.form-control(type='text' st-search='name' placeholder='Filter schemas...' ng-model='importDomain.displayedSchemasFilter' ng-change='selectSchema()') + tr + th(width='30px') + +chk('importDomain.allSchemasSelected', 'selectAllSchemas()', 'Select all schemas') + th + label Schema + tbody + tr + td(colspan='2') + .scrollable-y(style='height: 213px') + table.table-modal-striped(id='importSchemasData') + tbody + tr(ng-repeat='schema in importDomain.displayedSchemas') + td(width='30px') + input(type='checkbox' ng-model='schema.use' ng-change='selectSchema()') + td + label {{schema.name}} + .import-domain-model-wizard-page(ng-show='importDomain.action == "tables"') + table.table.metadata(st-table='importDomain.displayedTables' st-safe-src='importDomain.tables') + thead + tr + th.header(colspan='6') + .col-sm-4.pull-right(style='margin-bottom: 8px') + input.form-control(type='text' st-search='label' placeholder='Filter tables...' ng-model='importDomain.displayedTablesFilter' ng-change='selectTable()') + tr + th(width='30px') + +chk('importDomain.allTablesSelected', 'selectAllTables()', 'Select all tables') + th(width='130px') + label Schema + th(width='160px') + label Table name + th(colspan=2 width='288px') + label Cache + th + tbody + tr + td(colspan='6') + .scrollable-y(style='height: 143px') + table.table-modal-striped(id='importTableData') + tbody + tr(ng-repeat='table in importDomain.displayedTables track by $index') + td(width='30px' style='min-width: 30px; max-width: 30px') + input(type='checkbox' ng-model='table.use' ng-change='selectTable()') + +td-ellipses-lbl('130px', '{{table.schema}}') + +td-ellipses-lbl('160px', '{{table.tbl}}') + td(colspan='2' width='288px' style='min-width: 160px; max-width: 160px') + div.td-ellipsis + a(ng-if='!table.edit' ng-click='startEditDbTableCache(table)') {{tableActionView(table)}} + div(style='display: flex' ng-if='table.edit') + button.select-toggle.form-control(style='width: 35%; margin-right: 5px' bs-select ng-model='table.action' data-container='.modal-domain-import' bs-options='item.value as item.shortLabel for item in importActions') + button.select-toggle.form-control(style='width: 65%; margin-right: 0' bs-select ng-model='table.cacheOrTemplate' data-container='.modal-domain-import' bs-options='item.value as item.label for item in table.cachesOrTemplates') + td + .settings-row + label Defaults to be applied for filtered tables + i.tipLabel.fa.fa-question-circle(bs-tooltip='' data-title='Select and apply options for caches generation') + .settings-row + .col-sm-11 + .col-sm-6(style='padding-right: 5px') + button.select-toggle.form-control(bs-select ng-model='importCommon.action' data-container='.modal-domain-import' bs-options='item.value as item.label for item in importActions') + .col-sm-6(style='padding-left: 5px; padding-right: 5px') + button.select-toggle.form-control(bs-select ng-model='importCommon.cacheOrTemplate' data-container='.modal-domain-import' bs-options='item.value as item.label for item in importCommon.cachesOrTemplates') + .col-sm-1(style='padding-left: 5px') + button.btn.btn-primary(ng-click='applyDefaults()') Apply + .import-domain-model-wizard-page(ng-show='importDomain.action == "options"' style='margin-bottom: 176px') + form.form-horizontal(name='optionsForm' novalidate) + .settings-row + .col-xs-3.col-sm-2.col-md-2.required + label.required Package: + .col-xs-9.col-sm-10.col-md-10 + i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='Package that will be used for POJOs generation') + .input-tip + input.form-control(id='domainPackageName' type='text' ng-model='ui.packageName' placeholder='Package for POJOs generation') + .settings-row + .checkbox + label + input(id='domainBuiltinKeys' type='checkbox' ng-model='ui.builtinKeys') + | Use Java built-in types for keys + i.tipLabel.fa.fa-question-circle(bs-tooltip='' data-title='Use Java built-in types like "Integer", "Long", "String" instead of POJO generation in case when table primary key contains only one field') + .settings-row + .checkbox + label + input(id='domainUsePrimitives' type='checkbox' ng-model='ui.usePrimitives') + | Use primitive types for NOT NULL table columns + i.tipLabel.fa.fa-question-circle(bs-tooltip='' data-title='Use primitive types like "int", "long", "double" for POJOs fields generation in case of NOT NULL columns') + .settings-row + .checkbox + label + input(id='domainGenerateAliases' type='checkbox' ng-model='ui.generateAliases') + | Generate aliases for query fields + i.tipLabel.fa.fa-question-circle(bs-tooltip='' data-title='Generate aliases for query fields with names from database fields') + .settings-row + .col-xs-3.col-sm-2.col-md-2.required + label Clusters: + .col-xs-9.col-sm-10.col-md-10 + i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='Choose clusters that will be associated with generated caches') + .input-tip + button.select-toggle.form-control(id='generatedCachesClusters' bs-select ng-model='ui.generatedCachesClusters' ng-class='{placeholder: !(ui.generatedCachesClusters && ui.generatedCachesClusters.length > 0)}' data-container='.modal-domain-import' data-multiple='1' placeholder='Choose clusters for generated caches' bs-options='item.value as item.label for item in clusters') + .modal-footer + label(ng-hide='importDomain.action == "drivers" || (importDomain.action == "connect" && importDomain.demo)').labelField {{importDomain.info}} + a.btn.btn-primary(ng-hide='importDomain.action == "drivers" || importDomain.action == "connect"' ng-click='importDomainPrev()' bs-tooltip='' data-title='{{prevTooltipText()}}' data-placement='bottom') Prev + a.btn.btn-primary(ng-click='importDomainNext()' ng-disabled='!importDomainNextAvailable()' bs-tooltip='' data-title='{{nextTooltipText()}}' data-placement='bottom') {{importDomain.button}} http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-console/src/main/js/views/configuration/domains.jade ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/views/configuration/domains.jade b/modules/web-console/src/main/js/views/configuration/domains.jade new file mode 100644 index 0000000..9975df9 --- /dev/null +++ b/modules/web-console/src/main/js/views/configuration/domains.jade @@ -0,0 +1,66 @@ +//- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +include ../../app/helpers/jade/mixins.jade + +.docs-header + h1 Configure Domain Model And SQL Queries +.docs-body(ng-controller='domainsController') + ignite-information + ul: li Import database schemas + li Configure indexed types + div(ignite-loading='loadingDomainModelsScreen' ignite-loading-text='Loading domain models...' ignite-loading-position='top') + div(ng-show='ui.ready') + hr + .padding-bottom-dflt(ng-show='domains && domains.length > 0') + table.links(st-table='displayedRows' st-safe-src='domains') + thead + tr + th + .col-sm-8 + .col-sm-5 + lable.labelHeader.labelFormField {{domainModelTitle()}} + .col-sm-7 + .pull-right.labelLogin.additional-filter(ng-if='(domains | domainsValidation:false:true).length > 0') + a.labelFormField(ng-if='ui.showValid' ng-click='toggleValid()' bs-tooltip='' data-title='{{::ui.invalidKeyFieldsTooltip}}') Key fields should be configured: {{(displayedRows | domainsValidation:false:true).length}}  + a.labelFormField(ng-if='!ui.showValid' ng-click='toggleValid()') Show all domain models: {{displayedRows.length}}  + .col-sm-4 + input.form-control.pull-right(type='text' st-search='valueType' placeholder='Filter domain models...') + tbody + tr + td + .scrollable-y(ng-show='(displayedRows | domainsValidation:ui.showValid:true).length > 0' style='max-height: 200px') + table + tbody + tr(ng-repeat='row in (displayedRows | domainsValidation:ui.showValid:true) track by row._id' ignite-bs-affix-update) + td + a(ng-class='{active: row._id == selectedItem._id}' ng-click='selectItem(row)') {{$index + 1}}) {{row.valueType}} + label.placeholder(ng-show='(displayedRows | domainsValidation:ui.showValid:true).length == 0') No domain models found + .padding-top-dflt(bs-affix) + .panel-tip-container(data-placement='bottom' bs-tooltip='' data-title='Create new domain model') + button.btn.btn-primary(id='new-item' ng-click='createItem()') Add domain model + .panel-tip-container(bs-tooltip='' data-title='Import domain models from database' data-placement='bottom') + button.btn.btn-primary(ng-click='showImportDomainModal()') Import from database + +save-remove-clone-undo-buttons('domain model') + .btn-group.panel-tip-container.pull-right(bs-tooltip='' data-title='Import domain models from demo database' data-placement='bottom') + hr + .bs-affix-fix + div(bs-collapse='' data-allow-multiple='true' ng-model='ui.activePanels') + form.form-horizontal(name='ui.inputForm' ng-show='contentVisible()' novalidate) + .panel-group + ignite-configuration-domains-general + ignite-configuration-domains-query + ignite-configuration-domains-store http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-console/src/main/js/views/configuration/igfs.jade ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/views/configuration/igfs.jade b/modules/web-console/src/main/js/views/configuration/igfs.jade new file mode 100644 index 0000000..b889a97 --- /dev/null +++ b/modules/web-console/src/main/js/views/configuration/igfs.jade @@ -0,0 +1,51 @@ +//- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +include ../../app/helpers/jade/mixins.jade + +.docs-header + h1 Configure Ignite In-memory File Systems +.docs-body(ng-controller='igfsController') + ignite-information(data-title='Configure IGFS only if you are going to use In-memory File System') + ul + li Ignite File System (#[a(href='https://apacheignite-fs.readme.io/docs/in-memory-file-system' target='_blank') IGFS]) is an in-memory file system allowing work with files and directories over existing cache infrastructure + li IGFS can either work as purely in-memory file system, or delegate to another file system (e.g. various Hadoop file system implementations) acting as a caching layer (see #[a(href='https://apacheignite-fs.readme.io/docs/secondary-file-system' target='_blank') secondary file system] for more detail) + li In addition IGFS provides API to execute map-reduce tasks over file system data + div(ignite-loading='loadingIgfsScreen' ignite-loading-text='Loading IGFS screen...' ignite-loading-position='top') + div(ng-show='ui.ready') + hr + +main-table('IGFS', 'igfss', 'igfsName', 'selectItem(row)', '{{$index + 1}}) {{row.name}}', 'name') + .padding-top-dflt(bs-affix) + .panel-tip-container(data-placement='bottom' bs-tooltip='' data-title='Create new IGFS') + button.btn.btn-primary(id='new-item' ng-click='createItem()') Add IGFS + +save-remove-clone-undo-buttons('IGFS') + hr + .bs-affix-fix + div(bs-collapse='' data-allow-multiple='true' ng-model='ui.activePanels') + form.form-horizontal(name='ui.inputForm' ng-show='contentVisible()' novalidate) + .panel-group + ignite-configuration-igfs-general + + +advanced-options-toggle-default + + div(ng-show='ui.expanded') + ignite-configuration-igfs-secondary + ignite-configuration-igfs-ipc + ignite-configuration-igfs-fragmentizer + ignite-configuration-igfs-dual + ignite-configuration-igfs-misc + + +advanced-options-toggle-default http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-console/src/main/js/views/configuration/sidebar.jade ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/views/configuration/sidebar.jade b/modules/web-console/src/main/js/views/configuration/sidebar.jade new file mode 100644 index 0000000..bba6b25 --- /dev/null +++ b/modules/web-console/src/main/js/views/configuration/sidebar.jade @@ -0,0 +1,29 @@ +//- + 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. + +.row + .col-xs-3.col-sm-3.col-md-2.border-right.section-left.greedy + .sidebar-nav(bs-affix) + ul.menu(ignite-sidebar) + li(ng-repeat='item in sidebar.items') + a(ui-sref-active='active' ui-sref='{{::item.sref}}') + span.fa-stack + i.fa.fa-circle-thin.fa-stack-2x + i.fa.fa-stack-1x {{::$index + 1}} + | {{::item.text}} + + .col-xs-9.col-sm-9.col-md-10.border-left.section-right + .docs-content(ui-view='') http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-console/src/main/js/views/configuration/summary-project-structure.jade ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/views/configuration/summary-project-structure.jade b/modules/web-console/src/main/js/views/configuration/summary-project-structure.jade new file mode 100644 index 0000000..aa09437 --- /dev/null +++ b/modules/web-console/src/main/js/views/configuration/summary-project-structure.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. +.popover.summary-project-structure + h3.popover-title + label.labelField Project structure + button.close(id='summary-project-structure-close' ng-click='$hide()') × + .popover-content + treecontrol.tree-classic(tree-model='projectStructure' options='projectStructureOptions' expanded-nodes='projectStructureExpanded') + span(ng-switch='' on='node.type') + span(ng-switch-when='folder') + label {{node.name}} + span(ng-switch-when='file') + i.fa.fa-file-text-o + label {{node.name}} http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-console/src/main/js/views/configuration/summary-tabs.jade ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/views/configuration/summary-tabs.jade b/modules/web-console/src/main/js/views/configuration/summary-tabs.jade new file mode 100644 index 0000000..847b42f --- /dev/null +++ b/modules/web-console/src/main/js/views/configuration/summary-tabs.jade @@ -0,0 +1,25 @@ +//- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +ul.nav(ng-class='$navClass', role='tablist') + li(role='presentation' ng-repeat='$pane in $panes track by $index' ng-class='[ $isActive($pane, $index) ? $activeClass : "", $pane.disabled ? "disabled" : "" ]') + a.summary-tab(ng-show='$pane.title != "POJO" || (cluster | hasPojo)' ng-switch='$pane.title' role='tab' data-toggle='tab' ng-click='!$pane.disabled && $setActive($pane.name || $index)' data-index='{{ $index }}' aria-controls='$pane.title') {{$pane.title}} + img(ng-switch-when='XML' src='/images/xml.png') + img(ng-switch-when='Java' src='/images/java.png') + img(ng-switch-when='POM' src='/images/xml.png') + img(ng-switch-when='POJO' src='/images/java.png') + img(ng-switch-when='Dockerfile' src='/images/docker.png') +.tab-content(ng-transclude style='fontSize: 12px; min-height: 25em') http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-console/src/main/js/views/configuration/summary.jade ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/views/configuration/summary.jade b/modules/web-console/src/main/js/views/configuration/summary.jade new file mode 100644 index 0000000..830adc1 --- /dev/null +++ b/modules/web-console/src/main/js/views/configuration/summary.jade @@ -0,0 +1,152 @@ +//- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +include ../../app/helpers/jade/mixins.jade + +mixin hard-link(ref, txt) + a(style='color:#ec1c24' href=ref target='_blank') #{txt} + +.docs-header + h1 Configurations Summary +.docs-body + ignite-information + ul + li Preview XML configurations for #[a(href='https://apacheignite.readme.io/docs/clients-vs-servers' target='_blank') server and client] nodes + li Preview code configuration + li Preview #[a(href='https://apacheignite.readme.io/docs/docker-deployment' target='_blank') Docker file] + li Preview POM dependencies + li Download ready-to-use Maven project + + hr + .padding-dflt(ng-if='ui.ready && (!clusters || clusters.length == 0)') + | You have no clusters configured. Please configure them #[a(ui-sref='base.configuration.clusters') here]. + + div(ng-show='clusters && clusters.length > 0' ignite-loading='summaryPage' ignite-loading-text='Loading summary screen...' ignite-loading-position='top') + +main-table('clusters', 'clustersView', 'clusterName', 'selectItem(row)', '{{$index + 1}}) {{row.name}}', 'name') + div(ng-show='selectedItem && contentVisible(displayedRows, selectedItem)') + .padding-top-dflt(bs-affix) + button.btn.btn-primary(id='download' ng-click='downloadConfiguration()' bs-tooltip='' data-title='Download project' data-placement='bottom') Download project + .btn.btn-primary(bs-tooltip='' data-title='Preview generated project structure' data-placement='bottom') + div(bs-popover data-template-url='/configuration/summary-project-structure.html', data-placement='bottom', data-trigger='click' data-auto-close='true') + i.fa.fa-sitemap + label.tipLabel Project structure + button.btn.btn-primary(id='proprietary-jdbc-drivers' ng-if='downloadJdbcDriversVisible()' ng-click='downloadJdbcDrivers()' bs-tooltip='' data-title='Open proprietary JDBC drivers download pages' data-placement='bottom') Download JDBC drivers + hr + .bs-affix-fix + .panel-group(bs-collapse ng-init='ui.activePanels=[0,1]' ng-model='ui.activePanels' data-allow-multiple='true') + .panel.panel-default + .panel-heading(role='tab' bs-collapse-toggle) + ignite-form-panel-chevron + label Server + + .panel-collapse(id='server' role='tabpanel' bs-collapse-target) + ignite-ui-ace-tabs.summary-tabs + div(bs-tabs data-bs-active-pane="tabsServer.activeTab" template='configuration/summary-tabs.html') + div(bs-pane title='XML') + ignite-ui-ace-xml(ng-if='tabsServer.activeTab == 0 || tabsServer.init[0]' ng-init='tabsServer.init[0] = true' data-master='cluster' data-no-deep-watch) + div(bs-pane title='Java') + ignite-ui-ace-java(ng-if='tabsServer.activeTab == 1 || tabsServer.init[1]' ng-init='tabsServer.init[1] = true' data-master='cluster' data-no-deep-watch) + div(bs-pane title='POM') + ignite-ui-ace-pom(ng-if='tabsServer.activeTab == 2 || tabsServer.init[2]' ng-init='tabsServer.init[2] = true' data-cluster='cluster' data-no-deep-watch) + div(bs-pane title='Dockerfile') + ignite-ui-ace-docker(ng-if='tabsServer.activeTab == 3 || tabsServer.init[3]' ng-init='tabsServer.init[3] = true' data-cluster='cluster' data-no-deep-watch ng-model='ctrl.data.docker') + + .panel.panel-default + .panel-heading(role='tab' bs-collapse-toggle) + ignite-form-panel-chevron + label Client + + .panel-collapse(id='client' role='tabpanel' bs-collapse-target) + form(name='clientForm' novalidate) + -var nearCfg = 'ctrl.cluster.clientNearCfg' + -var nearCfgEvictionPolicy = nearCfg + '.nearEvictionPolicy[' + nearCfg + '.nearEvictionPolicy.kind]' + + .group-content + .settings-row + ignite-form-field.col-xs-8.col-sm-8.col-md-7(data-label='Near cache start size') + ignite-form-field-tooltip + | Initial cache size for near cache which will be used to pre-create internal hash table after start + ignite-form-field-input-number( + data-name='nearStartSize' + data-ng-model='#{nearCfg}.nearStartSize' + data-placeholder='375000' + ) + + .settings-row + ignite-form-field.col-xs-8.col-sm-8.col-md-7(data-label='Near cache eviction policy') + ignite-form-field-tooltip + | Cache expiration policy + ignite-form-field-dropdown( + data-id='evictionPolicies' + data-name='evictionPolicies' + data-placeholder='Not set' + data-options='[\ + {value: "LRU", label: "LRU"},\ + {value: "FIFO", label: "FIFO"},\ + {value: "SORTED", label: "Sorted"},\ + {value: undefined, label: "Not set"}\ + ]' + data-ng-model='#{nearCfg}.nearEvictionPolicy.kind' + ) + span(ng-if='#{nearCfg}.nearEvictionPolicy.kind') + a.customize( + ng-show='ctrl.__form.expanded' + ng-click='ctrl.__form.expanded = false' + ) Hide settings + a.customize( + ng-hide='ctrl.__form.expanded' + ng-click='ctrl.__form.expanded = true' + ) Show settings + + .settings-row + .panel-details.col-xs-12.col-sm-12.col-md-7(ng-if='ctrl.__form.expanded && #{nearCfg}.nearEvictionPolicy.kind') + .details-row + ignite-form-field(data-label='Batch size') + ignite-form-field-tooltip + | Number of entries to remove on shrink + ignite-form-field-input-number( + data-name='batchSize' + data-ng-model='#{nearCfgEvictionPolicy}.batchSize' + data-placeholder='1' + ) + .details-row + ignite-form-field(data-label='Max memory size') + ignite-form-field-tooltip + | Maximum allowed cache size in bytes + ignite-form-field-input-number( + data-name='maxMemorySize' + data-ng-model='#{nearCfgEvictionPolicy}.maxMemorySize' + data-placeholder='0' + ) + .details-row + ignite-form-field(data-label='Max size') + ignite-form-field-tooltip + | Maximum allowed size of cache before entry will start getting evicted + ignite-form-field-input-number( + data-name='maxSize' + data-ng-model='#{nearCfgEvictionPolicy}.maxSize' + data-placeholder='100000' + ) + .summary-tabs(ignite-ui-ace-tabs) + div(bs-tabs data-bs-active-pane="tabsClient.activeTab" template='configuration/summary-tabs.html') + div(bs-pane title='XML') + ignite-ui-ace-xml(ng-if='tabsClient.activeTab == 0 || tabsClient.init[0]' ng-init='tabsClient.init[0] = true' data-master='cluster' data-no-deep-watch data-cluster-cfg='#{nearCfg}') + div(bs-pane title='Java') + ignite-ui-ace-java(ng-if='tabsClient.activeTab == 1 || tabsClient.init[1]' ng-init='tabsClient.init[1] = true' data-master='cluster' data-no-deep-watch data-cluster-cfg='#{nearCfg}') + div(bs-pane title='POM') + ignite-ui-ace-pom(ng-if='tabsClient.activeTab == 2 || tabsClient.init[2]' ng-init='tabsClient.init[2] = true' data-cluster='cluster' data-no-deep-watch) + div(bs-pane title='POJO' ng-if='cluster | hasPojo') + ignite-ui-ace-pojos(ng-if='tabsClient.activeTab == 3 || tabsClient.init[3]' ng-init='tabsClient.init[3] = true' data-cluster='cluster' data-no-deep-watch ng-model='ctrl.data.pojos') http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-console/src/main/js/views/includes/footer.jade ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/views/includes/footer.jade b/modules/web-console/src/main/js/views/includes/footer.jade new file mode 100644 index 0000000..4ef3bf6 --- /dev/null +++ b/modules/web-console/src/main/js/views/includes/footer.jade @@ -0,0 +1,23 @@ +//- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +.container.container-footer + footer + .col-md-offset-1.col-md-10 + ignite-footer + .col-md-1 + .pull-right + ignite-powered-by-apache http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-console/src/main/js/views/includes/header.jade ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/views/includes/header.jade b/modules/web-console/src/main/js/views/includes/header.jade new file mode 100644 index 0000000..2b66d82 --- /dev/null +++ b/modules/web-console/src/main/js/views/includes/header.jade @@ -0,0 +1,48 @@ +//- + 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. + +header#header.header + .viewedUser(ng-show='$root.user.becomeUsed') + | Currently assuming #[strong {{$root.user.firstName}} {{$root.user.lastName}}], #[a(ng-click='$root.revertIdentity()') revert to your identity]. + table.container + tr + td.col-xs-3.col-sm-3.col-md-2 + ignite-header-logo + td(ng-if='$root.user' style='padding-top: 20px') + ul.nav.navbar-nav(ignite-sidebar ignite-navbar) + li(ng-class='{active: $state.includes("base.configuration")}') + a.dropdown-toggle(data-toggle='dropdown' bs-dropdown='sidebar.items' data-placement='bottom-right') Configuration + span.caret + + li.sql-notebooks(ng-class='{active: $state.includes("base.sql")}' ng-controller='notebooks') + a(ng-if='IgniteDemoMode' ui-sref='base.sql.demo') SQL + + a(ng-if='!IgniteDemoMode && !notebooks.length' ng-click='inputNotebookName()') SQL + + a.dropdown-toggle(ng-if='!IgniteDemoMode && notebooks.length' data-toggle='dropdown' bs-dropdown='notebookDropdown' data-placement='bottom-left') SQL + span.caret + + li(ui-sref-active='active' ng-repeat='item in navbar.items') + a(ui-sref='{{::item.sref}}') {{::item.text}} + + a(ng-controller='demoController') + button.btn.btn-info(ng-if='IgniteDemoMode' ng-click='closeDemo()') Close demo + button.btn.btn-info(ng-if='!IgniteDemoMode' ng-click='startDemo()') Start demo + + ul.nav.navbar-nav.pull-right(ignite-userbar) + li(ng-class='{active: $state.includes("settings")}') + a.dropdown-toggle(data-toggle='dropdown' bs-dropdown='userbar.items' data-placement='bottom-right') {{user.firstName}} {{user.lastName}} + span.caret http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-console/src/main/js/views/index.jade ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/views/index.jade b/modules/web-console/src/main/js/views/index.jade new file mode 100644 index 0000000..8514533 --- /dev/null +++ b/modules/web-console/src/main/js/views/index.jade @@ -0,0 +1,66 @@ +//- + 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-console' id='app' ng-strict-di) + head + base(href='/') + link(rel='shortcut icon' href='favicon.ico') + + meta(http-equiv='content-type' content='text/html; charset=UTF8') + meta(http-equiv='content-language' content='en') + + title(ng-bind='$meta.title') + + meta(name='fragment' content='!') + meta(name='description' content='{{$meta.description}}') + meta(name='keywords' content='{{$meta.keywords}}') + meta(ng-repeat='(key, value) in $meta.properties' name='{{::key}}' content='{{::value}}') + + // build:css + link(rel='stylesheet', href='/vendors.css') + link(rel='stylesheet', href='/app.css') + // endbuild + + body.theme-line.body-overlap.greedy + + .splash.splash-max-foreground(hide-on-state-change) + .splash-wrapper + .spinner + .bounce1 + .bounce2 + .bounce3 + + .splash-wellcome Loading... + + + .ribbon-wrapper.right(ng-cloak) + .ribbon(ng-style='IgniteDemoMode && {"background": "#1b6d88"}') + label {{IgniteDemoMode ? "Demo" : "Beta" }} + + .wrapper(ui-view='') + + + // build:js + script(src='jspm_packages/system.js') + script(src='system.config.js') + script(src='vendors.js') + script(src='app.js') + script System.import('app/index'); + // endbuild + + // ignite:plugins + // endignite \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-console/src/main/js/views/reset.jade ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/views/reset.jade b/modules/web-console/src/main/js/views/reset.jade new file mode 100644 index 0000000..e5b8f12 --- /dev/null +++ b/modules/web-console/src/main/js/views/reset.jade @@ -0,0 +1,48 @@ +//- + 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. + +header#header.header + table.container + tr + td.col-xs-3.col-sm-3.col-md-2 + ignite-header-logo + td + ignite-header-title + +.container.body-container + .main-content(ng-controller='resetPassword') + .row + .text-center(ng-if='!token') + p Further instructions for password reset have been sent to your e-mail address. + .text-center(ng-if='error') + p {{::error}} + div(ng-if='token && !error') + form.form-horizontal(name='resetForm' ng-init='reset_info.token = token') + .settings-row + label.col-sm-1 E-mail: + label {{::email}} + .settings-row + label.col-sm-1.required Password: + .col-sm-3 + input#user_password.form-control(enter-focus-next='user_confirm' type='password' ng-model='reset_info.password' placeholder='New password' required) + .settings-row + label.col-sm-1.required Confirm: + .col-sm-3 + input#user_confirm.form-control(type='password' ng-model='reset_info.confirm' match='reset_info.password' placeholder='Confirm new password' required on-enter='resetForm.$valid && resetPassword(user_info)') + .settings-row + button.btn.btn-primary(ng-disabled='resetForm.$invalid' ng-click='resetPassword(reset_info)') Reset Password + +include includes/footer http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-console/src/main/js/views/settings/admin.jade ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/views/settings/admin.jade b/modules/web-console/src/main/js/views/settings/admin.jade new file mode 100644 index 0000000..862d959 --- /dev/null +++ b/modules/web-console/src/main/js/views/settings/admin.jade @@ -0,0 +1,76 @@ +//- + 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. + +.row(ng-controller='adminController') + .docs-content.greedy + .docs-header + h1 List of registered users + hr + .docs-body + .col-xs-12 + table.table.table-striped.table-vertical-middle.admin(st-table='displayedUsers' st-safe-src='users') + thead + tr + th.header(colspan='10') + .col-xs-3 + input.form-control(type='text' st-search='label' placeholder='Filter users...') + .col-xs-9.admin-summary.text-right(colspan='10') + strong Total users: {{ users.length }} + .col-xs-offset-6.col-xs-6.text-right + div(st-pagination st-items-by-page='15' st-displayed-pages='5' st-template='../templates/pagination.html') + tr + th(st-sort='userName') User + th(st-sort='email') Email + th(st-sort='company') Company + th(st-sort='country') Country + th.col-xs-2(st-sort='lastLogin' st-sort-default='reverse') Last login + th.text-nowrap(st-sort='counters.clusters' st-descending-first bs-tooltip='"Clusters count"' data-placement='top') + i.fa.fa-sitemap() + th.text-nowrap(st-sort='counters.models' st-descending-first bs-tooltip='"Models count"' data-placement='top') + i.fa.fa-object-group() + th.text-nowrap(st-sort='counters.caches' st-descending-first bs-tooltip='"Caches count"' data-placement='top') + i.fa.fa-database() + th.text-nowrap(st-sort='counters.igfs' st-descending-first bs-tooltip='"IGFS count"' data-placement='top') + i.fa.fa-folder-o() + th(width='1%') Actions + tbody + tr(ng-repeat='row in displayedUsers track by row._id') + td {{::row.userName}} + td + a(ng-href='mailto:{{::row.email}}') {{::row.email}} + td {{::row.company}} + td {{::row.countryCode}} + td {{::row.lastLogin | date:'medium'}} + td {{::row.counters.clusters}} + td {{::row.counters.models}} + td {{::row.counters.caches}} + td {{::row.counters.igfs}} + td.text-center + a.btn.btn-default.dropdown-toggle(bs-dropdown='' ng-show='row._id != user._id' data-placement='bottom-right') + i.fa.fa-gear + span.caret + ul.dropdown-menu(role='menu') + li + a(ng-click='becomeUser(row)') Become this user + li + a(ng-click='toggleAdmin(row)' ng-if='row.admin && row._id !== user._id') Revoke admin + a(ng-click='toggleAdmin(row)' ng-if='!row.admin && row._id !== user._id') Grant admin + li + a(ng-click='removeUser(row)') Remove user + tfoot + tr + td.text-right(colspan='10') + div(st-pagination st-items-by-page='15' st-displayed-pages='5' st-template='../templates/pagination.html')
