Browse Source

UI-2994: adding chart to show user roles if available

Conflicts:
	submodules/myOffice/myOffice.js
	submodules/users/users.js
4.3
Jean-Roch Maitre 8 years ago
parent
commit
2c70ea00b5
6 changed files with 162 additions and 42 deletions
  1. +40
    -3
      app.js
  2. +5
    -1
      i18n/en-US.json
  3. +35
    -3
      submodules/myOffice/myOffice.css
  4. +50
    -2
      submodules/myOffice/myOffice.js
  5. +8
    -30
      submodules/users/users.js
  6. +24
    -3
      views/myOffice-layout.html

+ 40
- 3
app.js View File

@ -29,6 +29,9 @@ define(function(require) {
requests: {}, requests: {},
subscribe: {}, subscribe: {},
appFlags: {
global: {}
},
subModules: ['devices', 'groups', 'numbers', 'strategy', 'callLogs', 'users', 'myOffice', 'featureCodes', 'vmboxes'], subModules: ['devices', 'groups', 'numbers', 'strategy', 'callLogs', 'users', 'myOffice', 'featureCodes', 'vmboxes'],
@ -54,9 +57,11 @@ define(function(require) {
parent = container || $('#monster_content'), parent = container || $('#monster_content'),
template = $(monster.template(self, 'app')); template = $(monster.template(self, 'app'));
/* On first Load, load my office */
template.find('.category#myOffice').addClass('active');
monster.pub('voip.myOffice.render', { parent: template.find('.right-content') });
self.loadGlobalData(function() {
/* On first Load, load my office */
template.find('.category#myOffice').addClass('active');
monster.pub('voip.myOffice.render', { parent: template.find('.right-content') });
});
self.bindEvents(template); self.bindEvents(template);
@ -69,6 +74,38 @@ define(function(require) {
var self = this; var self = this;
}, },
loadGlobalData: function(callback) {
var self = this;
monster.parallel({
servicePlansRole: function(callback) {
if (monster.config.hasOwnProperty('resellerId') && monster.config.resellerId.length) {
self.callApi({
resource: 'servicePlan.list',
data: {
accountId: self.accountId,
filters: {
paginate: false,
'filter_merge.strategy': 'cumulative'
}
},
success: function(data, status) {
var formattedData = _.keyBy(data.data, 'id');
callback(null, formattedData);
}
});
} else {
callback(null, {});
}
}
}, function(err, results) {
self.appFlags.global = results;
callback && callback(self.appFlags.global);
});
},
bindEvents: function(parent) { bindEvents: function(parent) {
var self = this, var self = this,
container = parent.find('.right-content'); container = parent.find('.right-content');


+ 5
- 1
i18n/en-US.json View File

@ -1130,7 +1130,11 @@
"__version": "3.23", "__version": "3.23",
"missingCnamE911Message": "Please setup your Company Caller ID and e911 on a Main Number.", "missingCnamE911Message": "Please setup your Company Caller ID and e911 on a Main Number.",
"missingCnamMessage": "Please setup your Company Caller ID on a Main Number.", "missingCnamMessage": "Please setup your Company Caller ID on a Main Number.",
"missingE911Message": "Please setup your e911 on a Main Number."
"missingE911Message": "Please setup your e911 on a Main Number.",
"userChartLegend": {
"none": "No Role"
}
}, },
"__comment": "UI-299, v3.19_s2: Added the Feature Codes tab to SmartPBX.", "__comment": "UI-299, v3.19_s2: Added the Feature Codes tab to SmartPBX.",


+ 35
- 3
submodules/myOffice/myOffice.css View File

@ -78,6 +78,9 @@
-moz-box-sizing: border-box; -moz-box-sizing: border-box;
-webkit-box-sizing: border-box; -webkit-box-sizing: border-box;
} }
#myoffice_container .dashboard-left-section {
margin-bottom: 20px;
}
#myoffice_container .dashboard-content-div.dashboard-left-content { #myoffice_container .dashboard-content-div.dashboard-left-content {
padding-right: 10px; padding-right: 10px;
} }
@ -108,9 +111,6 @@
color: #22a5ff; color: #22a5ff;
float: right; float: right;
} }
#myoffice_container .dashboard-left-content .left-section-content {
margin-bottom: 20px;
}
#myoffice_container .dashboard-left-content .users-section-content .users-element { #myoffice_container .dashboard-left-content .users-section-content .users-element {
display: inline-block; display: inline-block;
padding: 5px; padding: 5px;
@ -132,6 +132,38 @@
float: left; float: left;
} }
#myoffice_container .users-section-content {
display: block;
}
#myoffice_container .users-section-content .users-canvas-wrapper {
width: 130px;
height: 130px;
}
#myoffice_container .users-section-content .users-chart-legend {
margin-left: 150px;
margin-right: 10px;
}
#myoffice_container .users-section-content .users-chart-legend ul {
list-style: none;
margin: 0px;
}
#myoffice_container .users-section-content .users-chart-legend .legend-element {
font-size: 12px;
line-height: 18px;
}
#myoffice_container .users-section-content .users-chart-legend .legend-element.no-user {
opacity: 0.5;
}
#myoffice_container .users-section-content .users-chart-legend .legend-number {
float: right;
}
#myoffice_container .users-section-content .users-chart-legend .legend-color {
margin-right: 10px;
font-size: 14px;
}
#myoffice_container .devices-section-content .devices-chart-legend { #myoffice_container .devices-section-content .devices-chart-legend {
margin-left: 150px; margin-left: 150px;
margin-right: 10px; margin-right: 10px;


