Browse Source

UI-2994: adding licensed service plan roles to smart pbx

Conflicts:
	i18n/en-US.json
4.3
Jean-Roch Maitre 8 years ago
parent
commit
d2db190375
7 changed files with 207 additions and 4 deletions
  1. +13
    -2
      i18n/en-US.json
  2. +21
    -0
      submodules/users/users.css
  3. +125
    -1
      submodules/users/users.js
  4. +14
    -0
      views/users-creation.html
  5. +4
    -1
      views/users-layout.html
  6. +24
    -0
      views/users-licensed-roles.html
  7. +6
    -0
      views/users-row.html

+ 13
- 2
i18n/en-US.json View File

@ -532,7 +532,10 @@
"extensions": "Extensions",
"phoneNumbers": "Phone Numbers",
"devices": "Devices",
"features": "User Features"
"features": "User Features",
"__comment": "UI-2994: add licensed user service plans as a listing category",
"__version": "4.1",
"userLicensedRoles": "User Type"
},
"toastrMessages": {
"devicesUpdated": "You successfully updated the devices assigned to {{ name }}.",
@ -746,7 +749,15 @@
"__comment": "UI-2921: Delete User new Dialog",
"__version": "4.2",
"impersonate": "Impersonate"
"impersonate": "Impersonate",
"__comment": "UI-2994: adding licensed user roles",
"__version": "4.1",
"licensedUserRoles": {
"none": "- Not Set -",
"label": "User Type",
"selectPlaceholder": "Select a User Type"
}
},
"strategy": {


+ 21
- 0
submodules/users/users.css View File

@ -192,6 +192,21 @@
width: 15%;
}
/* With 6 columns, shorter width on all other columns */
#users_container .users-grid.additional-column .grid-row .grid-cell.phone-number {
width: 18%;
}
#users_container .users-grid.additional-column .grid-row .grid-cell.devices,
#users_container .users-grid.additional-column .grid-row .grid-cell.extension {
width: 12%;
}
#users_container .users-grid.additional-column .grid-row .grid-cell.licensed-user-role {
width: 13%;
}
/* end 6th columns mode */
#users_container .user-rows .grid-row {
margin-bottom: 10px;
border-radius: 2px;
@ -269,6 +284,12 @@
margin-top: 2px;
}
/* Detail User */
#users_container .detail-user-role .user-role-wrapper {
display: inline-block;
margin-top: 15px;
}
/* Detail User */
#users_container .detail-user .user-fields {
-webkit-box-sizing: border-box;


+ 125
- 1
submodules/users/users.js View File

