You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2017/02/15 10:44:37 UTC
[12/50] [abbrv] ignite git commit: IGNITE-4472 Added user activities
in Web Console.
IGNITE-4472 Added user activities in Web Console.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/26ee9c28
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/26ee9c28
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/26ee9c28
Branch: refs/heads/ignite-3477-merge2.0
Commit: 26ee9c2865648118da97ee8ef84df990359edb96
Parents: e6ea938
Author: Andrey Novikov <an...@gridgain.com>
Authored: Wed Feb 8 11:43:22 2017 +0700
Committer: Andrey Novikov <an...@gridgain.com>
Committed: Wed Feb 8 11:43:22 2017 +0700
----------------------------------------------------------------------
modules/web-console/backend/app/agent.js | 10 +-
modules/web-console/backend/app/mongo.js | 49 ++--
modules/web-console/backend/app/routes.js | 5 +-
.../web-console/backend/routes/activities.js | 52 +++++
modules/web-console/backend/routes/admin.js | 2 +-
modules/web-console/backend/routes/agent.js | 10 +-
modules/web-console/backend/routes/public.js | 1 -
.../web-console/backend/services/activities.js | 136 +++++++++++
modules/web-console/backend/services/users.js | 13 +-
modules/web-console/frontend/app/app.config.js | 9 +
modules/web-console/frontend/app/app.js | 29 ++-
.../activities-user-dialog.controller.js | 60 +++++
.../activities-user-dialog.jade | 36 +++
.../components/activities-user-dialog/index.js | 36 +++
.../form-field-datepicker.jade | 55 +++++
.../form-field-datepicker.scss | 20 ++
.../list-of-registered-users/index.js | 28 +++
.../list-of-registered-users.categories.js | 30 +++
.../list-of-registered-users.column-defs.js | 80 +++++++
.../list-of-registered-users.controller.js | 207 ++++++++++++++++
.../list-of-registered-users.jade | 54 +++++
.../ui-grid-header/ui-grid-header.jade | 27 +++
.../ui-grid-header/ui-grid-header.scss | 84 +++++++
.../ui-grid-settings/ui-grid-settings.jade | 33 +++
.../ui-grid-settings/ui-grid-settings.scss | 70 ++++++
.../app/core/activities/Activities.data.js | 39 ++++
.../frontend/app/core/admin/Admin.data.js | 77 ++++++
modules/web-console/frontend/app/core/index.js | 25 ++
modules/web-console/frontend/app/data/i18n.js | 38 +++
.../ui-grid-settings/ui-grid-settings.jade | 33 ---
.../ui-grid-settings/ui-grid-settings.scss | 38 ---
.../app/filters/uiGridSubcategories.filter.js | 24 ++
.../frontend/app/modules/Demo/Demo.module.js | 166 -------------
.../frontend/app/modules/demo/Demo.module.js | 172 ++++++++++++++
.../frontend/app/modules/sql/sql.controller.js | 14 +-
.../frontend/app/modules/sql/sql.module.js | 2 +-
.../frontend/app/modules/states/admin.state.js | 2 +-
.../configuration/summary/summary.controller.js | 6 +-
.../app/modules/user/AclRoute.provider.js | 31 +--
.../frontend/app/modules/user/Auth.service.js | 2 +-
.../frontend/app/modules/user/permissions.js | 2 +-
.../frontend/app/modules/user/user.module.js | 6 +-
modules/web-console/frontend/app/vendor.js | 1 +
.../frontend/controllers/admin-controller.js | 234 -------------------
.../frontend/controllers/domains-controller.js | 12 +-
modules/web-console/frontend/package.json | 1 +
.../stylesheets/_font-awesome-custom.scss | 28 +++
.../frontend/public/stylesheets/style.scss | 39 +++-
.../frontend/public/stylesheets/variables.scss | 1 +
.../frontend/views/settings/admin.jade | 32 +--
modules/web-console/frontend/views/sql/sql.jade | 4 +-
51 files changed, 1603 insertions(+), 562 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/backend/app/agent.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/app/agent.js b/modules/web-console/backend/app/agent.js
index 961253f..8170280 100644
--- a/modules/web-console/backend/app/agent.js
+++ b/modules/web-console/backend/app/agent.js
@@ -24,7 +24,7 @@
*/
module.exports = {
implements: 'agent-manager',
- inject: ['require(lodash)', 'require(fs)', 'require(path)', 'require(jszip)', 'require(socket.io)', 'settings', 'mongo']
+ inject: ['require(lodash)', 'require(fs)', 'require(path)', 'require(jszip)', 'require(socket.io)', 'settings', 'mongo', 'services/activities']
};
/**
@@ -35,9 +35,10 @@ module.exports = {
* @param socketio
* @param settings
* @param mongo
+ * @param {ActivitiesService} activitiesService
* @returns {AgentManager}
*/
-module.exports.factory = function(_, fs, path, JSZip, socketio, settings, mongo) {
+module.exports.factory = function(_, fs, path, JSZip, socketio, settings, mongo, activitiesService) {
/**
*
*/
@@ -823,6 +824,11 @@ module.exports.factory = function(_, fs, path, JSZip, socketio, settings, mongo)
const sockets = this._browsers[accountId];
_.forEach(sockets, (socket) => socket.emit('agent:count', {count: agents.length}));
+
+ activitiesService.merge(accountId, {
+ group: 'agent',
+ action: '/agent/start'
+ });
});
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/backend/app/mongo.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/app/mongo.js b/modules/web-console/backend/app/mongo.js
index dd71f3a..2d252b9 100644
--- a/modules/web-console/backend/app/mongo.js
+++ b/modules/web-console/backend/app/mongo.js
@@ -48,6 +48,7 @@ module.exports.factory = function(passportMongo, settings, pluginMongo, mongoose
company: String,
country: String,
lastLogin: Date,
+ lastActivity: Date,
admin: Boolean,
token: String,
resetPasswordToken: String
@@ -59,22 +60,26 @@ module.exports.factory = function(passportMongo, settings, pluginMongo, mongoose
usernameLowerCase: true
});
+ const transform = (doc, ret) => {
+ return {
+ _id: ret._id,
+ email: ret.email,
+ firstName: ret.firstName,
+ lastName: ret.lastName,
+ company: ret.company,
+ country: ret.country,
+ admin: ret.admin,
+ token: ret.token,
+ lastLogin: ret.lastLogin,
+ lastActivity: ret.lastActivity
+ };
+ };
+
// Configure transformation to JSON.
- AccountSchema.set('toJSON', {
- transform: (doc, ret) => {
- return {
- _id: ret._id,
- email: ret.email,
- firstName: ret.firstName,
- lastName: ret.lastName,
- company: ret.company,
- country: ret.country,
- admin: ret.admin,
- token: ret.token,
- lastLogin: ret.lastLogin
- };
- }
- });
+ AccountSchema.set('toJSON', { transform });
+
+ // Configure transformation to JSON.
+ AccountSchema.set('toObject', { transform });
result.errCodes = {
DUPLICATE_KEY_ERROR: 11000,
@@ -902,6 +907,20 @@ module.exports.factory = function(passportMongo, settings, pluginMongo, mongoose
res.status(err.code || 500).send(err.message);
};
+ // Define Activities schema.
+ const ActivitiesSchema = new Schema({
+ owner: {type: ObjectId, ref: 'Account'},
+ date: Date,
+ group: String,
+ action: String,
+ amount: { type: Number, default: 1 }
+ });
+
+ ActivitiesSchema.index({ owner: 1, group: 1, action: 1, date: 1}, { unique: true });
+
+ // Define Activities model.
+ result.Activities = mongoose.model('Activities', ActivitiesSchema);
+
// Registering the routes of all plugin modules
for (const name in pluginMongo) {
if (pluginMongo.hasOwnProperty(name))
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/backend/app/routes.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/app/routes.js b/modules/web-console/backend/app/routes.js
index 6961173..6b5d052 100644
--- a/modules/web-console/backend/app/routes.js
+++ b/modules/web-console/backend/app/routes.js
@@ -22,11 +22,11 @@
module.exports = {
implements: 'routes',
inject: ['routes/public', 'routes/admin', 'routes/profiles', 'routes/demo', 'routes/clusters', 'routes/domains',
- 'routes/caches', 'routes/igfss', 'routes/notebooks', 'routes/agents', 'routes/configurations']
+ 'routes/caches', 'routes/igfss', 'routes/notebooks', 'routes/agents', 'routes/configurations', 'routes/activities']
};
module.exports.factory = function(publicRoute, adminRoute, profilesRoute, demoRoute,
- clustersRoute, domainsRoute, cachesRoute, igfssRoute, notebooksRoute, agentsRoute, configurationsRoute) {
+ clustersRoute, domainsRoute, cachesRoute, igfssRoute, notebooksRoute, agentsRoute, configurationsRoute, activitiesRoute) {
return {
register: (app) => {
const _mustAuthenticated = (req, res, next) => {
@@ -59,6 +59,7 @@ module.exports.factory = function(publicRoute, adminRoute, profilesRoute, demoRo
app.use('/notebooks', _mustAuthenticated, notebooksRoute);
app.use('/agent', _mustAuthenticated, agentsRoute);
+ app.use('/activities', _mustAuthenticated, activitiesRoute);
}
};
};
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/backend/routes/activities.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/routes/activities.js b/modules/web-console/backend/routes/activities.js
new file mode 100644
index 0000000..08c27cf
--- /dev/null
+++ b/modules/web-console/backend/routes/activities.js
@@ -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.
+ */
+
+'use strict';
+
+// Fire me up!
+
+module.exports = {
+ implements: 'routes/activities',
+ inject: ['require(express)', 'services/activities']
+};
+
+/**
+ * @param express
+ * @param {ActivitiesService} activitiesService
+ * @returns {Promise}
+ */
+module.exports.factory = function(express, activitiesService) {
+ return new Promise((factoryResolve) => {
+ const router = new express.Router();
+
+ // Get user activities.
+ router.get('/user/:userId', (req, res) => {
+ activitiesService.listByUser(req.params.userId, req.query)
+ .then(res.api.ok)
+ .catch(res.api.error);
+ });
+
+ // Post user activities to page.
+ router.post('/page', (req, res) => {
+ activitiesService.merge(req.user._id, req.body)
+ .then(res.api.ok)
+ .catch(res.api.error);
+ });
+
+ factoryResolve(router);
+ });
+};
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/backend/routes/admin.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/routes/admin.js b/modules/web-console/backend/routes/admin.js
index 70736d0..5b0896a 100644
--- a/modules/web-console/backend/routes/admin.js
+++ b/modules/web-console/backend/routes/admin.js
@@ -43,7 +43,7 @@ module.exports.factory = function(_, express, settings, mongo, spacesService, ma
* Get list of user accounts.
*/
router.post('/list', (req, res) => {
- usersService.list()
+ usersService.list(req.body)
.then(res.api.ok)
.catch(res.api.error);
});
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/backend/routes/agent.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/routes/agent.js b/modules/web-console/backend/routes/agent.js
index 477363f..5ae807b 100644
--- a/modules/web-console/backend/routes/agent.js
+++ b/modules/web-console/backend/routes/agent.js
@@ -21,21 +21,27 @@
module.exports = {
implements: 'routes/agents',
- inject: ['require(lodash)', 'require(express)', 'services/agents']
+ inject: ['require(lodash)', 'require(express)', 'services/agents', 'services/activities']
};
/**
* @param _
* @param express
* @param {AgentsService} agentsService
+ * @param {ActivitiesService} activitiesService
* @returns {Promise}
*/
-module.exports.factory = function(_, express, agentsService) {
+module.exports.factory = function(_, express, agentsService, activitiesService) {
return new Promise((resolveFactory) => {
const router = new express.Router();
/* Get grid topology. */
router.get('/download/zip', (req, res) => {
+ activitiesService.merge(req.user._id, {
+ group: 'agent',
+ action: '/agent/download'
+ });
+
agentsService.getArchive(req.origin(), req.user.token)
.then(({fileName, buffer}) => {
// Set the archive name.
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/backend/routes/public.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/routes/public.js b/modules/web-console/backend/routes/public.js
index 590d395..860e267 100644
--- a/modules/web-console/backend/routes/public.js
+++ b/modules/web-console/backend/routes/public.js
@@ -25,7 +25,6 @@ module.exports = {
};
/**
- *
* @param express
* @param passport
* @param mongo
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/backend/services/activities.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/services/activities.js b/modules/web-console/backend/services/activities.js
new file mode 100644
index 0000000..7f3a777
--- /dev/null
+++ b/modules/web-console/backend/services/activities.js
@@ -0,0 +1,136 @@
+/*
+ * 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: 'services/activities',
+ inject: ['require(lodash)', 'mongo']
+};
+
+/**
+ * @param _
+ * @param mongo
+ * @returns {ActivitiesService}
+ */
+module.exports.factory = (_, mongo) => {
+ class ActivitiesService {
+ /**
+ * Update page activities.
+ *
+ * @param {String} owner - User ID
+ * @param {Object} page - The page
+ * @returns {Promise.<mongo.ObjectId>} that resolve activity
+ */
+ static merge(owner, {action, group}) {
+ mongo.Account.findById(owner)
+ .then((user) => {
+ user.lastActivity = new Date();
+
+ return user.save();
+ });
+
+ const date = new Date();
+
+ date.setDate(1);
+ date.setHours(0, 0, 0, 0);
+
+ return mongo.Activities.findOne({owner, action, date}).exec()
+ .then((activity) => {
+ if (activity) {
+ activity.amount++;
+
+ return activity.save();
+ }
+
+ return mongo.Activities.create({owner, action, group, date});
+ });
+ }
+
+ /**
+ * Get user activities
+ * @param {String} owner - User ID
+ * @returns {Promise.<mongo.ObjectId>} that resolve activities
+ */
+ static listByUser(owner, {startDate, endDate}) {
+ const $match = {owner};
+
+ if (startDate)
+ $match.date = {$gte: new Date(startDate)};
+
+ if (endDate) {
+ $match.date = $match.date || {};
+ $match.date.$lt = new Date(endDate);
+ }
+
+ return mongo.Activities.find($match);
+ }
+
+ static total({startDate, endDate}) {
+ const $match = {};
+
+ if (startDate)
+ $match.date = {$gte: new Date(startDate)};
+
+ if (endDate) {
+ $match.date = $match.date || {};
+ $match.date.$lt = new Date(endDate);
+ }
+
+ return mongo.Activities.aggregate([
+ {$match},
+ {$group: {
+ _id: {owner: '$owner', group: '$group'},
+ amount: {$sum: '$amount'}
+ }}
+ ]).exec().then((data) => {
+ return _.reduce(data, (acc, { _id, amount }) => {
+ const {owner, group} = _id;
+ acc[owner] = _.merge(acc[owner] || {}, { [group]: amount });
+ return acc;
+ }, {});
+ });
+ }
+
+ static detail({startDate, endDate}) {
+ const $match = { };
+
+ if (startDate)
+ $match.date = {$gte: new Date(startDate)};
+
+ if (endDate) {
+ $match.date = $match.date || {};
+ $match.date.$lt = new Date(endDate);
+ }
+
+ return mongo.Activities.aggregate([
+ {$match},
+ {$group: {_id: {owner: '$owner', action: '$action'}, total: {$sum: '$amount'}}}
+ ]).exec().then((data) => {
+ return _.reduce(data, (acc, { _id, total }) => {
+ const {owner, action} = _id;
+ acc[owner] = _.merge(acc[owner] || {}, { [action]: total });
+ return acc;
+ }, {});
+ });
+ }
+ }
+
+ return ActivitiesService;
+};
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/backend/services/users.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/services/users.js b/modules/web-console/backend/services/users.js
index 8058b25..2dd603f 100644
--- a/modules/web-console/backend/services/users.js
+++ b/modules/web-console/backend/services/users.js
@@ -21,7 +21,7 @@
module.exports = {
implements: 'services/users',
- inject: ['require(lodash)', 'mongo', 'settings', 'services/spaces', 'services/mails', 'agent-manager', 'errors']
+ inject: ['require(lodash)', 'mongo', 'settings', 'services/spaces', 'services/mails', 'services/activities', 'agent-manager', 'errors']
};
/**
@@ -30,11 +30,12 @@ module.exports = {
* @param settings
* @param {SpacesService} spacesService
* @param {MailsService} mailsService
+ * @param {ActivitiesService} activitiesService
* @param agentMgr
* @param errors
* @returns {UsersService}
*/
-module.exports.factory = (_, mongo, settings, spacesService, mailsService, agentMgr, errors) => {
+module.exports.factory = (_, mongo, settings, spacesService, mailsService, activitiesService, agentMgr, errors) => {
const _randomString = () => {
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const possibleLen = possible.length;
@@ -143,7 +144,7 @@ module.exports.factory = (_, mongo, settings, spacesService, mailsService, agent
* Get list of user accounts and summary information.
* @returns {mongo.Account[]} - returns all accounts with counters object
*/
- static list() {
+ static list(params) {
return Promise.all([
mongo.Space.aggregate([
{$match: {demo: false}},
@@ -161,13 +162,17 @@ module.exports.factory = (_, mongo, settings, spacesService, mailsService, agent
}
}
]).exec(),
+ activitiesService.total(params),
+ activitiesService.detail(params),
mongo.Account.find({}).sort('firstName lastName').lean().exec()
])
- .then(([counters, users]) => {
+ .then(([counters, activitiesTotal, activitiesDetail, users]) => {
const countersMap = _.keyBy(counters, 'owner');
_.forEach(users, (user) => {
user.counters = _.omit(countersMap[user._id], '_id', 'owner');
+ user.activitiesTotal = activitiesTotal[user._id];
+ user.activitiesDetail = activitiesDetail[user._id];
});
return users;
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/app.config.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/app.config.js b/modules/web-console/frontend/app/app.config.js
index 7416ce9..0e85711 100644
--- a/modules/web-console/frontend/app/app.config.js
+++ b/modules/web-console/frontend/app/app.config.js
@@ -94,3 +94,12 @@ igniteConsoleCfg.config(['$dropdownProvider', ($dropdownProvider) => {
templateUrl: 'templates/dropdown.html'
});
}]);
+
+// AngularStrap dropdowns () configuration.
+igniteConsoleCfg.config(['$datepickerProvider', ($datepickerProvider) => {
+ angular.extend($datepickerProvider.defaults, {
+ autoclose: true,
+ iconLeft: 'icon-datepicker-left',
+ iconRight: 'icon-datepicker-right'
+ });
+}]);
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/app.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/app.js b/modules/web-console/frontend/app/app.js
index 4ecd9b5..9958cb5 100644
--- a/modules/web-console/frontend/app/app.js
+++ b/modules/web-console/frontend/app/app.js
@@ -16,7 +16,9 @@
*/
import '../public/stylesheets/style.scss';
-import '../app/directives/ui-grid-settings/ui-grid-settings.scss';
+import '../app/components/ui-grid-header/ui-grid-header.scss';
+import '../app/components/ui-grid-settings/ui-grid-settings.scss';
+import '../app/components/form-field-datepicker/form-field-datepicker.scss';
import './helpers/jade/mixins.jade';
import './app.config';
@@ -25,10 +27,10 @@ import './decorator/select';
import './decorator/tooltip';
import './modules/form/form.module';
-import './modules/agent/agent.module.js';
+import './modules/agent/agent.module';
import './modules/sql/sql.module';
import './modules/nodes/nodes.module';
-import './modules/Demo/Demo.module.js';
+import './modules/demo/Demo.module';
import './modules/states/signin.state';
import './modules/states/logout.state';
@@ -39,6 +41,7 @@ import './modules/states/admin.state';
import './modules/states/errors.state';
// ignite:modules
+import './core';
import './modules/user/user.module';
import './modules/branding/branding.module';
import './modules/navbar/navbar.module';
@@ -50,6 +53,9 @@ import './modules/socket.module';
import './modules/loading/loading.module';
// endignite
+// Data
+import i18n from './data/i18n';
+
// Directives.
import igniteAutoFocus from './directives/auto-focus.directive.js';
import igniteBsAffixUpdate from './directives/bs-affix-update.directive';
@@ -98,9 +104,9 @@ import defaultName from './filters/default-name.filter';
import domainsValidation from './filters/domainsValidation.filter';
import duration from './filters/duration.filter';
import hasPojo from './filters/hasPojo.filter';
+import uiGridSubcategories from './filters/uiGridSubcategories.filter';
// Controllers
-import admin from 'controllers/admin-controller';
import caches from 'controllers/caches-controller';
import clusters from 'controllers/clusters-controller';
import domains from 'controllers/domains-controller';
@@ -109,6 +115,10 @@ import profile from 'controllers/profile-controller';
import auth from './controllers/auth.controller';
import resetPassword from './controllers/reset-password.controller';
+// Components
+import igniteListOfRegisteredUsers from './components/list-of-registered-users';
+import IgniteActivitiesUserDialog from './components/activities-user-dialog';
+
// Inject external modules.
import 'ignite_modules_temp/index';
@@ -129,6 +139,7 @@ angular
'nvd3',
'smart-table',
'treeControl',
+ 'pascalprecht.translate',
'ui.grid',
'ui.grid.saveState',
'ui.grid.selection',
@@ -136,6 +147,7 @@ angular
'ui.grid.autoResize',
'ui.grid.exporter',
// Base modules.
+ 'ignite-console.core',
'ignite-console.ace',
'ignite-console.Form',
'ignite-console.user',
@@ -186,6 +198,7 @@ angular
.directive(...igniteRetainSelection)
.directive('igniteOnFocusOut', igniteOnFocusOut)
.directive('igniteRestoreInputFocus', igniteRestoreInputFocus)
+.directive('igniteListOfRegisteredUsers', igniteListOfRegisteredUsers)
// Services.
.service('IgniteErrorPopover', ErrorPopover)
.service('JavaTypes', JavaTypes)
@@ -204,8 +217,8 @@ angular
.service(...FormUtils)
.service(...LegacyUtils)
.service(...UnsavedChangesGuard)
+.service('IgniteActivitiesUserDialog', IgniteActivitiesUserDialog)
// Controllers.
-.controller(...admin)
.controller(...auth)
.controller(...resetPassword)
.controller(...caches)
@@ -219,7 +232,11 @@ angular
.filter(...domainsValidation)
.filter(...duration)
.filter(...hasPojo)
-.config(['$stateProvider', '$locationProvider', '$urlRouterProvider', ($stateProvider, $locationProvider, $urlRouterProvider) => {
+.filter('uiGridSubcategories', uiGridSubcategories)
+.config(['$translateProvider', '$stateProvider', '$locationProvider', '$urlRouterProvider', ($translateProvider, $stateProvider, $locationProvider, $urlRouterProvider) => {
+ $translateProvider.translations('en', i18n);
+ $translateProvider.preferredLanguage('en');
+
// Set up the states.
$stateProvider
.state('base', {
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/activities-user-dialog/activities-user-dialog.controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/activities-user-dialog/activities-user-dialog.controller.js b/modules/web-console/frontend/app/components/activities-user-dialog/activities-user-dialog.controller.js
new file mode 100644
index 0000000..46853b2
--- /dev/null
+++ b/modules/web-console/frontend/app/components/activities-user-dialog/activities-user-dialog.controller.js
@@ -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.
+ */
+
+const COLUMNS_DEFS = [
+ {displayName: 'Action', field: 'action', minWidth: 65 },
+ {displayName: 'Description', field: 'title', minWidth: 65 },
+ {displayName: 'Visited', field: 'amount', minWidth: 65 }
+];
+
+export default class ActivitiesCtrl {
+ static $inject = ['$state', 'user', 'params', 'IgniteActivitiesData'];
+
+ constructor($state, user, params, ActivitiesData) {
+ const $ctrl = this;
+ const userId = user._id;
+
+ $ctrl.user = user;
+
+ $ctrl.gridOptions = {
+ data: [],
+ columnVirtualizationThreshold: 30,
+ columnDefs: COLUMNS_DEFS,
+ categories: [
+ {name: 'Action', visible: true, selectable: true},
+ {name: 'Description', visible: true, selectable: true},
+ {name: 'Visited', visible: true, selectable: true}
+ ],
+ enableRowSelection: false,
+ enableRowHeaderSelection: false,
+ enableColumnMenus: false,
+ multiSelect: false,
+ modifierKeysToMultiSelect: true,
+ noUnselect: true,
+ flatEntityAccess: true,
+ fastWatch: true,
+ onRegisterApi: (api) => {
+ $ctrl.gridApi = api;
+ }
+ };
+
+ ActivitiesData.listByUser(userId, params)
+ .then((data) => {
+ $ctrl.data = data;
+ });
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/activities-user-dialog/activities-user-dialog.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/activities-user-dialog/activities-user-dialog.jade b/modules/web-console/frontend/app/components/activities-user-dialog/activities-user-dialog.jade
new file mode 100644
index 0000000..2c55ebd
--- /dev/null
+++ b/modules/web-console/frontend/app/components/activities-user-dialog/activities-user-dialog.jade
@@ -0,0 +1,36 @@
+//-
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+.modal(tabindex='-1' role='dialog')
+ .modal-dialog
+ .modal-content
+ .modal-header
+ h4.modal-title
+ i.fa.fa-info-circle
+ | Activities: {{ ctrl.user.userName }}
+ .modal-body.modal-body-with-scroll(id='activities-user-dialog')
+ table.table.table-striped.table-bordered.table-hover(scrollable-container='#activities-user-dialog' st-table='displayedRows' st-safe-src='ctrl.data')
+ thead
+ th.text-center(st-sort='title') Description
+ th.text-center(st-sort='action') Action
+ th.text-center(st-sort='amount') Visited
+ tbody
+ tr(ng-repeat='row in displayedRows')
+ td.text-left {{ row.action | translate }}
+ td.text-left {{ row.action }}
+ td.text-left {{ row.amount }}
+ .modal-footer
+ button.btn.btn-primary(id='confirm-btn-confirm' ng-click='$hide()') Close
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/activities-user-dialog/index.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/activities-user-dialog/index.js b/modules/web-console/frontend/app/components/activities-user-dialog/index.js
new file mode 100644
index 0000000..03d3585
--- /dev/null
+++ b/modules/web-console/frontend/app/components/activities-user-dialog/index.js
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ import controller from './activities-user-dialog.controller';
+ import templateUrl from './activities-user-dialog.jade';
+
+ export default ['$modal', ($modal) => ({ show = true, user, params }) => {
+ const ActivitiesUserDialog = $modal({
+ templateUrl,
+ show,
+ resolve: {
+ user: () => user,
+ params: () => params
+ },
+ placement: 'center',
+ controller,
+ controllerAs: 'ctrl'
+ });
+
+ return ActivitiesUserDialog.$promise
+ .then(() => ActivitiesUserDialog);
+ }];
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/form-field-datepicker/form-field-datepicker.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/form-field-datepicker/form-field-datepicker.jade b/modules/web-console/frontend/app/components/form-field-datepicker/form-field-datepicker.jade
new file mode 100644
index 0000000..6792977
--- /dev/null
+++ b/modules/web-console/frontend/app/components/form-field-datepicker/form-field-datepicker.jade
@@ -0,0 +1,55 @@
+//-
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+mixin ignite-form-field-datepicker(label, model, name, disabled, required, placeholder, tip)
+ mixin form-field-input()
+ input.form-control(
+ id='{{ #{name} }}Input'
+ name='{{ #{name} }}'
+
+ placeholder=placeholder
+
+ data-ng-model=model
+
+ data-ng-required=required && '#{required}'
+ data-ng-disabled=disabled && '#{disabled}'
+
+ bs-datepicker
+ data-date-format='MMM yyyy'
+ data-start-view='1'
+ data-min-view='1'
+ data-max-date='today'
+
+ data-container='body > .wrapper'
+
+ tabindex='0'
+
+ onkeydown="return false"
+
+ data-ignite-form-panel-field=''
+ )&attributes(attributes.attributes)
+
+ .ignite-form-field
+ +ignite-form-field__label(label, name, required)
+ .ignite-form-field__control
+ if tip
+ i.tipField.icon-help(bs-tooltip='' data-title=tip)
+
+ if block
+ block
+
+ .input-tip
+ +form-field-input(attributes=attributes)
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/form-field-datepicker/form-field-datepicker.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/form-field-datepicker/form-field-datepicker.scss b/modules/web-console/frontend/app/components/form-field-datepicker/form-field-datepicker.scss
new file mode 100644
index 0000000..0f6fe6e
--- /dev/null
+++ b/modules/web-console/frontend/app/components/form-field-datepicker/form-field-datepicker.scss
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+.datepicker.dropdown-menu tbody button {
+ height: 100%;
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/list-of-registered-users/index.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/list-of-registered-users/index.js b/modules/web-console/frontend/app/components/list-of-registered-users/index.js
new file mode 100644
index 0000000..32a34f4
--- /dev/null
+++ b/modules/web-console/frontend/app/components/list-of-registered-users/index.js
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import templateUrl from './list-of-registered-users.jade';
+import controller from './list-of-registered-users.controller';
+
+export default [() => {
+ return {
+ scope: true,
+ templateUrl,
+ controller,
+ controllerAs: '$ctrl'
+ };
+}];
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.categories.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.categories.js b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.categories.js
new file mode 100644
index 0000000..95edf8b
--- /dev/null
+++ b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.categories.js
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default [
+ {name: 'Actions', visible: true, selectable: true},
+ {name: 'User', visible: true, selectable: true},
+ {name: 'Email', visible: true, selectable: true},
+ {name: 'Company', visible: true, selectable: true},
+ {name: 'Country', visible: true, selectable: true},
+ {name: 'Last login', visible: false, selectable: true},
+ {name: 'Last activity', visible: true, selectable: true},
+ {name: 'Configurations', visible: false, selectable: true},
+ {name: 'Total activities', visible: true, selectable: true},
+ {name: 'Configuration\'s activities', visible: false, selectable: true},
+ {name: 'Queries\' activities', visible: false, selectable: true}
+];
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.column-defs.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.column-defs.js b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.column-defs.js
new file mode 100644
index 0000000..61e1bd8
--- /dev/null
+++ b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.column-defs.js
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const ICON_SORT = '<span ui-grid-one-bind-id-grid="col.uid + \'-sortdir-text\'" ui-grid-visible="col.sort.direction" aria-label="Sort Descending"><i ng-class="{ \'ui-grid-icon-up-dir\': col.sort.direction == asc, \'ui-grid-icon-down-dir\': col.sort.direction == desc, \'ui-grid-icon-blank\': !col.sort.direction }" title="" aria-hidden="true"></i></span>';
+
+const USER_TEMPLATE = '<div class="ui-grid-cell-contents"><i class="pull-left" ng-class="row.entity.admin ? \'icon-admin\' : \'icon-user\'"></i>{{ COL_FIELD }}</div>';
+
+const CLUSTER_HEADER_TEMPLATE = `<div class='ui-grid-cell-contents' bs-tooltip data-title='{{ col.headerTooltip(col) }}' data-placement='top'><i class='fa fa-sitemap'></i>${ICON_SORT}</div>`;
+const MODEL_HEADER_TEMPLATE = `<div class='ui-grid-cell-contents' bs-tooltip data-title='{{ col.headerTooltip(col) }}' data-placement='top'><i class='fa fa-object-group'></i>${ICON_SORT}</div>`;
+const CACHE_HEADER_TEMPLATE = `<div class='ui-grid-cell-contents' bs-tooltip data-title='{{ col.headerTooltip(col) }}' data-placement='top'><i class='fa fa-database'></i>${ICON_SORT}</div>`;
+const IGFS_HEADER_TEMPLATE = `<div class='ui-grid-cell-contents' bs-tooltip data-title='{{ col.headerTooltip(col) }}' data-placement='top'><i class='fa fa-folder-o'></i>${ICON_SORT}</div>`;
+
+const ACTIONS_TEMPLATE = `
+<div class='text-center ui-grid-cell-actions'>
+ <a class='btn btn-default dropdown-toggle' bs-dropdown='' data-placement='bottom-right' data-container='.panel'>
+ <i class='fa fa-gear'></i>
+ <span class='caret'></span>
+ </a>
+ <ul class='dropdown-menu' role='menu'>
+ <li ng-show='row.entity._id != $root.user._id'>
+ <a ng-click='grid.api.becomeUser(row.entity)'>Become this user</a>
+ </li>
+ <li ng-show='row.entity._id != $root.user._id'>
+ <a ng-click='grid.api.toggleAdmin(row.entity)' ng-if='row.entity.admin && row.entity._id !== $root.user._id'>Revoke admin</a>
+ <a ng-click='grid.api.toggleAdmin(row.entity)' ng-if='!row.entity.admin && row.entity._id !== $root.user._id'>Grant admin</a>
+ </li>
+ <li ng-show='row.entity._id != $root.user._id'>
+ <a ng-click='grid.api.removeUser(row.entity)'>Remove user</a>
+ </li>
+ <li>
+ <a ng-click='grid.api.showActivities(row.entity)'>Activity detail</a>
+ </li>
+</div>`;
+
+const EMAIL_TEMPLATE = '<div class="ui-grid-cell-contents"><a ng-href="mailto:{{ COL_FIELD }}">{{ COL_FIELD }}</a></div>';
+
+export default [
+ {displayName: 'Actions', categoryDisplayName: 'Actions', cellTemplate: ACTIONS_TEMPLATE, field: 'test', minWidth: 70, width: 70, enableFiltering: false, enableSorting: false, pinnedLeft: true},
+ {displayName: 'User', categoryDisplayName: 'User', field: 'userName', cellTemplate: USER_TEMPLATE, minWidth: 160, enableFiltering: true, filter: { placeholder: 'Filter by name...' }, pinnedLeft: true},
+ {displayName: 'Email', categoryDisplayName: 'Email', field: 'email', cellTemplate: EMAIL_TEMPLATE, minWidth: 160, enableFiltering: true, filter: { placeholder: 'Filter by email...' }},
+ {displayName: 'Company', categoryDisplayName: 'Company', field: 'company', minWidth: 160, enableFiltering: true},
+ {displayName: 'Country', categoryDisplayName: 'Country', field: 'countryCode', minWidth: 80, enableFiltering: true},
+ {displayName: 'Last login', categoryDisplayName: 'Last login', field: 'lastLogin', cellFilter: 'date:"M/d/yy HH:mm"', minWidth: 105, width: 105, enableFiltering: false, visible: false},
+ {displayName: 'Last activity', categoryDisplayName: 'Last activity', field: 'lastActivity', cellFilter: 'date:"M/d/yy HH:mm"', minWidth: 105, width: 105, enableFiltering: false, visible: true, sort: { direction: 'desc', priority: 0 }},
+ // Configurations
+ {displayName: 'Clusters count', categoryDisplayName: 'Configurations', headerCellTemplate: CLUSTER_HEADER_TEMPLATE, field: 'counters.clusters', type: 'number', headerTooltip: 'Clusters count', minWidth: 50, width: 50, enableFiltering: false, visible: false},
+ {displayName: 'Models count', categoryDisplayName: 'Configurations', headerCellTemplate: MODEL_HEADER_TEMPLATE, field: 'counters.models', type: 'number', headerTooltip: 'Models count', minWidth: 50, width: 50, enableFiltering: false, visible: false},
+ {displayName: 'Caches count', categoryDisplayName: 'Configurations', headerCellTemplate: CACHE_HEADER_TEMPLATE, field: 'counters.caches', type: 'number', headerTooltip: 'Caches count', minWidth: 50, width: 50, enableFiltering: false, visible: false},
+ {displayName: 'IGFS count', categoryDisplayName: 'Configurations', headerCellTemplate: IGFS_HEADER_TEMPLATE, field: 'counters.igfs', type: 'number', headerTooltip: 'IGFS count', minWidth: 50, width: 50, enableFiltering: false, visible: false},
+ // Activities Total
+ {displayName: 'Cfg', categoryDisplayName: 'Total activities', field: 'activitiesTotal["configuration"] || 0', type: 'number', headerTooltip: 'Configuration', minWidth: 50, width: 50, enableFiltering: false},
+ {displayName: 'Qry', categoryDisplayName: 'Total activities', field: 'activitiesTotal["queries"] || 0', type: 'number', headerTooltip: 'Queries', minWidth: 50, width: 50, enableFiltering: false},
+ {displayName: 'Demo', categoryDisplayName: 'Total activities', field: 'activitiesTotal["demo"] || 0', type: 'number', headerTooltip: 'Demo', minWidth: 50, width: 50, enableFiltering: false},
+ {displayName: 'AD', categoryDisplayName: 'Total activities', field: 'activitiesDetail["/agent/download"] || 0', type: 'number', headerTooltip: 'Agent Download', minWidth: 50, width: 50, enableFiltering: false},
+ {displayName: 'AS', categoryDisplayName: 'Total activities', field: 'activitiesDetail["/agent/start"] || 0', type: 'number', headerTooltip: 'Agent Start', minWidth: 50, width: 50, enableFiltering: false},
+ // Activities Configuration
+ {displayName: 'Clusters', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/clusters"] || 0', type: 'number', headerTooltip: 'Configuration Clusters', minWidth: 50, width: 80, enableFiltering: false, visible: false},
+ {displayName: 'Model', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/domains"] || 0', type: 'number', headerTooltip: 'Configuration Model', minWidth: 50, width: 80, enableFiltering: false, visible: false},
+ {displayName: 'Caches', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/caches"] || 0', type: 'number', headerTooltip: 'Configuration Caches', minWidth: 50, width: 80, enableFiltering: false, visible: false},
+ {displayName: 'IGFS', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/igfs"] || 0', type: 'number', headerTooltip: 'Configuration IGFS', minWidth: 50, width: 80, enableFiltering: false, visible: false},
+ {displayName: 'Summary', categoryDisplayName: 'Configuration\'s activities', field: 'activitiesDetail["/configuration/summary"] || 0', type: 'number', headerTooltip: 'Configuration Summary', minWidth: 50, width: 80, enableFiltering: false, visible: false},
+ // Activities Queries
+ {displayName: 'Execute', categoryDisplayName: 'Queries\' activities', field: 'activitiesDetail["/queries/execute"] || 0', type: 'number', headerTooltip: 'Query execute', minWidth: 50, width: 80, enableFiltering: false, visible: false},
+ {displayName: 'Explain', categoryDisplayName: 'Queries\' activities', field: 'activitiesDetail["/queries/explain"] || 0', type: 'number', headerTooltip: 'Query explain', minWidth: 50, width: 80, enableFiltering: false, visible: false},
+ {displayName: 'Scan', categoryDisplayName: 'Queries\' activities', field: 'activitiesDetail["/queries/scan"] || 0', type: 'number', headerTooltip: 'Scan', minWidth: 50, width: 80, enableFiltering: false, visible: false}
+];
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.controller.js b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.controller.js
new file mode 100644
index 0000000..19f7921
--- /dev/null
+++ b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.controller.js
@@ -0,0 +1,207 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import headerTemplate from 'app/components/ui-grid-header/ui-grid-header.jade';
+
+import columnDefs from './list-of-registered-users.column-defs';
+import categories from './list-of-registered-users.categories';
+
+export default class IgniteListOfRegisteredUsersCtrl {
+ static $inject = ['$scope', '$state', '$templateCache', 'User', 'uiGridConstants', 'IgniteAdminData', 'IgniteNotebookData', 'IgniteConfirm', 'IgniteActivitiesUserDialog'];
+
+ constructor($scope, $state, $templateCache, User, uiGridConstants, AdminData, NotebookData, Confirm, ActivitiesUserDialog) {
+ const $ctrl = this;
+
+ const companySelectOptions = [];
+ const countrySelectOptions = [];
+
+ $ctrl.params = {
+ startDate: new Date()
+ };
+
+ $ctrl.params.startDate.setDate(1);
+ $ctrl.params.startDate.setHours(0, 0, 0, 0);
+
+ const columnCompany = _.find(columnDefs, { displayName: 'Company' });
+ const columnCountry = _.find(columnDefs, { displayName: 'Country' });
+
+ columnCompany.filter = {
+ selectOptions: companySelectOptions,
+ type: uiGridConstants.filter.SELECT,
+ condition: uiGridConstants.filter.EXACT
+ };
+
+ columnCountry.filter = {
+ selectOptions: countrySelectOptions,
+ type: uiGridConstants.filter.SELECT,
+ condition: uiGridConstants.filter.EXACT
+ };
+
+ const becomeUser = (user) => {
+ AdminData.becomeUser(user._id)
+ .then(() => User.load())
+ .then(() => $state.go('base.configuration.clusters'))
+ .then(() => NotebookData.load());
+ };
+
+ const removeUser = (user) => {
+ Confirm.confirm(`Are you sure you want to remove user: "${user.userName}"?`)
+ .then(() => AdminData.removeUser(user))
+ .then(() => {
+ const i = _.findIndex($ctrl.gridOptions.data, (u) => u._id === user._id);
+
+ if (i >= 0)
+ $ctrl.gridOptions.data.splice(i, 1);
+ })
+ .then(() => $ctrl.adjustHeight($ctrl.gridOptions.data.length));
+ };
+
+ const toggleAdmin = (user) => {
+ if (user.adminChanging)
+ return;
+
+ user.adminChanging = true;
+
+ AdminData.toggleAdmin(user)
+ .then(() => user.admin = !user.admin)
+ .finally(() => user.adminChanging = false);
+ };
+
+ const showActivities = (user) => {
+ return new ActivitiesUserDialog({ user, params: $ctrl.params });
+ };
+
+ $ctrl.gridOptions = {
+ data: [],
+ columnVirtualizationThreshold: 30,
+ columnDefs,
+ categories,
+ headerTemplate: $templateCache.get(headerTemplate),
+ enableFiltering: true,
+ enableRowSelection: false,
+ enableRowHeaderSelection: false,
+ enableColumnMenus: false,
+ multiSelect: false,
+ modifierKeysToMultiSelect: true,
+ noUnselect: true,
+ fastWatch: true,
+ onRegisterApi: (api) => {
+ $ctrl.gridApi = api;
+
+ api.becomeUser = becomeUser;
+ api.removeUser = removeUser;
+ api.toggleAdmin = toggleAdmin;
+ api.showActivities = showActivities;
+ }
+ };
+
+ const usersToFilterOptions = (column) => {
+ return _.sortBy(
+ _.map(
+ _.groupBy($ctrl.gridOptions.data, (usr) => {
+ const fld = usr[column];
+
+ return _.isNil(fld) ? fld : fld.toUpperCase();
+ }),
+ (arr, value) => ({label: `${_.head(arr)[column] || 'Not set'} (${arr.length})`, value})
+ ),
+ 'value');
+ };
+
+ /**
+ * @param {{startDate: Date, endDate: Date}} params
+ */
+ const reloadUsers = (params) => {
+ AdminData.loadUsers(params)
+ .then((data) => $ctrl.gridOptions.data = data)
+ .then((data) => {
+ companySelectOptions.push(...usersToFilterOptions('company'));
+ countrySelectOptions.push(...usersToFilterOptions('countryCode'));
+
+ this.gridApi.grid.refresh();
+
+ return data;
+ })
+ .then((data) => $ctrl.adjustHeight(data.length));
+ };
+
+ $scope.$watch(() => $ctrl.params.startDate, () => {
+ const endDate = new Date($ctrl.params.startDate);
+
+ endDate.setMonth(endDate.getMonth() + 1);
+
+ $ctrl.params.endDate = endDate;
+
+ reloadUsers($ctrl.params);
+ });
+ }
+
+ adjustHeight(rows) {
+ const height = Math.min(rows, 20) * 30 + 75;
+
+ // Remove header height.
+ this.gridApi.grid.element.css('height', height + 'px');
+
+ this.gridApi.core.handleWindowResize();
+ }
+
+ _enableColumns(_categories, visible) {
+ _.forEach(_categories, (cat) => {
+ cat.visible = visible;
+
+ _.forEach(this.gridOptions.columnDefs, (col) => {
+ if (col.categoryDisplayName === cat.name)
+ col.visible = visible;
+ });
+ });
+
+ // Workaround for this.gridApi.grid.refresh() didn't return promise.
+ this.gridApi.grid.processColumnsProcessors(this.gridApi.grid.columns)
+ .then((renderableColumns) => this.gridApi.grid.setVisibleColumns(renderableColumns))
+ .then(() => this.gridApi.grid.redrawInPlace())
+ .then(() => this.gridApi.grid.refreshCanvas(true))
+ .then(() => {
+ if (visible) {
+ const categoryDisplayName = _.last(_categories).name;
+
+ const col = _.findLast(this.gridOptions.columnDefs, {categoryDisplayName});
+
+ this.gridApi.grid.scrollTo(null, col);
+ }
+ });
+ }
+
+ _selectableColumns() {
+ return _.filter(this.gridOptions.categories, (cat) => cat.selectable);
+ }
+
+ toggleColumns(category, visible) {
+ this._enableColumns([category], visible);
+ }
+
+ selectAllColumns() {
+ this._enableColumns(this._selectableColumns(), true);
+ }
+
+ clearAllColumns() {
+ this._enableColumns(this._selectableColumns(), false);
+ }
+
+ exportCsv() {
+ this.gridApi.exporter.csvExport('all', 'visible');
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.jade b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.jade
new file mode 100644
index 0000000..efed9c0
--- /dev/null
+++ b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.jade
@@ -0,0 +1,54 @@
+//-
+ 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
+include /app/components/form-field-datepicker/form-field-datepicker.jade
+
+mixin grid-settings()
+ i.fa.fa-bars(data-animation='am-flip-x' bs-dropdown='' aria-haspopup='true' aria-expanded='expanded' data-auto-close='1' data-trigger='click')
+ ul.select.dropdown-menu(role='menu')
+ li(ng-repeat='item in $ctrl.gridOptions.categories|filter:{selectable:true}')
+ a(ng-click='$ctrl.toggleColumns(item, !item.visible)')
+ i.fa.fa-check-square-o.pull-left(ng-if='item.visible')
+ i.fa.fa-square-o.pull-left(ng-if='!item.visible')
+ span {{::item.name}}
+ li.divider
+ li
+ a(ng-click='$ctrl.selectAllColumns()') Select all
+ li
+ a(ng-click='$ctrl.clearAllColumns()') Clear all
+ li.divider
+ li
+ a(ng-click='$hide()') Close
+
+.panel.panel-default
+ .panel-heading.ui-grid-settings
+ +grid-settings
+ label Total users:
+ strong {{ $ctrl.gridOptions.data.length }}
+ label Showing users:
+ strong {{ $ctrl.gridApi.grid.getVisibleRows().length }}
+ sub(ng-show='users.length === $ctrl.gridApi.grid.getVisibleRows().length') all
+ div.ui-grid-settings-dateperiod
+ form(ng-form=form novalidate)
+ -var form = 'admin'
+
+ +ignite-form-field-datepicker('Period:', '$ctrl.params.startDate', '"period"')
+
+ button.btn.btn-primary(ng-click='$ctrl.exportCsv()' bs-tooltip data-title='Export table to csv') Export
+
+ .panel-collapse
+ .grid.ui-grid--ignite(ui-grid='$ctrl.gridOptions' ui-grid-resize-columns ui-grid-selection ui-grid-exporter ui-grid-pinning)
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.jade b/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.jade
new file mode 100644
index 0000000..7e44d94
--- /dev/null
+++ b/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.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.
+
+.ui-grid-header.ui-grid-header--subcategories(role='rowgroup')
+ .ui-grid-top-panel
+ .ui-grid-header-viewport
+ .ui-grid-header-canvas
+ .ui-grid-header-cell-wrapper(ng-style='colContainer.headerCellWrapperStyle()')
+ .ui-grid-header-cell-row(role='row')
+ .ui-grid-header-span.ui-grid-header-cell.ui-grid-clearfix(ng-repeat='cat in grid.options.categories')
+ div(ng-show='(colContainer.renderedColumns|uiGridSubcategories:cat.name).length > 1')
+ .ui-grid-cell-contents {{ cat.name }}
+ .ui-grid-header-cell-row
+ .ui-grid-header-cell.ui-grid-clearfix(ng-repeat='col in (colContainer.renderedColumns|uiGridSubcategories:cat.name) track by col.uid' ui-grid-header-cell='' col='col' render-index='$index')
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.scss b/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.scss
new file mode 100644
index 0000000..c390504
--- /dev/null
+++ b/modules/web-console/frontend/app/components/ui-grid-header/ui-grid-header.scss
@@ -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.
+ */
+
+.ui-grid-header--subcategories {
+ .ui-grid-row:nth-child(even) .ui-grid-cell.cell-total {
+ background-color: rgba(102,175,233,.6);
+ }
+
+ .ui-grid-row:nth-child(odd) .ui-grid-cell.cell-total {
+ background-color: rgba(102,175,233,.3);
+ }
+
+ .ui-grid-header-cell-row {
+ height: 30px;
+ }
+
+ .ui-grid-header-cell [role="columnheader"] {
+ display: flex;
+
+ flex-wrap: wrap;
+ align-items: center;
+ justify-content: center;
+
+ height: 100%;
+
+ & > div {
+ flex: 1 100%;
+ height: auto;
+ }
+
+ & > div[ui-grid-filter] {
+ flex: auto;
+ }
+ }
+
+ .ui-grid-header-span {
+ position: relative;
+ border-right: 0;
+
+ .ng-hide + .ui-grid-header-cell-row .ui-grid-header-cell {
+ height: 58px;
+ }
+
+ .ng-hide + .ui-grid-header-cell-row .ui-grid-cell-contents {
+ padding: 5px 5px;
+ }
+
+ .ui-grid-column-resizer.right {
+ top: -100px;
+ }
+ .ng-hide + .ui-grid-header-cell-row .ui-grid-column-resizer.right {
+ bottom: -100px;
+ }
+
+ &.ui-grid-header-cell .ui-grid-header-cell .ui-grid-column-resizer.right {
+ border-right-width: 0;
+ }
+ &.ui-grid-header-cell .ui-grid-header-cell:last-child .ui-grid-column-resizer.right {
+ border-right-width: 1px;
+ }
+
+ & > div > .ui-grid-cell-contents {
+ border-bottom: 1px solid #d4d4d4;
+ }
+ }
+
+ input {
+ line-height: 21px;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/ui-grid-settings/ui-grid-settings.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/ui-grid-settings/ui-grid-settings.jade b/modules/web-console/frontend/app/components/ui-grid-settings/ui-grid-settings.jade
new file mode 100644
index 0000000..8f1487e
--- /dev/null
+++ b/modules/web-console/frontend/app/components/ui-grid-settings/ui-grid-settings.jade
@@ -0,0 +1,33 @@
+//-
+ 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 ui-grid-settings()
+ .ui-grid-settings
+ i.fa.fa-bars(data-animation='am-flip-x' bs-dropdown='' aria-haspopup='true' aria-expanded='expanded' data-auto-close='1' data-trigger='click')
+ ul.select.dropdown-menu(role='menu')
+ li(ng-repeat='item in paragraph.gridOptions.categories|filter:{selectable:true}')
+ a(ng-click='paragraph.toggleColumns(item, !item.visible)')
+ i.fa.fa-check-square-o.pull-left(ng-if='item.visible')
+ i.fa.fa-square-o.pull-left(ng-if='!item.visible')
+ span {{::item.name}}
+ li.divider
+ li
+ a(ng-click='paragraph.selectAllColumns()') Select all
+ li
+ a(ng-click='paragraph.clearAllColumns()') Clear all
+ li.divider
+ li
+ a(ng-click='$hide()') Close
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/components/ui-grid-settings/ui-grid-settings.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/ui-grid-settings/ui-grid-settings.scss b/modules/web-console/frontend/app/components/ui-grid-settings/ui-grid-settings.scss
new file mode 100644
index 0000000..3016488
--- /dev/null
+++ b/modules/web-console/frontend/app/components/ui-grid-settings/ui-grid-settings.scss
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+.ui-grid-settings {
+ ul.select.dropdown-menu > li > a {
+ padding-top: 0;
+ padding-bottom: 0;
+ }
+
+ ul.select.dropdown-menu > li > a > i {
+ position: relative;
+ line-height: 26px;
+ width: 14px;
+ margin-left: 0;
+ color: inherit;
+ }
+
+ ul.select.dropdown-menu > li > a > span {
+ line-height: 26px;
+ padding-left: 5px;
+ padding-right: 8px;
+ cursor: pointer;
+ }
+
+ &-dateperiod {
+ float: right;
+
+ .ignite-form-field {
+ width: 160px;
+ margin-right: 10px;
+
+ &__label {
+ }
+
+ &__control {
+ }
+
+ &:nth-child(1) {
+ float: left;
+
+ .ignite-form-field__label {
+ width: 40%;
+ }
+
+ .ignite-form-field__control {
+ width: 60%;
+ }
+ }
+ }
+
+ .btn {
+ line-height: 20px;
+ margin-right: 0;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/core/activities/Activities.data.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/core/activities/Activities.data.js b/modules/web-console/frontend/app/core/activities/Activities.data.js
new file mode 100644
index 0000000..8a67a97
--- /dev/null
+++ b/modules/web-console/frontend/app/core/activities/Activities.data.js
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default class ActivitiesData {
+ static $inject = ['$http', '$state'];
+
+ constructor($http, $state) {
+ this.$http = $http;
+ this.$state = $state;
+ }
+
+ post(options = {}) {
+ let { group, action } = options;
+
+ action = action || this.$state.$current.url.source;
+ group = group || action.match(/^\/([^/]+)/)[1];
+
+ return this.$http.post('/api/v1/activities/page', { group, action });
+ }
+
+ listByUser(userId, params) {
+ return this.$http.get(`/api/v1/activities/user/${userId}`, { params })
+ .then(({ data }) => data);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/core/admin/Admin.data.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/core/admin/Admin.data.js b/modules/web-console/frontend/app/core/admin/Admin.data.js
new file mode 100644
index 0000000..66d82f0
--- /dev/null
+++ b/modules/web-console/frontend/app/core/admin/Admin.data.js
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default class IgniteAdminData {
+ static $inject = ['$http', 'IgniteMessages', 'IgniteCountries'];
+
+ constructor($http, Messages, Countries) {
+ this.$http = $http;
+ this.Messages = Messages;
+ this.Countries = Countries;
+ }
+
+ becomeUser(viewedUserId) {
+ return this.$http.get('/api/v1/admin/become', {
+ params: {viewedUserId}
+ })
+ .catch(this.Messages.showError);
+ }
+
+ removeUser(user) {
+ return this.$http.post('/api/v1/admin/remove', {
+ userId: user._id
+ })
+ .then(() => {
+ this.Messages.showInfo(`User has been removed: "${user.userName}"`);
+ })
+ .catch(({data, status}) => {
+ if (status === 503)
+ this.Messages.showInfo(data);
+ else
+ this.Messages.showError('Failed to remove user: ', data);
+ });
+ }
+
+ toggleAdmin(user) {
+ return this.$http.post('/api/v1/admin/save', {
+ userId: user._id,
+ adminFlag: !user.admin
+ })
+ .then(() => {
+ this.Messages.showInfo(`Admin right was successfully toggled for user: "${user.userName}"`);
+ })
+ .catch((res) => {
+ this.Messages.showError('Failed to toggle admin right for user: ', res);
+ });
+ }
+
+ prepareUsers(user) {
+ const { Countries } = this;
+
+ user.userName = user.firstName + ' ' + user.lastName;
+ user.countryCode = Countries.getByName(user.country).code;
+
+ return user;
+ }
+
+ loadUsers(params) {
+ return this.$http.post('/api/v1/admin/list', params)
+ .then(({ data }) => data)
+ .then((users) => _.map(users, this.prepareUsers.bind(this)))
+ .catch(this.Messages.showError);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/core/index.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/core/index.js b/modules/web-console/frontend/app/core/index.js
new file mode 100644
index 0000000..7f72ee3
--- /dev/null
+++ b/modules/web-console/frontend/app/core/index.js
@@ -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.
+ */
+
+import angular from 'angular';
+
+import IgniteAdminData from './admin/Admin.data';
+import IgniteActivitiesData from './activities/Activities.data';
+
+angular.module('ignite-console.core', [])
+ .service('IgniteAdminData', IgniteAdminData)
+ .service('IgniteActivitiesData', IgniteActivitiesData);
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/data/i18n.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/data/i18n.js b/modules/web-console/frontend/app/data/i18n.js
new file mode 100644
index 0000000..bc8c700
--- /dev/null
+++ b/modules/web-console/frontend/app/data/i18n.js
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default {
+ '/agent/start': 'Agent start',
+ '/agent/download': 'Agent download',
+ '/configuration/clusters': 'Configure clusters',
+ '/configuration/caches': 'Configure caches',
+ '/configuration/domains': 'Configure domain model',
+ '/configuration/igfs': 'Configure IGFS',
+ '/configuration/summary': 'Configurations summary',
+ '/demo/resume': 'Demo resume',
+ '/demo/reset': 'Demo reset',
+ '/queries/execute': 'Query execute',
+ '/queries/explain': 'Query explain',
+ '/queries/scan': 'Scan',
+ '/queries/add/query': 'Add query',
+ '/queries/add/scan': 'Add scan',
+ '/queries/demo': 'SQL demo',
+ '/queries/notebook/': 'Query notebook',
+ '/settings/profile': 'User profile',
+ '/settings/admin': 'Admin panel',
+ '/logout': 'Logout'
+};
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.jade b/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.jade
deleted file mode 100644
index 8f1487e..0000000
--- a/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.jade
+++ /dev/null
@@ -1,33 +0,0 @@
-//-
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-mixin ui-grid-settings()
- .ui-grid-settings
- i.fa.fa-bars(data-animation='am-flip-x' bs-dropdown='' aria-haspopup='true' aria-expanded='expanded' data-auto-close='1' data-trigger='click')
- ul.select.dropdown-menu(role='menu')
- li(ng-repeat='item in paragraph.gridOptions.categories|filter:{selectable:true}')
- a(ng-click='paragraph.toggleColumns(item, !item.visible)')
- i.fa.fa-check-square-o.pull-left(ng-if='item.visible')
- i.fa.fa-square-o.pull-left(ng-if='!item.visible')
- span {{::item.name}}
- li.divider
- li
- a(ng-click='paragraph.selectAllColumns()') Select all
- li
- a(ng-click='paragraph.clearAllColumns()') Clear all
- li.divider
- li
- a(ng-click='$hide()') Close
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.scss b/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.scss
deleted file mode 100644
index 6517a60..0000000
--- a/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.scss
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-.ui-grid-settings {
- ul.select.dropdown-menu > li > a {
- padding-top: 0;
- padding-bottom: 0;
- }
-
- ul.select.dropdown-menu > li > a > i {
- position: relative;
- line-height: 26px;
- width: 14px;
- margin-left: 0;
- color: inherit;
- }
-
- ul.select.dropdown-menu > li > a > span {
- line-height: 26px;
- padding-left: 5px;
- padding-right: 8px;
- cursor: pointer;
- }
-}
http://git-wip-us.apache.org/repos/asf/ignite/blob/26ee9c28/modules/web-console/frontend/app/filters/uiGridSubcategories.filter.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/filters/uiGridSubcategories.filter.js b/modules/web-console/frontend/app/filters/uiGridSubcategories.filter.js
new file mode 100644
index 0000000..f36ae6e
--- /dev/null
+++ b/modules/web-console/frontend/app/filters/uiGridSubcategories.filter.js
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default [() => {
+ return (arr, category) => {
+ return _.filter(arr, (item) => {
+ return item.colDef.categoryDisplayName === category;
+ });
+ };
+}];