+ 50
- 2
submodules/myOffice/myOffice.js View File

@ -60,11 +60,13 @@ define(function(require) {
faxNumbers: myOfficeData.faxNumbers || [], faxNumbers: myOfficeData.faxNumbers || [],
topMessage: myOfficeData.topMessage, topMessage: myOfficeData.topMessage,
devicesList: _.toArray(myOfficeData.devicesData).sort(function(a, b) { return b.count - a.count; }), devicesList: _.toArray(myOfficeData.devicesData).sort(function(a, b) { return b.count - a.count; }),
usersList: _.toArray(myOfficeData.usersData).sort(function(a, b) { return b.count - a.count ; }),
assignedNumbersList: _.toArray(myOfficeData.assignedNumbersData).sort(function(a, b) { return b.count - a.count; }), assignedNumbersList: _.toArray(myOfficeData.assignedNumbersData).sort(function(a, b) { return b.count - a.count; }),
// numberTypesList: _.toArray(myOfficeData.numberTypesData).sort(function(a, b) { return b.count - a.count ; }), // numberTypesList: _.toArray(myOfficeData.numberTypesData).sort(function(a, b) { return b.count - a.count ; }),
classifiedNumbers: myOfficeData.classifiedNumbers, classifiedNumbers: myOfficeData.classifiedNumbers,
directoryUsers: myOfficeData.directory.users && myOfficeData.directory.users.length || 0, directoryUsers: myOfficeData.directory.users && myOfficeData.directory.users.length || 0,
directoryLink: myOfficeData.directoryLink
directoryLink: myOfficeData.directoryLink,
showUserTypes: _.size(self.appFlags.global.servicePlansRole) > 0
}, },
template = $(monster.template(self, 'myOffice-layout', dataTemplate)), template = $(monster.template(self, 'myOffice-layout', dataTemplate)),
$devicesCanvas = template.find('#dashboard_devices_chart'), $devicesCanvas = template.find('#dashboard_devices_chart'),
@ -77,6 +79,7 @@ define(function(require) {
} }
], ],
devicesDataSet = _.chain(myOfficeData.devicesData).omit('totalCount').sortBy('count').value(), devicesDataSet = _.chain(myOfficeData.devicesData).omit('totalCount').sortBy('count').value(),
usersDataSet = _.chain(myOfficeData.usersData).omit('totalCount').sortBy('count').value(),
assignedNumbersDataSet = _.chain(myOfficeData.assignedNumbersData).omit('totalCount').sortBy('count').value(), assignedNumbersDataSet = _.chain(myOfficeData.assignedNumbersData).omit('totalCount').sortBy('count').value(),
classifiedNumbersDataSet = _.chain(myOfficeData.classifiedNumbers).sortBy('count').value(), classifiedNumbersDataSet = _.chain(myOfficeData.classifiedNumbers).sortBy('count').value(),
createDoughnutCanvas = function createDoughnutCanvas($target) { createDoughnutCanvas = function createDoughnutCanvas($target) {
@ -110,6 +113,7 @@ define(function(require) {
}; };
devicesDataSet = _.isEmpty(devicesDataSet) ? emptyDataSet : devicesDataSet; devicesDataSet = _.isEmpty(devicesDataSet) ? emptyDataSet : devicesDataSet;
usersDataSet = _.isEmpty(usersDataSet) ? emptyDataSet : usersDataSet;
assignedNumbersDataSet = _.isEmpty(assignedNumbersDataSet) ? emptyDataSet : assignedNumbersDataSet; assignedNumbersDataSet = _.isEmpty(assignedNumbersDataSet) ? emptyDataSet : assignedNumbersDataSet;
classifiedNumbersDataSet = _.isEmpty(classifiedNumbersDataSet) ? emptyDataSet : classifiedNumbersDataSet; classifiedNumbersDataSet = _.isEmpty(classifiedNumbersDataSet) ? emptyDataSet : classifiedNumbersDataSet;
@ -146,6 +150,16 @@ define(function(require) {
borderWidth: 0 borderWidth: 0
}); });
if (dataTemplate.showUserTypes) {
var $usersCanvas = template.find('#dashboard_user_type_chart');
createDoughnutCanvas($usersCanvas, {
data: _.map(usersDataSet, 'count'),
backgroundColor: _.map(usersDataSet, 'color'),
borderWidth: 0
});
}
self.myOfficeCheckWalkthrough(); self.myOfficeCheckWalkthrough();
callback && callback(); callback && callback();
@ -451,6 +465,13 @@ define(function(require) {
}, },
totalCount: 0 totalCount: 0
}, },
users = {
"_unassigned": {
label: self.i18n.active().myOffice.userChartLegend.none,
count: 0,
color: self.chartColors[8]
}
},
// numberTypes = { // numberTypes = {
// local: { // local: {
// label: self.i18n.active().myOffice.numberChartLegend.local, // label: self.i18n.active().myOffice.numberChartLegend.local,
@ -475,6 +496,17 @@ define(function(require) {
registeredDevices = _.map(data.devicesStatus, function(device) { return device.device_id; }), registeredDevices = _.map(data.devicesStatus, function(device) { return device.device_id; }),
unregisteredDevices = 0; unregisteredDevices = 0;
if (_.size(self.appFlags.global.servicePlansRole) > 0) {
var i = 7; // start from the end of chart colors so all the charts don't look the same
_.each(self.appFlags.global.servicePlansRole, function(role, id) {
users[id] = {
label: role.name,
count: 0,
color: self.chartColors[i >= 1 ? i-- : 8]
};
});
}
_.each(data.numbers, function(numData, num) { _.each(data.numbers, function(numData, num) {
_.find(data.classifiers, function(classifier, classifierKey) { _.find(data.classifiers, function(classifier, classifierKey) {
if (!(classifierKey in classifierRegexes)) { if (!(classifierKey in classifierRegexes)) {
@ -540,7 +572,22 @@ define(function(require) {
}); });
_.each(data.users, function(val) { _.each(data.users, function(val) {
if (val.features.indexOf('conferencing') >= 0) {
if (val.hasOwnProperty('service') && val.service.hasOwnProperty('plans') && !_.isEmpty(val.service.plans)) {
var planId;
for (var key in val.service.plans) {
if (val.service.plans.hasOwnProperty(key)) {
planId = key;
break;
}
}
users[planId].count++;
} else {
users._unassigned.count++;
}
if (val.features.indexOf("conferencing") >= 0) {
totalConferences++; totalConferences++;
} }
}); });
@ -601,6 +648,7 @@ define(function(require) {
data.totalChannels = channelsArray.length; data.totalChannels = channelsArray.length;
data.devicesData = devices; data.devicesData = devices;
data.usersData = users;
data.assignedNumbersData = assignedNumbers; data.assignedNumbersData = assignedNumbers;
// data.numberTypesData = numberTypes; // data.numberTypesData = numberTypes;
data.totalConferences = totalConferences; data.totalConferences = totalConferences;


+ 8
- 30
submodules/users/users.js View File

@ -17,8 +17,7 @@ define(function(require) {
users: { users: {
smartPBXCallflowString: ' SmartPBX\'s Callflow', smartPBXCallflowString: ' SmartPBX\'s Callflow',
smartPBXConferenceString: ' SmartPBX Conference', smartPBXConferenceString: ' SmartPBX Conference',
smartPBXVMBoxString: '\'s VMBox',
servicePlansRole: {}
smartPBXVMBoxString: '\'s VMBox'
} }
}, },
@ -175,7 +174,7 @@ define(function(require) {
extension: dataUser.hasOwnProperty('presence_id') ? dataUser.presence_id : '', extension: dataUser.hasOwnProperty('presence_id') ? dataUser.presence_id : '',
hasFeatures: false, hasFeatures: false,
isAdmin: dataUser.priv_level === 'admin', isAdmin: dataUser.priv_level === 'admin',
showLicensedUserRoles: _.size(self.appFlags.users.servicePlansRole) > 0,
showLicensedUserRoles: _.size(self.appFlags.global.servicePlansRole) > 0,
licensedUserRole: self.i18n.active().users.licensedUserRoles.none, licensedUserRole: self.i18n.active().users.licensedUserRoles.none,
listCallerId: [], listCallerId: [],
listExtensions: [], listExtensions: [],
@ -251,8 +250,8 @@ define(function(require) {
} }
} }
if (self.appFlags.users.servicePlansRole.hasOwnProperty(planId)) {
dataUser.extra.licensedUserRole = self.appFlags.users.servicePlansRole[planId].name;
if (self.appFlags.global.servicePlansRole.hasOwnProperty(planId)) {
dataUser.extra.licensedUserRole = self.appFlags.global.servicePlansRole[planId].name;
} }
} }
@ -357,7 +356,7 @@ define(function(require) {
mapUsers = {}, mapUsers = {},
registeredDevices = _.map(data.deviceStatus, function(device) { return device.device_id; }); registeredDevices = _.map(data.deviceStatus, function(device) { return device.device_id; });
if (_.size(self.appFlags.users.servicePlansRole) > 0) {
if (_.size(self.appFlags.global.servicePlansRole) > 0) {
dataTemplate.showLicensedUserRoles = true; dataTemplate.showLicensedUserRoles = true;
} }
@ -1674,8 +1673,8 @@ define(function(require) {
arrayVMBoxes = [], arrayVMBoxes = [],
allNumbers = []; allNumbers = [];
if (_.size(self.appFlags.users.servicePlansRole) > 0) {
formattedData.licensedUserRoles = self.appFlags.users.servicePlansRole;
if (_.size(self.appFlags.global.servicePlansRole) > 0) {
formattedData.licensedUserRoles = self.appFlags.global.servicePlansRole;
} }
_.each(data.callflows, function(callflow) { _.each(data.callflows, function(callflow) {
@ -3117,7 +3116,7 @@ define(function(require) {
var self = this, var self = this,
formattedData = { formattedData = {
selectedRole: undefined, selectedRole: undefined,
availableRoles: self.appFlags.users.servicePlansRole
availableRoles: self.appFlags.global.servicePlansRole
}; };
if (user.hasOwnProperty('service') && user.service.hasOwnProperty('plans') && _.size(user.service.plans) > 0) { if (user.hasOwnProperty('service') && user.service.hasOwnProperty('plans') && _.size(user.service.plans) > 0) {
@ -4287,27 +4286,6 @@ define(function(require) {
callback(null, data.data); callback(null, data.data);
} }
}); });
},
availableLicensedUserRoles: function(callback) {
if (monster.config.hasOwnProperty('resellerId') && monster.config.resellerId.length) {
self.callApi({
resource: 'servicePlan.list',
data: {
accountId: self.accountId,
filters: {
paginate: false,
'filter_merge.strategy': 'cumulative'
}
},
success: function(data, status) {
self.appFlags.users.servicePlansRole = _.keyBy(data.data, 'id');
callback(null, self.appFlags.users.servicePlansRole);
}
});
} else {
callback(null, {});
}
} }
}, function(err, results) { }, function(err, results) {
callback && callback(results); callback && callback(results);


+ 24
- 3
views/myOffice-layout.html View File

@ -34,9 +34,30 @@
<span class="number">{{totalUsers}}</span> <span class="number">{{totalUsers}}</span>
</div> </div>
<div class="left-section-content users-section-content"> <div class="left-section-content users-section-content">
{{#times totalUsers}}
<div class="users-element"><i class="fa-2x fa fa-male{{#compare this '<' ../totalChannels}} monster-primary-color{{/compare}}"></i></div>
{{/times}}
{{#if showUserTypes}}
<div class="users-chart">
<div class="users-canvas-wrapper pull-left">
<canvas id="dashboard_user_type_chart"></canvas>
</div>
<div class="users-chart-legend">
<ul>
{{#each usersList}}
{{#if label}}
<li class="legend-element{{#unless count}} no-user{{/unless}}">
<i class="fa fa-circle legend-color" style="color: {{color}};"></i>
<span class="legend-label">{{label}}</span>
<span class="legend-number">{{count}}</span>
</li>
{{/if}}
{{/each}}
</ul>
</div>
</div>
{{else}}
{{#times totalUsers}}
<div class="users-element"><i class="fa-2x fa fa-male{{#compare this '<' ../totalChannels}} monster-primary-color{{/compare}}"></i></div>
{{/times}}
{{/if}}
</div> </div>
</div> </div>
<div class="dashboard-left-section clearfix"> <div class="dashboard-left-section clearfix">


Loading…
Cancel
Save