define(function(require){ var $ = require('jquery'), _ = require('underscore'), monster = require('monster'), timezone = require('monster-timezone'), toastr = require('toastr'); var app = { requests: { /* Groups */ 'voip.groups.listGroups': { url: 'accounts/{accountId}/groups', verb: 'GET' }, 'voip.groups.getGroup': { url: 'accounts/{accountId}/groups/{groupId}', verb: 'GET' }, 'voip.groups.createGroup': { url: 'accounts/{accountId}/groups', verb: 'PUT' }, 'voip.groups.updateGroup': { url: 'accounts/{accountId}/groups/{groupId}', verb: 'POST' }, 'voip.groups.deleteGroup': { url: 'accounts/{accountId}/groups/{groupId}', verb: 'DELETE' }, /* Users */ 'voip.groups.listUsers': { url: 'accounts/{accountId}/users', verb: 'GET' }, /* Callflows */ 'voip.groups.listRingGroups': { url: 'accounts/{accountId}/callflows?has_key=group_id', verb: 'GET' }, 'voip.groups.listUserCallflows': { url: 'accounts/{accountId}/callflows?has_key=owner_id&key_missing=type', verb: 'GET' }, 'voip.groups.listMainCallflows': { url: 'accounts/{accountId}/callflows?filter_type=main', verb: 'GET' }, 'voip.groups.getCallflows': { url: 'accounts/{accountId}/callflows/', verb: 'GET' }, 'voip.groups.createCallflow': { url: 'accounts/{accountId}/callflows', verb: 'PUT' }, 'voip.groups.listGroupCallflows': { url: 'accounts/{accountId}/callflows?filter_group_id={groupId}', verb: 'GET' }, 'voip.groups.getCallflow': { url: 'accounts/{accountId}/callflows/{callflowId}', verb: 'GET' }, 'voip.groups.updateCallflow': { url: 'accounts/{accountId}/callflows/{callflowId}', verb: 'POST' }, 'voip.groups.deleteCallflow': { url: 'accounts/{accountId}/callflows/{callflowId}', verb: 'DELETE' }, /* Misc */ 'voip.groups.getNumbers': { url: 'accounts/{accountId}/phone_numbers/', verb: 'GET' }, 'voip.groups.listMedia': { url: 'accounts/{accountId}/media?key_missing=type', verb: 'GET' }, 'voip.groups.createMedia': { url: 'accounts/{accountId}/media', verb: 'PUT' }, 'voip.groups.deleteMedia': { url: 'accounts/{accountId}/media/{mediaId}', verb: 'DELETE' }, 'voip.groups.uploadMedia': { url: 'accounts/{accountId}/media/{mediaId}/raw', verb: 'POST', type: 'application/x-base64' }, 'voip.groups.listVMBoxes': { url: 'accounts/{accountId}/vmboxes', verb: 'GET' } }, subscribe: { 'voip.groups.render': 'groupsRender' }, /* Users */ /* args: parent and groupId */ groupsRender: function(args) { var self = this, args = args || {}, parent = args.parent || $('.right-content'), _groupId = args.groupId, noGroup = true; self.groupsRemoveOverlay(); self.groupsGetData(function(data) { var dataTemplate = self.groupsFormatListData(data), template = $(monster.template(self, 'groups-layout', { countGroups: Object.keys(dataTemplate.groups).length })), templateGroup; _.each(dataTemplate.groups, function(group) { templateGroup = monster.template(self, 'groups-row', group); template.find('.groups-rows').append(templateGroup); }); self.groupsBindEvents(template, parent); parent .empty() .append(template); if(_groupId) { var cells = parent.find('.grid-row[data-id=' + _groupId + '] .grid-cell'); monster.ui.fade(cells); } for (var group in dataTemplate.groups) { noGroup = ( typeof dataTemplate.groups[group] === 'undefined' ) ? true : false; } if ( noGroup ) { parent.find('.grid-row.title').css('display', 'none'); parent.find('.no-groups-row').css('display', 'block'); } else { parent.find('.grid-row.title').css('display', 'block'); parent.find('.no-groups-row').css('display', 'none'); } }); }, groupsFormatListData: function(data) { var self = this, mapGroups = {}; _.each(data.groups, function(group) { mapGroups[group.id] = group; mapGroups[group.id].extra = self.groupsGetGroupFeatures(group); }); _.each(data.callflows, function(callflow) { if(callflow.group_id in mapGroups) { var listExtensions = [], listNumbers = []; _.each(callflow.numbers, function(number) { number.length < 7 ? listExtensions.push(number) : listNumbers.push(number); }); mapGroups[callflow.group_id].extra.listCallerId = []; if(listExtensions.length > 0) { mapGroups[callflow.group_id].extra.extension = listExtensions[0]; _.each(listExtensions, function(number) { mapGroups[callflow.group_id].extra.listCallerId.push(number); }); } mapGroups[callflow.group_id].extra.additionalExtensions = listExtensions.length > 1; if(listNumbers.length > 0) { mapGroups[callflow.group_id].extra.mainNumber = listNumbers[0]; _.each(listNumbers, function(number) { mapGroups[callflow.group_id].extra.listCallerId.push(number); }); } mapGroups[callflow.group_id].extra.additionalNumbers = listNumbers.length > 1; mapGroups[callflow.group_id].extra.callflowId = callflow.id; } }); data.groups = mapGroups; return data; }, groupsGetGroupFeatures: function(group) { var self = this, result = { mapFeatures: { call_recording: { icon: 'icon-microphone', iconColor: 'icon-blue', title: self.i18n.active().groups.callRecording.title }, ringback: { icon: 'icon-music', iconColor: 'icon-yellow', title: self.i18n.active().groups.ringback.title } }, hasFeatures: false }; _.each(result.mapFeatures, function(val, key) { if(('features' in group && group.features.indexOf(key) >= 0) // If data from view || ('smartpbx' in group && key in group.smartpbx && group.smartpbx[key].enabled)) { // If data from document val.active = true; result.hasFeatures = true; } }); return result; }, groupsBindEvents: function(template, parent) { var self = this; template.find('.grid-row:not(.title) .grid-cell').on('click', function() { var cell = $(this), type = cell.data('type'), row = cell.parents('.grid-row'), groupId = row.data('id'); template.find('.edit-groups').slideUp("400", function() { $(this).empty(); }); if(cell.hasClass('active')) { template.find('.grid-cell').removeClass('active'); template.find('.grid-row').removeClass('active'); self.groupsRemoveOverlay(); cell.css({ 'position': 'inline-block', 'z-index': '0' }); cell.parent().siblings('.edit-groups').css({ 'position': 'block', 'z-index': '0' }); } else { template.find('.grid-cell').removeClass('active'); template.find('.grid-row').removeClass('active'); cell.toggleClass('active'); row.toggleClass('active'); cell.css({ 'position': 'relative', 'z-index': '3' }); cell.parent().siblings('.edit-groups').css({ 'position': 'relative', 'z-index': '2' }); self.groupsGetTemplate(type, groupId, function(template, data) { //FancyCheckboxes. monster.ui.prettyCheck.create(template); row.find('.edit-groups').append(template).slideDown(); $('body').append($('
')); }); } }); template.find('.groups-header .search-query').on('keyup', function() { var searchString = $(this).val().toLowerCase(), rows = template.find('.groups-rows .grid-row:not(.title)'), emptySearch = template.find('.groups-rows .empty-search-row'); _.each(rows, function(row) { var row = $(row); row.data('search').toLowerCase().indexOf(searchString) < 0 ? row.hide() : row.show(); }); if(rows.size() > 0) { rows.is(':visible') ? emptySearch.hide() : emptySearch.show(); } }); template.on('click', '.cancel-link', function() { template.find('.edit-groups').slideUp("400", function() { $(this).empty(); template.find('.grid-cell.active').css({ 'position': 'inline-block', 'z-index': '0' }); template.find('.grid-row.active .edit-groups').css({ 'position': 'block', 'z-index': '0' }); template.find('.grid-row.active').removeClass('active'); self.groupsRemoveOverlay(); template.find('.grid-cell.active').removeClass('active'); }); }); template.find('.groups-header .add-group').on('click', function() { self.groupsGetCreationData(function(data) { var groupTemplate = $(monster.template(self, 'groups-creation', data)), groupForm = groupTemplate.find('#form_group_creation'); monster.ui.validate(groupForm); groupTemplate.find('#create_group').on('click', function() { var formattedData = self.groupsCreationMergeData(data, groupTemplate); // if(formattedData.group.name && formattedData.callflow.numbers[0]) { if(monster.ui.valid(groupForm)) { self.groupsCreate(formattedData, function(data) { popup.dialog('close').remove(); self.groupsRender({ groupId: data.id }); }); }/* else { monster.ui.alert('error', self.i18n.active().groups.dialogCreationGroup.missingDataAlert) }*/ }); groupTemplate.find('#group_user_selector .selected-users, #group_user_selector .available-users').sortable({ connectWith: '.connectedSortable' }).disableSelection(); var popup = monster.ui.dialog(groupTemplate, { title: self.i18n.active().groups.dialogCreationGroup.title }); }); }); $('body').on('click', '#groups_container_overlay', function() { template.find('.edit-groups').slideUp("400", function() { $(this).empty(); }); self.groupsRemoveOverlay(); template.find('.grid-cell.active').css({ 'position': 'inline-block', 'z-index': '0' }); template.find('.grid-row.active').parent().siblings('.edit-groups').css({ 'position': 'block', 'z-index': '0' }); template.find('.grid-cell.active').removeClass('active'); template.find('.grid-row.active').removeClass('active'); }); }, groupsCreationMergeData: function(data, template) { var formData = form2object('form_group_creation'), fixedTimeout = '20', fixedDelay = '0', settings = { timeout: fixedTimeout, delay: fixedDelay, endpoint_type: 'user' }, listUserRingGroup = [], listUserGroup = {}; template.find('.selected-users li').each(function() { var userId = $(this).data('user_id'), ringGroupUser = $.extend(true, {}, settings, { id: userId }); listUserGroup[userId] = { type: 'user' }; listUserRingGroup.push(ringGroupUser); }); var formattedData = { group: { name: formData.name, endpoints: listUserGroup }, callflow: { numbers: [ formData.extra.extension ], name: formData.name + ' Ring Group', flow: { module: 'ring_group', children: {}, data: { name: formData.name + ' Ring Group', strategy: 'simultaneous', timeout: parseInt(fixedTimeout) + parseInt(fixedDelay), endpoints: listUserRingGroup } } } }; return formattedData; }, groupsGetTemplate: function(type, groupId, callbackAfterData) { var self = this, template; if(type === 'name') { self.groupsGetNameTemplate(groupId, callbackAfterData); } else if(type === 'numbers') { self.groupsGetNumbersTemplate(groupId, callbackAfterData); } else if(type === 'extensions') { self.groupsGetExtensionsTemplate(groupId, callbackAfterData); } else if(type === 'features') { self.groupsGetFeaturesTemplate(groupId, callbackAfterData); } else if(type === 'members') { self.groupsGetMembersTemplate(groupId, callbackAfterData); } }, groupsGetFeaturesTemplate: function(groupId, callback) { var self = this; self.groupsGetFeaturesData(groupId, function(data) { template = $(monster.template(self, 'groups-features', data.group)); self.groupsBindFeatures(template, data); callback && callback(template, data); }); }, groupsGetNameTemplate: function(groupId, callback) { var self = this; self.groupsGetNameData(groupId, function(data) { template = $(monster.template(self, 'groups-name', data)); self.groupsBindName(template, data); callback && callback(template, data); }); }, groupsGetNumbersTemplate: function(groupId, callback) { var self = this; self.groupsGetNumbersData(groupId, function(data) { self.groupsFormatNumbersData(data, function(data) { template = $(monster.template(self, 'groups-numbers', data)); self.groupsBindNumbers(template, data); callback && callback(template, data); }); }); }, groupsGetExtensionsTemplate: function(groupId, callback) { var self = this; self.groupsGetNumbersData(groupId, function(data) { self.groupsFormatNumbersData(data, function(data) { template = $(monster.template(self, 'groups-extensions', data)); self.groupsBindExtensions(template, data); callback && callback(template, data); }); }); }, groupsGetMembersTemplate: function(groupId, callback) { var self = this; self.groupsGetMembersData(groupId, function(results) { var results = self.groupsFormatMembersData(results); template = $(monster.template(self, 'groups-members', results)); self.groupsRenderMemberSliders(template, results.extra.ringGroup); self.groupsBindMembers(template, results); template.find('[data-toggle="tooltip"]').tooltip(); callback && callback(template, results); }); }, groupsBindFeatures: function(template, data) { var self = this; template.find('.feature[data-feature="call_recording"]').on('click', function() { self.groupsRenderCallRecording(data); }); template.find('.feature[data-feature="ringback"]').on('click', function() { self.groupsRenderRingback(data); }); }, groupsRenderCallRecording: function(data) { var self = this, templateData = $.extend(true, { group: data.group }, (data.group.extra.mapFeatures.call_recording.active ? { url: data.callflow.flow.data.url, format: data.callflow.flow.data.format, timeLimit: data.callflow.flow.data.time_limit } : {}) ), featureTemplate = $(monster.template(self, 'groups-feature-call_recording', templateData)), switchFeature = featureTemplate.find('.switch').bootstrapSwitch(), featureForm = featureTemplate.find('#call_recording_form'), popup; monster.ui.validate(featureForm, { rules: { 'time_limit': { digits: true } } }); featureTemplate.find('.cancel-link').on('click', function() { popup.dialog('close').remove(); }); switchFeature.on('switch-change', function(e, data) { data.value ? featureTemplate.find('.content').slideDown() : featureTemplate.find('.content').slideUp(); }); featureTemplate.find('.save').on('click', function() { if(monster.ui.valid(featureForm)) { var formData = form2object('call_recording_form'), enabled = switchFeature.bootstrapSwitch('status'); if(!('smartpbx' in data.group)) { data.group.smartpbx = {}; } if(!('call_recording' in data.group.smartpbx)) { data.group.smartpbx.call_recording = { enabled: false }; } if(data.group.smartpbx.call_recording.enabled || enabled) { data.group.smartpbx.call_recording.enabled = enabled; var newCallflow = $.extend(true, {}, data.callflow); if(enabled) { if(newCallflow.flow.module === 'record_call') { newCallflow.flow.data = $.extend(true, { action: "start" }, formData); } else { newCallflow.flow = { children: { "_": $.extend(true, {}, data.callflow.flow) }, module: "record_call", data: $.extend(true, { action: "start" }, formData) } } } else { newCallflow.flow = $.extend(true, {}, data.callflow.flow.children["_"]); } self.groupsUpdateCallflow(newCallflow, function(updatedCallflow) { self.groupsUpdate(data.group, function(updatedGroup) { popup.dialog('close').remove(); self.groupsRender({ groupId: data.group.id }); }); }); } else { popup.dialog('close').remove(); self.groupsRender({ groupId: data.group.id }); } } }); popup = monster.ui.dialog(featureTemplate, { title: data.group.extra.mapFeatures.call_recording.title, position: ['center', 20] }); }, groupsRenderRingback: function(data) { var self = this, silenceMediaId = 'silence_stream://300000', ringGroupNode = data.callflow.flow; while(ringGroupNode.module !== 'ring_group' && '_' in ringGroupNode.children) { ringGroupNode = ringGroupNode.children['_']; } self.groupsListMedias(function(medias) { var templateData = { group: data.group, silenceMedia: silenceMediaId, mediaList: medias, media: ringGroupNode.data.ringback || '' }, featureTemplate = $(monster.template(self, 'groups-feature-ringback', templateData)), switchFeature = featureTemplate.find('.switch').bootstrapSwitch(), popup, closeUploadDiv = function(newMedia) { var uploadInput = featureTemplate.find('.upload-input'); uploadInput.wrap('