@ -17,7 +17,8 @@ define(function(require) {
users: {
smartPBXCallflowString: ' SmartPBX\'s Callflow',
smartPBXConferenceString: ' SmartPBX Conference',
smartPBXVMBoxString: '\'s VMBox'
smartPBXVMBoxString: '\'s VMBox',
servicePlansRole: {}
}
},
@ -174,6 +175,8 @@ define(function(require) {
extension: dataUser.hasOwnProperty('presence_id') ? dataUser.presence_id : '',
hasFeatures: false,
isAdmin: dataUser.priv_level === 'admin',
showLicensedUserRoles: _.size(self.appFlags.users.servicePlansRole) > 0,
licensedUserRole: self.i18n.active().users.licensedUserRoles.none,
listCallerId: [],
listExtensions: [],
listNumbers: [],
@ -238,6 +241,21 @@ define(function(require) {
dataUser.extra = formattedUser;
}
if (dataUser.hasOwnProperty('service') && dataUser.service.hasOwnProperty('plans') && _.size(dataUser.service.plans) > 0) {
var planId;
for (var key in dataUser.service.plans) {
if (dataUser.service.plans.hasOwnProperty(key)) {
planId = key;
break;
}
}
if (self.appFlags.users.servicePlansRole.hasOwnProperty(planId)) {
dataUser.extra.licensedUserRole = self.appFlags.users.servicePlansRole[planId].name;
}
}
dataUser.extra.countFeatures = 0;
_.each(dataUser.features, function(v) {
if (v in dataUser.extra.mapFeatures) {
@ -332,12 +350,17 @@ define(function(require) {
usersFormatListData: function(data, _sortBy) {
var self = this,
dataTemplate = {
showLicensedUserRoles: false,
existingExtensions: [],
countUsers: data.users.length
},
mapUsers = {},
registeredDevices = _.map(data.deviceStatus, function(device) { return device.device_id; });
if (_.size(self.appFlags.users.servicePlansRole) > 0) {
dataTemplate.showLicensedUserRoles = true;
}
_.each(data.users, function(user) {
mapUsers[user.id] = self.usersFormatUserData(user);
});
@ -612,6 +635,8 @@ define(function(require) {
setTimeout(function() { template.find('.search-query').focus(); });
currentUser = userId;
unassignedDevices = {};
} else if (type === 'licensed-user-role') {
currentUser = data;
}
row.find('.edit-user').append(template).slideDown(400, function() {
@ -657,6 +682,8 @@ define(function(require) {
monster.ui.mask(userTemplate.find('#extension'), 'extension');
userTemplate.find('#licensed_role').chosen({search_contains: true, width: '220px'});
monster.ui.validate(userTemplate.find('#form_user_creation'), {
rules: {
'callflow.extension': {
@ -1070,6 +1097,24 @@ define(function(require) {
$(this).blur();
});
/* Events for License Roles */
template.on('click', '.save-user-role', function() {
var planId = template.find('#licensed_role').val();
/*currentUser.service = currentUser.service || {};
currentUser.service.plans = {};
currentUser.service.plans[planId] = {
account_id: monster.config.resellerId,
overrides: {}
};*/
currentUser.extra = currentUser.extra || {};
currentUser.extra.licensedRole = planId;
self.usersUpdateUser(currentUser, function(userData) {
toastr.success(monster.template(self, '!' + toastrMessages.userUpdated, { name: userData.data.first_name + ' ' + userData.data.last_name }));
self.usersRender({ userId: userData.data.id });
});
});
/* Events for Devices in Users */
template.on('click', '.create-device', function() {
var $this = $(this),
@ -1629,6 +1674,10 @@ define(function(require) {
arrayVMBoxes = [],
allNumbers = [];
if (_.size(self.appFlags.users.servicePlansRole) > 0) {
formattedData.licensedUserRoles = self.appFlags.users.servicePlansRole;
}
_.each(data.callflows, function(callflow) {
_.each(callflow.numbers, function(number) {
if (number.length < 7) {
@ -2760,6 +2809,15 @@ define(function(require) {
delete userData.language;
}
}
if (userData.extra.hasOwnProperty('licensedRole')) {
userData.service = userData.service || {};
userData.service.plans = {};
userData.service.plans[userData.extra.licensedRole] = {
account_id: monster.config.resellerId,
overrides: {}
};
}
}
if (userData.hasOwnProperty('call_forward')) {
@ -2805,6 +2863,8 @@ define(function(require) {
self.usersGetFeaturesTemplate(userId, listUsers, callbackAfterData);
} else if (type === 'devices') {
self.usersGetDevicesTemplate(userId, callbackAfterData);
} else if (type === 'licensed-user-role') {
self.usersGetLicensedRoleTemplate(userId, callbackAfterData);
}
},
@ -3041,6 +3101,36 @@ define(function(require) {
});
});
},
usersGetLicensedRoleTemplate: function(userId, callback) {
var self = this;
self.usersGetUser(userId, function(user) {
var formattedData = self.usersFormatLicensedRolesData(user),
template = $(monster.template(self, 'users-licensed-roles', formattedData));
template.find('#licensed_role').chosen({search_contains: true, width: '220px'});
callback && callback(template, user);
});
},
usersFormatLicensedRolesData: function(user) {
var self = this,
formattedData = {
selectedRole: undefined,
availableRoles: self.appFlags.users.servicePlansRole
};
if (user.hasOwnProperty('service') && user.service.hasOwnProperty('plans') && _.size(user.service.plans) > 0) {
for (var key in user.service.plans) {
if (user.service.plans.hasOwnProperty(key)) {
formattedData.selectedRole = key;
break;
}
}
}
return formattedData;
},
usersFormatDevicesData: function(userId, data) {
var self = this,
formattedData = {
@ -3198,6 +3288,19 @@ define(function(require) {
extra: data.extra
};
if (formattedData.user.extra) {
if (formattedData.user.extra.hasOwnProperty('licensedRole')) {
formattedData.user.service = formattedData.user.service || {};
formattedData.user.service.plans = {};
formattedData.user.service.plans[formattedData.user.extra.licensedRole] = {
account_id: monster.config.resellerId,
overrides: {}
};
}
}
delete formattedData.user.extra;
return formattedData;
},
@ -4184,6 +4287,27 @@ define(function(require) {
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) {
callback && callback(results);


+ 14
- 0
views/users-creation.html View File

@ -24,6 +24,20 @@
</div>
</div>
{{/unless}}
{{#if licensedUserRoles}}
<div class="control-group">
<label for="licensed_role" class="control-label"><i class="fa fa-user"></i></label>
<div class="controls">
<select id="licensed_role" name="user.extra.licensedRole" data-placeholder="{{ i18n.users.licensedUserRoles.selectPlaceholder }}">
<option value></option>
{{#each licensedUserRoles}}
<option value="{{id}}">{{name}}</option>
{{/each}}
</select>
</div>
</div>
{{/if}}
</div>
<div>


+ 4
- 1
views/users-layout.html View File

@ -16,9 +16,12 @@
</span>
</div>
<div class="users-grid">
<div class="users-grid{{#if showLicensedUserRoles}} additional-column{{/if}}">
<div class="grid-row title">
<div class="grid-cell name">{{ i18n.users.titleGrid.users }}</div>
{{#if showLicensedUserRoles}}
<div class="grid-cell licensed-user-role">{{ i18n.users.titleGrid.userLicensedRoles }}</div>
{{/if}}
<div class="grid-cell extension">{{ i18n.users.titleGrid.extensions }}</div>
<div class="grid-cell phone-number">{{ i18n.users.titleGrid.phoneNumbers }}</div>
<div class="grid-cell devices">{{ i18n.users.titleGrid.devices }}</div>


+ 24
- 0
views/users-licensed-roles.html View File

@ -0,0 +1,24 @@
<div class="detail-user-role">
<form class="form form-horizontal user-fields" id="form_update_license_role">
<div class="user-role-wrapper">
<label for="new_password" class="control-label">{{ i18n.users.licensedUserRoles.label }}</label>
<div class="controls">
<select id="licensed_role" name="extra.licensedRole" data-placeholder="{{ i18n.users.licensedUserRoles.selectPlaceholder }}">
<option value></option>
{{#select selectedRole}}
{{#each availableRoles}}
<option value="{{id}}">{{name}}</option>
{{/each}}
{{/select}}
</select>
</div>
</div>
</form>
<div class="actions">
<div class="pull-right">
<a class="cancel-link monster-link blue" href="javascript:void(0);">{{ i18n.cancel }}</a>
<button type="button" class="monster-button monster-button-success save-user-role">{{ i18n.saveChanges }}</button>
</div>
</div>
</div>

+ 6
- 0
views/users-row.html View File

@ -1,6 +1,12 @@
<div class="grid-row" data-id="{{id}}" data-priv_level="{{priv_level}}" data-name="{{first_name}} {{last_name}}" data-search="{{first_name}} {{last_name}}{{#each extra.listCallerId}} {{formatPhoneNumber this}} {{this}}{{/each}}">
<div class="user-cells">
<div class="name grid-cell" data-type="name"><i class="{{#if extra.isAdmin}}icon-telicon-moderator monster-primary-color{{else}}icon-telicon-user monster-lightgrey{{/if}}"></i> {{ first_name }} {{ last_name }}</div>
{{#if extra.showLicensedUserRoles}}
<div class="licensed-user-role grid-cell" data-type="licensed-user-role">
{{ extra.licensedUserRole }}
</div>
{{/if}}
<div class="extension grid-cell" data-type="extensions">
{{#if extra.extension}}
{{ extra.extension }}


Loading…
Cancel
Save