Browse Source

UI-2689: Handle combo key behavior, add `line` action (#23)

* OOB: Enforce ESLint rules

* UI-2689: Allow combo keys to be defined as line keys

* UI-2689: Show warning message on first combo key
4.3
Joris Tirado 9 years ago
committed by GitHub
parent
commit
82fe62b963
4 changed files with 231 additions and 198 deletions
  1. +3
    -0
      i18n/en-US.json
  2. +14
    -0
      submodules/devices/devices.css
  3. +189
    -197
      submodules/devices/devices.js
  4. +25
    -1
      views/devices-sip_device.html

+ 3
- 0
i18n/en-US.json View File

@ -261,6 +261,7 @@
"__comment": "UI-1351: Add ability to configure feature keys for SIP devices in SmartPBX", "__comment": "UI-1351: Add ability to configure feature keys for SIP devices in SmartPBX",
"__version": "v3.20_s4", "__version": "v3.20_s4",
"keys": { "keys": {
"alertMessage": "By default, this key will be used as a Line Key and we recommend you not to change it.",
"featureKeys": { "featureKeys": {
"title": "Feature Keys", "title": "Feature Keys",
"label": "Feature key" "label": "Feature key"
@ -280,6 +281,7 @@
"hideInfo": "Hide Info" "hideInfo": "Hide Info"
}, },
"types": { "types": {
"line": "Use as a line key.",
"presence": "Indicate when a user has an incoming call or is on the phone. The indicator can be used to pick up ringing calls or speed dial that user.", "presence": "Indicate when a user has an incoming call or is on the phone. The indicator can be used to pick up ringing calls or speed dial that user.",
"parking": "Indicate when a call is placed on a parking slot available to the entire company. The indicator can be used to transfer a call to the parking slot or retrieve a parked call.", "parking": "Indicate when a call is placed on a parking slot available to the entire company. The indicator can be used to transfer a call to the parking slot or retrieve a parked call.",
"personal_parking": "Indicate when a call is placed on a parking slot dedicated to the selected user. The indicator can be used to transfer a call to the parking slot or retrieve a parked call.", "personal_parking": "Indicate when a call is placed on a parking slot dedicated to the selected user. The indicator can be used to transfer a call to the parking slot or retrieve a parked call.",
@ -287,6 +289,7 @@
} }
}, },
"types": { "types": {
"line": "Line",
"none": "None", "none": "None",
"presence": "Presence", "presence": "Presence",
"parking": "Parking", "parking": "Parking",


+ 14
- 0
submodules/devices/devices.css View File

@ -275,6 +275,20 @@
margin-right: 15px; margin-right: 15px;
} }
.voip-edit-device-popup .edit-device .content .tabs-section.keys {
padding: 0 20px;
}
.voip-edit-device-popup .edit-device .content .tabs-section.keys .control-group.error {
padding: 10px 0;
border: 1px dashed red;
border-radius: 2px;
}
.voip-edit-device-popup .edit-device .content .tabs-section.keys .control-group.error .alert {
margin: 0 10px 10px;
}
.voip-edit-device-popup .edit-device .content .tabs-section .title { .voip-edit-device-popup .edit-device .content .tabs-section .title {
color: #22a5ff; color: #22a5ff;
font-size: 24px; font-size: 24px;


+ 189
- 197
submodules/devices/devices.js View File

@ -1,4 +1,4 @@
define(function(require){
define(function(require) {
var $ = require('jquery'), var $ = require('jquery'),
_ = require('underscore'), _ = require('underscore'),
monster = require('monster'), monster = require('monster'),
@ -52,7 +52,7 @@ define(function(require){
.empty() .empty()
.append(template); .append(template);
if(_deviceId) {
if (_deviceId) {
var row = parent.find('.grid-row[data-id=' + _deviceId + ']'); var row = parent.find('.grid-row[data-id=' + _deviceId + ']');
monster.ui.highlight(row, { monster.ui.highlight(row, {
@ -60,7 +60,7 @@ define(function(require){
}); });
} }
if ( dataTemplate.devices.length === 0 ) {
if (dataTemplate.devices.length === 0) {
parent.find('.no-devices-row').css('display', 'block'); parent.find('.no-devices-row').css('display', 'block');
} else { } else {
parent.find('.no-devices-row').css('display', 'none'); parent.find('.no-devices-row').css('display', 'none');
@ -86,7 +86,7 @@ define(function(require){
row.data('search').toLowerCase().indexOf(searchString) < 0 ? row.hide() : row.show(); row.data('search').toLowerCase().indexOf(searchString) < 0 ? row.hide() : row.show();
}); });
if(rows.size() > 0) {
if (rows.size() > 0) {
rows.is(':visible') ? emptySearch.hide() : emptySearch.show(); rows.is(':visible') ? emptySearch.hide() : emptySearch.show();
} }
}); });
@ -105,12 +105,12 @@ define(function(require){
var classStatus = 'disabled'; var classStatus = 'disabled';
if(dataDevice.enabled === true) {
if (dataDevice.enabled === true) {
classStatus = 'unregistered'; classStatus = 'unregistered';
_.each(data.devices, function(device) { _.each(data.devices, function(device) {
if(device.id === dataDevice.id) {
if(device.registered === true) {
if (device.id === dataDevice.id) {
if (device.registered === true) {
classStatus = 'registered'; classStatus = 'registered';
} }
@ -138,9 +138,12 @@ define(function(require){
isRegistered: $this.parents('.grid-row').data('registered') === true isRegistered: $this.parents('.grid-row').data('registered') === true
}; };
self.devicesRenderEdit({ data: dataDevice, callbackSave: function(dataDevice) {
self.devicesRender({ deviceId: dataDevice.id });
}});
self.devicesRenderEdit({
data: dataDevice,
callbackSave: function(dataDevice) {
self.devicesRender({ deviceId: dataDevice.id });
}
});
}); });
template.find('.create-device').on('click', function() { template.find('.create-device').on('click', function() {
@ -185,7 +188,7 @@ define(function(require){
if (keyTypes) { if (keyTypes) {
self.devicesListUsers({ self.devicesListUsers({
success: function(users) { success: function(users) {
_.each(keyTypes, function(type, idx) {
_.each(keyTypes, function(type) {
if (!dataDevice.provision.hasOwnProperty(type)) { if (!dataDevice.provision.hasOwnProperty(type)) {
dataDevice.provision[type] = {}; dataDevice.provision[type] = {};
} }
@ -196,7 +199,7 @@ define(function(require){
if (!dataDevice.provision[type].hasOwnProperty(i)) { if (!dataDevice.provision[type].hasOwnProperty(i)) {
dataDevice.provision[type][i] = { dataDevice.provision[type][i] = {
type: 'none' type: 'none'
}
};
} }
} }
}); });
@ -233,7 +236,7 @@ define(function(require){
} }
}; };
_.each(keyTypes, function(key, idx) {
_.each(keyTypes, function(key) {
var camelCaseKey = self.devicesSnakeToCamel(key); var camelCaseKey = self.devicesSnakeToCamel(key);
extra.provision.keys.push({ extra.provision.keys.push({
@ -250,15 +253,13 @@ define(function(require){
self.devicesRenderDevice(dataDevice, callbackSave, callbackDelete); self.devicesRenderDevice(dataDevice, callbackSave, callbackDelete);
} }
}); });
}
else {
} else {
self.devicesRenderDevice(dataDevice, callbackSave, callbackDelete); self.devicesRenderDevice(dataDevice, callbackSave, callbackDelete);
} }
}, function() { }, function() {
self.devicesRenderDevice(dataDevice, callbackSave, callbackDelete); self.devicesRenderDevice(dataDevice, callbackSave, callbackDelete);
}); });
}
else {
} else {
self.devicesRenderDevice(dataDevice, callbackSave, callbackDelete); self.devicesRenderDevice(dataDevice, callbackSave, callbackDelete);
} }
}); });
@ -272,7 +273,7 @@ define(function(require){
device_type: type device_type: type
}; };
if(type === 'sip_device' && monster.config.api.provisioner) {
if (type === 'sip_device' && monster.config.api.provisioner) {
monster.pub('common.chooseModel.render', { monster.pub('common.chooseModel.render', {
callback: function(dataModel, callbackCommonSuccess) { callback: function(dataModel, callbackCommonSuccess) {
self.callApi({ self.callApi({
@ -289,16 +290,21 @@ define(function(require){
}); });
}, },
callbackMissingBrand: function() { callbackMissingBrand: function() {
self.devicesRenderEdit({ data: data, callbackSave: function(dataDevice) {
callback && callback(dataDevice);
}});
self.devicesRenderEdit({
data: data,
callbackSave: function(dataDevice) {
callback && callback(dataDevice);
}
});
}
});
} else {
self.devicesRenderEdit({
data: data,
callbackSave: function(dataDevice) {
callback && callback(dataDevice);
} }
}); });
}
else {
self.devicesRenderEdit({ data: data, callbackSave: function(dataDevice) {
callback && callback(dataDevice);
}});
} }
}, },
@ -307,14 +313,14 @@ define(function(require){
mode = data.id ? 'edit' : 'add', mode = data.id ? 'edit' : 'add',
type = data.device_type, type = data.device_type,
popupTitle = mode === 'edit' ? monster.template(self, '!' + self.i18n.active().devices[type].editTitle, { name: data.name }) : self.i18n.active().devices[type].addTitle, popupTitle = mode === 'edit' ? monster.template(self, '!' + self.i18n.active().devices[type].editTitle, { name: data.name }) : self.i18n.active().devices[type].addTitle,
templateDevice = $(monster.template(self, 'devices-'+type, $.extend(true, {}, data, {
templateDevice = $(monster.template(self, 'devices-' + type, $.extend(true, {}, data, {
isProvisionerConfigured: monster.config.api.hasOwnProperty('provisioner'), isProvisionerConfigured: monster.config.api.hasOwnProperty('provisioner'),
showEmergencyCnam: monster.util.isNumberFeatureEnabled('cnam') && monster.util.isNumberFeatureEnabled('e911') showEmergencyCnam: monster.util.isNumberFeatureEnabled('cnam') && monster.util.isNumberFeatureEnabled('e911')
}))), }))),
deviceForm = templateDevice.find('#form_device'); deviceForm = templateDevice.find('#form_device');
if (data.extra.hasOwnProperty('provision') && data.extra.provision.hasOwnProperty('keys')) { if (data.extra.hasOwnProperty('provision') && data.extra.provision.hasOwnProperty('keys')) {
_.each(data.extra.provision.keys, function(value, idx) {
_.each(data.extra.provision.keys, function(value) {
var section = '.tabs-section[data-section="' + value.type + '"] '; var section = '.tabs-section[data-section="' + value.type + '"] ';
_.each(value.data, function(val, key) { _.each(value.data, function(val, key) {
@ -337,10 +343,10 @@ define(function(require){
}); });
} }
if ( data.extra.hasE911Numbers ) {
if (data.extra.hasE911Numbers) {
var currentNumber; var currentNumber;
if(data.caller_id && data.caller_id.emergency && data.caller_id.emergency.number) {
if (data.caller_id && data.caller_id.emergency && data.caller_id.emergency.number) {
currentNumber = data.caller_id.emergency.number; currentNumber = data.caller_id.emergency.number;
self.devicesGetE911NumberAddress(data.caller_id.emergency.number, function(address) { self.devicesGetE911NumberAddress(data.caller_id.emergency.number, function(address) {
templateDevice templateDevice
@ -392,11 +398,11 @@ define(function(require){
ignore: '' // Do not ignore hidden fields ignore: '' // Do not ignore hidden fields
}); });
if($.inArray(type, ['sip_device', 'smartphone', 'mobile', 'softphone', 'fax', 'ata']) > -1) {
if ($.inArray(type, ['sip_device', 'smartphone', 'mobile', 'softphone', 'fax', 'ata']) > -1) {
var audioCodecs = monster.ui.codecSelector('audio', templateDevice.find('#audio_codec_selector'), data.media.audio.codecs); var audioCodecs = monster.ui.codecSelector('audio', templateDevice.find('#audio_codec_selector'), data.media.audio.codecs);
} }
if($.inArray(type, ['sip_device', 'smartphone', 'mobile', 'softphone']) > -1) {
if ($.inArray(type, ['sip_device', 'smartphone', 'mobile', 'softphone']) > -1) {
var videoCodecs = monster.ui.codecSelector('video', templateDevice.find('#video_codec_selector'), data.media.video.codecs); var videoCodecs = monster.ui.codecSelector('video', templateDevice.find('#video_codec_selector'), data.media.video.codecs);
} }
@ -408,7 +414,7 @@ define(function(require){
monster.ui.mask(templateDevice.find('[name="call_forward.number"]'), 'phoneNumber'); monster.ui.mask(templateDevice.find('[name="call_forward.number"]'), 'phoneNumber');
templateDevice.find('.chosen-feature-key-user').chosen({ search_contains: true, width: 'inherit' }); templateDevice.find('.chosen-feature-key-user').chosen({ search_contains: true, width: 'inherit' });
if(!(data.media.encryption.enforce_security)) {
if (!(data.media.encryption.enforce_security)) {
templateDevice.find('#rtp_method').hide(); templateDevice.find('#rtp_method').hide();
} }
@ -417,7 +423,7 @@ define(function(require){
}); });
templateDevice.find('#restart_device').on('click', function() { templateDevice.find('#restart_device').on('click', function() {
if(!$(this).hasClass('disabled')) {
if (!$(this).hasClass('disabled')) {
self.devicesRestart(data.id, function() { self.devicesRestart(data.id, function() {
toastr.success(self.i18n.active().devices.popupSettings.miscellaneous.restart.success); toastr.success(self.i18n.active().devices.popupSettings.miscellaneous.restart.success);
}); });
@ -425,13 +431,13 @@ define(function(require){
}); });
templateDevice.find('#unlock_device').on('click', function() { templateDevice.find('#unlock_device').on('click', function() {
self.devicesUnlock(data.mac_address.replace(/\:/g, ''), function() {
self.devicesUnlock(data.mac_address.replace(/:/g, ''), function() {
toastr.success(self.i18n.active().devices.popupSettings.miscellaneous.unlock.success); toastr.success(self.i18n.active().devices.popupSettings.miscellaneous.unlock.success);
}); });
}); });
templateDevice.find('.actions .save').on('click', function() { templateDevice.find('.actions .save').on('click', function() {
if(monster.ui.valid(deviceForm)) {
if (monster.ui.valid(deviceForm)) {
templateDevice.find('.feature-key-value:not(.active)').remove(); templateDevice.find('.feature-key-value:not(.active)').remove();
var dataToSave = self.devicesMergeData(data, templateDevice, audioCodecs, videoCodecs); var dataToSave = self.devicesMergeData(data, templateDevice, audioCodecs, videoCodecs);
@ -479,8 +485,7 @@ define(function(require){
}); });
divAddress.slideDown(); divAddress.slideDown();
}
else {
} else {
divAddress.slideUp(); divAddress.slideUp();
} }
}); });
@ -492,10 +497,9 @@ define(function(require){
templateDevice.find('.restriction-matcher-button').on('click', function(e) { templateDevice.find('.restriction-matcher-button').on('click', function(e) {
e.preventDefault(); e.preventDefault();
var number = templateDevice.find('.restriction-matcher-input').val(),
matched = false;
var number = templateDevice.find('.restriction-matcher-input').val();
if(number) {
if (number) {
self.callApi({ self.callApi({
resource: 'numbers.matchClassifier', resource: 'numbers.matchClassifier',
data: { data: {
@ -503,35 +507,35 @@ define(function(require){
phoneNumber: encodeURIComponent(number) phoneNumber: encodeURIComponent(number)
}, },
success: function(data, status) { success: function(data, status) {
var matchedLine = templateDevice.find('.restriction-line[data-restriction="'+data.data.name+'"]'),
var matchedLine = templateDevice.find('.restriction-line[data-restriction="' + data.data.name + '"]'),
matchedSign = matchedLine.find('.restriction-matcher-sign'), matchedSign = matchedLine.find('.restriction-matcher-sign'),
matchedMsg = templateDevice.find('.restriction-message'); matchedMsg = templateDevice.find('.restriction-message');
templateDevice.find('.restriction-matcher-sign').hide(); templateDevice.find('.restriction-matcher-sign').hide();
if(matchedLine.find('.restrictions-switch').prop('checked')) {
matchedSign.removeClass('monster-red fa-times')
.addClass('monster-green fa-check')
.css('display', 'inline-block');
matchedMsg.removeClass('red-box')
.addClass('green-box')
.css('display', 'inline-block')
.empty()
.text(
monster.template(self, '!' + self.i18n.active().devices.popupSettings.restrictions.matcher.allowMessage, { phoneNumber: monster.util.formatPhoneNumber(number) })
);
if (matchedLine.find('.restrictions-switch').prop('checked')) {
matchedSign
.removeClass('monster-red fa-times')
.addClass('monster-green fa-check')
.css('display', 'inline-block');
matchedMsg
.removeClass('red-box')
.addClass('green-box')
.css('display', 'inline-block')
.empty()
.text(monster.template(self, '!' + self.i18n.active().devices.popupSettings.restrictions.matcher.allowMessage, { phoneNumber: monster.util.formatPhoneNumber(number) }));
} else { } else {
matchedSign.removeClass('monster-green fa-check')
.addClass('monster-red fa-times')
.css('display', 'inline-block');
matchedMsg.removeClass('green-box')
.addClass('red-box')
.css('display', 'inline-block')
.empty()
.text(
monster.template(self, '!' + self.i18n.active().devices.popupSettings.restrictions.matcher.denyMessage, { phoneNumber: monster.util.formatPhoneNumber(number) })
);
matchedSign
.removeClass('monster-green fa-check')
.addClass('monster-red fa-times')
.css('display', 'inline-block');
matchedMsg
.removeClass('green-box')
.addClass('red-box')
.css('display', 'inline-block')
.empty()
.text(monster.template(self, '!' + self.i18n.active().devices.popupSettings.restrictions.matcher.denyMessage, { phoneNumber: monster.util.formatPhoneNumber(number) }));
} }
} }
}); });
@ -603,11 +607,11 @@ define(function(require){
hasRTP = $.inArray(originalData.device_type, ['sip_device', 'mobile', 'softphone']) > -1, hasRTP = $.inArray(originalData.device_type, ['sip_device', 'mobile', 'softphone']) > -1,
formData = monster.ui.getFormData('form_device'); formData = monster.ui.getFormData('form_device');
if('mac_address' in formData) {
if ('mac_address' in formData) {
formData.mac_address = monster.util.formatMacAddress(formData.mac_address); formData.mac_address = monster.util.formatMacAddress(formData.mac_address);
} }
if(hasCallForward) {
if (hasCallForward) {
formData.call_forward = $.extend(true, { formData.call_forward = $.extend(true, {
enabled: true, enabled: true,
require_keypress: true, require_keypress: true,
@ -618,12 +622,12 @@ define(function(require){
formData.call_forward.failover = true; formData.call_forward.failover = true;
} }
if(formData.hasOwnProperty('extra') && formData.extra.allowVMCellphone) {
if (formData.hasOwnProperty('extra') && formData.extra.allowVMCellphone) {
formData.call_forward.require_keypress = !formData.extra.allowVMCellphone; formData.call_forward.require_keypress = !formData.extra.allowVMCellphone;
} }
} }
if(hasCodecs) {
if (hasCodecs) {
formData.media = $.extend(true, { formData.media = $.extend(true, {
audio: { audio: {
codecs: [] codecs: []
@ -634,7 +638,7 @@ define(function(require){
}, formData.media); }, formData.media);
} }
if(hasSIP) {
if (hasSIP) {
formData.sip = $.extend(true, { formData.sip = $.extend(true, {
expire_seconds: 360, expire_seconds: 360,
invite_format: 'username', invite_format: 'username',
@ -642,10 +646,10 @@ define(function(require){
}, formData.sip); }, formData.sip);
} }
if('call_restriction' in formData) {
if ('call_restriction' in formData) {
_.each(formData.call_restriction, function(restriction, key) { _.each(formData.call_restriction, function(restriction, key) {
if(key in originalData.extra.restrictions && originalData.extra.restrictions[key].disabled) {
restriction.action = originalData.extra.restrictions[key].action
if (key in originalData.extra.restrictions && originalData.extra.restrictions[key].disabled) {
restriction.action = originalData.extra.restrictions[key].action;
} else { } else {
restriction.action = restriction.action === true ? 'inherit' : 'deny'; restriction.action = restriction.action === true ? 'inherit' : 'deny';
} }
@ -668,8 +672,7 @@ define(function(require){
if (_.isEmpty(keys)) { if (_.isEmpty(keys)) {
delete originalData.provision[key]; delete originalData.provision[key];
}
else {
} else {
originalData.provision[key] = keys; originalData.provision[key] = keys;
} }
}); });
@ -680,42 +683,42 @@ define(function(require){
var mergedData = $.extend(true, {}, originalData, formData); var mergedData = $.extend(true, {}, originalData, formData);
/* The extend doesn't override an array if the new array is empty, so we need to run these snippet after the merge */ /* The extend doesn't override an array if the new array is empty, so we need to run these snippet after the merge */
if(hasRTP) {
if (hasRTP) {
mergedData.media.encryption.methods = []; mergedData.media.encryption.methods = [];
if(mergedData.media.encryption.enforce_security) {
if (mergedData.media.encryption.enforce_security) {
mergedData.media.encryption.methods.push(formData.extra.rtpMethod); mergedData.media.encryption.methods.push(formData.extra.rtpMethod);
} }
} }
if(mergedData.extra.hasOwnProperty('notify_unregister')) {
if (mergedData.extra.hasOwnProperty('notify_unregister')) {
mergedData.suppress_unregister_notifications = !mergedData.extra.notify_unregister; mergedData.suppress_unregister_notifications = !mergedData.extra.notify_unregister;
} }
if(hasCodecs) {
if(audioCodecs) {
if (hasCodecs) {
if (audioCodecs) {
mergedData.media.audio.codecs = audioCodecs.getSelectedItems(); mergedData.media.audio.codecs = audioCodecs.getSelectedItems();
} }
if(videoCodecs) {
if (videoCodecs) {
mergedData.media.video.codecs = videoCodecs.getSelectedItems(); mergedData.media.video.codecs = videoCodecs.getSelectedItems();
} }
} }
// If the key is set to "auto" we remove the key, we don't support this anymore // If the key is set to "auto" we remove the key, we don't support this anymore
if(mergedData.hasOwnProperty('media') && mergedData.media.hasOwnProperty('fax_option') && mergedData.media.fax_option === 'auto') {
if (mergedData.hasOwnProperty('media') && mergedData.media.hasOwnProperty('fax_option') && mergedData.media.fax_option === 'auto') {
delete mergedData.media.fax_option; delete mergedData.media.fax_option;
} }
// The UI mistakenly created this key, so we clean it up // The UI mistakenly created this key, so we clean it up
if(mergedData.hasOwnProperty('media') && mergedData.media.hasOwnProperty('fax') && mergedData.media.fax.hasOwnProperty('option')) {
if (mergedData.hasOwnProperty('media') && mergedData.media.hasOwnProperty('fax') && mergedData.media.fax.hasOwnProperty('option')) {
delete mergedData.media.fax.option; delete mergedData.media.fax.option;
} }
if(mergedData.hasOwnProperty('caller_id') && mergedData.caller_id.hasOwnProperty('emergency') && mergedData.caller_id.emergency.hasOwnProperty('number') && mergedData.caller_id.emergency.number === '') {
if (mergedData.hasOwnProperty('caller_id') && mergedData.caller_id.hasOwnProperty('emergency') && mergedData.caller_id.emergency.hasOwnProperty('number') && mergedData.caller_id.emergency.number === '') {
delete mergedData.caller_id.emergency.number; delete mergedData.caller_id.emergency.number;
if(_.isEmpty(mergedData.caller_id.emergency)) {
if (_.isEmpty(mergedData.caller_id.emergency)) {
delete mergedData.caller_id.emergency; delete mergedData.caller_id.emergency;
} }
} }
@ -749,7 +752,7 @@ define(function(require){
enabled: true, enabled: true,
media: { media: {
encryption: { encryption: {
enforce_security: false,
enforce_security: false
}, },
audio: { audio: {
codecs: ['PCMU', 'PCMA'] codecs: ['PCMU', 'PCMA']
@ -784,7 +787,7 @@ define(function(require){
}, },
contact_list: { contact_list: {
exclude: true exclude: true
},
}
}, },
ata: { ata: {
sip: { sip: {
@ -842,25 +845,24 @@ define(function(require){
} }
} }
}; };
_.each(data.listClassifiers, function(restriction, name) { _.each(data.listClassifiers, function(restriction, name) {
if(name in self.i18n.active().devices.classifiers) {
if (name in self.i18n.active().devices.classifiers) {
defaults.extra.restrictions[name].friendly_name = self.i18n.active().devices.classifiers[name].name; defaults.extra.restrictions[name].friendly_name = self.i18n.active().devices.classifiers[name].name;
if('help' in self.i18n.active().devices.classifiers[name]) {
if ('help' in self.i18n.active().devices.classifiers[name]) {
defaults.extra.restrictions[name].help = self.i18n.active().devices.classifiers[name].help; defaults.extra.restrictions[name].help = self.i18n.active().devices.classifiers[name].help;
} }
} }
if('call_restriction' in data.accountLimits && name in data.accountLimits.call_restriction && data.accountLimits.call_restriction[name].action === 'deny') {
if ('call_restriction' in data.accountLimits && name in data.accountLimits.call_restriction && data.accountLimits.call_restriction[name].action === 'deny') {
defaults.extra.restrictions[name].disabled = true; defaults.extra.restrictions[name].disabled = true;
defaults.extra.hasDisabledRestrictions = true; defaults.extra.hasDisabledRestrictions = true;
} }
if('call_restriction' in data.device && name in data.device.call_restriction) {
if ('call_restriction' in data.device && name in data.device.call_restriction) {
defaults.extra.restrictions[name].action = data.device.call_restriction[name].action; defaults.extra.restrictions[name].action = data.device.call_restriction[name].action;
}
else {
} else {
defaults.extra.restrictions[name].action = 'inherit'; defaults.extra.restrictions[name].action = 'inherit';
} }
}); });
@ -869,18 +871,18 @@ define(function(require){
/* Audio Codecs*/ /* Audio Codecs*/
/* extend doesn't replace the array so we need to do it manually */ /* extend doesn't replace the array so we need to do it manually */
if(data.device.media && data.device.media.audio && data.device.media.audio.codecs) {
if (data.device.media && data.device.media.audio && data.device.media.audio.codecs) {
formattedData.media.audio.codecs = data.device.media.audio.codecs; formattedData.media.audio.codecs = data.device.media.audio.codecs;
} }
/* Video codecs */ /* Video codecs */
if(data.device.media && data.device.media.video && data.device.media.video.codecs) {
if (data.device.media && data.device.media.video && data.device.media.video.codecs) {
formattedData.media.video.codecs = data.device.media.video.codecs; formattedData.media.video.codecs = data.device.media.video.codecs;
} }
formattedData.extra.isRegistered = dataList.isRegistered; formattedData.extra.isRegistered = dataList.isRegistered;
if(formattedData.hasOwnProperty('call_forward') && formattedData.call_forward.hasOwnProperty('require_keypress')) {
if (formattedData.hasOwnProperty('call_forward') && formattedData.call_forward.hasOwnProperty('require_keypress')) {
formattedData.extra.allowVMCellphone = !formattedData.call_forward.require_keypress; formattedData.extra.allowVMCellphone = !formattedData.call_forward.require_keypress;
} }
@ -931,17 +933,17 @@ define(function(require){
classStatus: device.enabled ? 'unregistered' : 'disabled' /* Display a device in black if it's disabled, otherwise, until we know whether it's registered or not, we set the color to red */, classStatus: device.enabled ? 'unregistered' : 'disabled' /* Display a device in black if it's disabled, otherwise, until we know whether it's registered or not, we set the color to red */,
isRegistered: false, isRegistered: false,
sipUserName: device.username sipUserName: device.username
}
};
}); });
_.each(data.status, function(status) { _.each(data.status, function(status) {
if(status.registered === true && status.device_id in formattedData.devices) {
if (status.registered === true && status.device_id in formattedData.devices) {
var device = formattedData.devices[status.device_id]; var device = formattedData.devices[status.device_id];
device.registered = true; device.registered = true;
/* Now that we know if it's registered, we set the color to green */ /* Now that we know if it's registered, we set the color to green */
if(device.enabled) {
if (device.enabled) {
device.classStatus = 'registered'; device.classStatus = 'registered';
device.isRegistered = true; device.isRegistered = true;
} }
@ -956,21 +958,18 @@ define(function(require){
arrayToSort.sort(function(a, b) { arrayToSort.sort(function(a, b) {
/* If owner is the same, order by device name */ /* If owner is the same, order by device name */
if(a.userName === b.userName) {
if (a.userName === b.userName) {
var aName = a.name.toLowerCase(), var aName = a.name.toLowerCase(),
bName = b.name.toLowerCase(); bName = b.name.toLowerCase();
return (aName > bName) ? 1 : (aName < bName) ? -1 : 0; return (aName > bName) ? 1 : (aName < bName) ? -1 : 0;
}
else {
} else {
/* Otherwise, push the unassigned devices to the bottom of the list, and show the assigned devices ordered by user name */ /* Otherwise, push the unassigned devices to the bottom of the list, and show the assigned devices ordered by user name */
if(a.userName === unassignedString) {
if (a.userName === unassignedString) {
return 1; return 1;
}
else if(b.userName === unassignedString) {
} else if (b.userName === unassignedString) {
return -1; return -1;
}
else {
} else {
var aSortName = a.sortableUserName.toLowerCase(), var aSortName = a.sortableUserName.toLowerCase(),
bSortName = b.sortableUserName.toLowerCase(); bSortName = b.sortableUserName.toLowerCase();
@ -985,7 +984,7 @@ define(function(require){
}, },
devicesSnakeToCamel: function(string) { devicesSnakeToCamel: function(string) {
return string.replace(/(\_\w)/g, function (match) { return match[1].toUpperCase(); });
return string.replace(/(_\w)/g, function(match) { return match[1].toUpperCase(); });
}, },
/* Utils */ /* Utils */
@ -1034,7 +1033,7 @@ define(function(require){
var e911Numbers = {}; var e911Numbers = {};
_.each(data.data.numbers, function(val, key) { _.each(data.data.numbers, function(val, key) {
if(val.features.indexOf('e911') >= 0) {
if (val.features.indexOf('e911') >= 0) {
e911Numbers[key] = self.devicesFormatNumber(val); e911Numbers[key] = self.devicesFormatNumber(val);
} }
}); });
@ -1047,7 +1046,7 @@ define(function(require){
devicesFormatNumber: function(value) { devicesFormatNumber: function(value) {
var self = this; var self = this;
if('locality' in value) {
if ('locality' in value) {
value.isoCountry = value.locality.country || ''; value.isoCountry = value.locality.country || '';
value.friendlyLocality = 'city' in value.locality ? value.locality.city + ('state' in value.locality ? ', ' + value.locality.state : '') : ''; value.friendlyLocality = 'city' in value.locality ? value.locality.city + ('state' in value.locality ? ', ' + value.locality.state : '') : '';
} }
@ -1057,46 +1056,43 @@ define(function(require){
devicesGetEditData: function(dataDevice, callback) { devicesGetEditData: function(dataDevice, callback) {
var self = this; var self = this;
monster.parallel({ monster.parallel({
listClassifiers: function(callback) {
self.devicesListClassifiers(function(dataClassifiers) {
callback(null, dataClassifiers);
});
},
device: function(callback) {
if(dataDevice.id) {
self.devicesGetDevice(dataDevice.id, function(dataDevice) {
callback(null, dataDevice);
});
}
else {
listClassifiers: function(callback) {
self.devicesListClassifiers(function(dataClassifiers) {
callback(null, dataClassifiers);
});
},
device: function(callback) {
if (dataDevice.id) {
self.devicesGetDevice(dataDevice.id, function(dataDevice) {
callback(null, dataDevice); callback(null, dataDevice);
}
},
e911Numbers: function(callback) {
self.devicesGetE911Numbers(function(e911Numbers) {
callback(null, e911Numbers);
});
},
accountLimits: function(callback) {
self.callApi({
resource: 'limits.get',
data: {
accountId: self.accountId
},
success: function(data, status) {
callback(null, data.data);
}
}); });
} else {
callback(null, dataDevice);
} }
}, },
function(error, results) {
var formattedData = self.devicesFormatData(results, dataDevice);
callback && callback(formattedData);
e911Numbers: function(callback) {
self.devicesGetE911Numbers(function(e911Numbers) {
callback(null, e911Numbers);
});
},
accountLimits: function(callback) {
self.callApi({
resource: 'limits.get',
data: {
accountId: self.accountId
},
success: function(data, status) {
callback(null, data.data);
}
});
} }
);
}, function(error, results) {
var formattedData = self.devicesFormatData(results, dataDevice);
callback && callback(formattedData);
});
}, },
devicesGetDevice: function(deviceId, callbackSuccess, callbackError) { devicesGetDevice: function(deviceId, callbackSuccess, callbackError) {
@ -1120,10 +1116,9 @@ define(function(require){
devicesSaveDevice: function(deviceData, callback) { devicesSaveDevice: function(deviceData, callback) {
var self = this; var self = this;
if(deviceData.id) {
if (deviceData.id) {
self.devicesUpdateDevice(deviceData, callback); self.devicesUpdateDevice(deviceData, callback);
}
else {
} else {
self.devicesCreateDevice(deviceData, callback); self.devicesCreateDevice(deviceData, callback);
} }
}, },
@ -1166,53 +1161,51 @@ define(function(require){
var self = this; var self = this;
monster.parallel({ monster.parallel({
users: function(callback) {
self.callApi({
resource: 'user.list',
data: {
accountId: self.accountId,
filters: {
paginate: 'false'
}
},
success: function(dataUsers) {
callback && callback(null, dataUsers.data);
}
});
},
status: function(callback) {
self.callApi({
resource: 'device.getStatus',
data: {
accountId: self.accountId,
filters: {
paginate: 'false'
}
},
success: function(dataStatus) {
callback && callback(null, dataStatus.data);
users: function(callback) {
self.callApi({
resource: 'user.list',
data: {
accountId: self.accountId,
filters: {
paginate: 'false'
} }
});
},
devices: function(callback) {
self.callApi({
resource: 'device.list',
data: {
accountId: self.accountId,
filters: {
paginate: 'false'
}
},
success: function(dataDevices) {
callback(null, dataDevices.data);
},
success: function(dataUsers) {
callback && callback(null, dataUsers.data);
}
});
},
status: function(callback) {
self.callApi({
resource: 'device.getStatus',
data: {
accountId: self.accountId,
filters: {
paginate: 'false'
} }
});
}
},
success: function(dataStatus) {
callback && callback(null, dataStatus.data);
}
});
}, },
function(err, results) {
callback && callback(results);
devices: function(callback) {
self.callApi({
resource: 'device.list',
data: {
accountId: self.accountId,
filters: {
paginate: 'false'
}
},
success: function(dataDevices) {
callback(null, dataDevices.data);
}
});
} }
);
}, function(err, results) {
callback && callback(results);
});
}, },
devicesGetE911NumberAddress: function(number, callback) { devicesGetE911NumberAddress: function(number, callback) {
@ -1230,7 +1223,7 @@ define(function(require){
postal_code = _data.data.e911.postal_code, postal_code = _data.data.e911.postal_code,
region = _data.data.e911.region; region = _data.data.e911.region;
if ( typeof _data.data.e911.extended_address !== 'undefined' ) {
if (typeof _data.data.e911.extended_address !== 'undefined') {
callback(street_address + ', ' + _data.data.e911.extended_address + '<br>' + locality + ', ' + region + ' ' + postal_code); callback(street_address + ', ' + _data.data.e911.extended_address + '<br>' + locality + ', ' + region + ' ' + postal_code);
} else { } else {
callback(street_address + ', ' + '<br>' + locality + ', ' + region + ' ' + postal_code); callback(street_address + ', ' + '<br>' + locality + ', ' + region + ' ' + postal_code);
@ -1242,7 +1235,7 @@ define(function(require){
devicesGetIterator: function(args, callbackSuccess, callbackError) { devicesGetIterator: function(args, callbackSuccess, callbackError) {
var self = this; var self = this;
if(args.hasOwnProperty('endpoint_brand') && args.hasOwnProperty('endpoint_family') && args.hasOwnProperty('endpoint_model')) {
if (args.hasOwnProperty('endpoint_brand') && args.hasOwnProperty('endpoint_family') && args.hasOwnProperty('endpoint_model')) {
monster.request({ monster.request({
resource: 'provisioner.ui.getModel', resource: 'provisioner.ui.getModel',
data: { data: {
@ -1254,11 +1247,10 @@ define(function(require){
callbackSuccess && callbackSuccess(data.data.template); callbackSuccess && callbackSuccess(data.data.template);
}, },
error: function(data, status) { error: function(data, status) {
callbackError && callbackError();
} }
}); });
}
else {
} else {
callbackError && callbackError(); callbackError && callbackError();
} }
}, },


+ 25
- 1
views/devices-sip_device.html View File

@ -286,10 +286,25 @@
</p> </p>
{{/if}} {{/if}}
{{/each}} {{/each}}
{{#compare id '===' 'combo_keys'}}
<p>
<strong>
{{@root.i18n.devices.popupSettings.keys.types.line}}
</strong>
: {{@root.i18n.devices.popupSettings.keys.info.types.line}}
</p>
{{/compare}}
</div> </div>
</div> </div>
{{#each data}} {{#each data}}
<div class="control-group" data-id="{{@key}}">
<div class="control-group{{#compare ../id '===' 'combo_keys'}}{{#compare @key '===' '0'}} error{{/compare}}{{/compare}}" data-id="{{@key}}">
{{#compare ../id '===' 'combo_keys'}}
{{#compare @key '===' '0'}}
<div class="alert alert-error">
{{@root.i18n.devices.popupSettings.keys.alertMessage}}
</div>
{{/compare}}
{{/compare}}
<label for="provision.keys.{{../id}}[{{@key}}].type" class="control-label"> <label for="provision.keys.{{../id}}[{{@key}}].type" class="control-label">
{{ ../label }} <span class="feature-key-index">{{@key}}</span> {{ ../label }} <span class="feature-key-index">{{@key}}</span>
</label> </label>
@ -299,6 +314,9 @@
{{#each @root.extra.provision.keyActions}} {{#each @root.extra.provision.keyActions}}
<option value="{{id}}">{{text}}</option> <option value="{{id}}">{{text}}</option>
{{/each}} {{/each}}
{{#compare ../id '===' 'combo_keys'}}
<option value="line">{{@root.i18n.devices.popupSettings.keys.types.line}}</option>
{{/compare}}
{{/select}} {{/select}}
</select> </select>
<div class="feature-key-value" data-type="presence"> <div class="feature-key-value" data-type="presence">
@ -329,6 +347,12 @@
<label for="provision.keys.{{../id}}[{{@key}}].value">{{ @root.i18n.devices.popupSettings.keys.labels.value }}</label> <label for="provision.keys.{{../id}}[{{@key}}].value">{{ @root.i18n.devices.popupSettings.keys.labels.value }}</label>
<input type="text" value="" name="provision.keys.{{../id}}[{{@key}}].value"> <input type="text" value="" name="provision.keys.{{../id}}[{{@key}}].value">
</div> </div>
{{#compare id '===' 'combo_keys'}}
{{#compare @key '===' '0'}}
{{#if @root.extra.firstComboKeyUnset}}
{{/if}}
{{/compare}}
{{/compare}}
</div> </div>
</div> </div>
{{/each}} {{/each}}


Loading…
Cancel
Save