diff --git a/i18n/en-US.json b/i18n/en-US.json index fb6c7cd..da906be 100644 --- a/i18n/en-US.json +++ b/i18n/en-US.json @@ -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": { diff --git a/submodules/users/users.css b/submodules/users/users.css index fcbd54a..38a9584 100644 --- a/submodules/users/users.css +++ b/submodules/users/users.css @@ -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; diff --git a/submodules/users/users.js b/submodules/users/users.js index a076986..bf57c0a 100644 --- a/submodules/users/users.js +++ b/submodules/users/users.js @@ -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); diff --git a/views/users-creation.html b/views/users-creation.html index 333bc15..f894fc3 100644 --- a/views/users-creation.html +++ b/views/users-creation.html @@ -24,6 +24,20 @@ {{/unless}} + + {{#if licensedUserRoles}} +