define(function(require) { var $ = require('jquery'), monster = require('monster'), toastr = require('toastr'), storagesConfig = require('./storages'); var settings = { debug: false }; var log = function(msg){ if(settings.debug) { console.log(msg); } }; // Autoload submodules // (Submodules should be described in /apps/storage/storages.js) var storagesList = storagesConfig.storages; var storagesPaths = []; for (var i = 0, len = storagesList.length; i < len; i++) { storagesPaths.push('./submodules/' + storagesList[i] + '/' + storagesList[i]); } require(storagesPaths); var storageManager = { name: 'storage', css: [ 'app' ], requests: {}, subscribe: { 'storage.fetchStorages': 'define_storage_nodes' // For all submodules }, subModules: storagesList, storages: {}, i18n: { 'en-US': { customCss: false } }, load: function(callback) { var self = this; self.initApp(function() { callback && callback(self); }); }, initApp: function(callback) { var self = this; monster.pub('auth.initApp', { app: self, callback: callback }); }, render: function(container) { var self = this; console.log("STORAGES:"); console.log(self.storages); monster.pub('storage.fetchStorages', { storages: self.storages, callback: function (args) { self.extendI18nOfSubmodule(args); } }); monster.ui.generateAppLayout(self, { menus: [ { tabs: [ { callback: self.storageManagerRender } ] } ] }); $(document.body).addClass('storage-app'); // class for styles; }, extendI18nOfSubmodule: function (args) { var self = this; if(args.i18n && args.submoduleName) { var submoduleLanguages = args.i18n; var curLanguage = self.i18n.hasOwnProperty(monster.config.whitelabel.language) ? monster.config.whitelabel.language : monster.defaultLanguage; if (submoduleLanguages.length && submoduleLanguages.length > 0) { if(submoduleLanguages.indexOf(curLanguage) > -1) { $.getJSON('/apps/storage/submodules/' + args.submoduleName + '/i18n/' + curLanguage + '.json').done(function (newDict) { var dict = self.data.i18n[curLanguage]; $.extend(true, dict, newDict); }); } } } else { log('Extend i18n of submodule failed'); } }, storageManagerRender: function(pArgs) { var self = this, args = pArgs || {}, $container = args.container || $('.app-content-wrapper'), callback = args.callback; if(pArgs.hasOwnProperty('onSetDefault') && typeof(pArgs.onSetDefault) === 'function') { self.storageManagerOnSetDefault = pArgs.onSetDefault; } if(!monster.util.isAdmin()) { log('Permission error. Use admin account for change storage settings'); return; } self.getStorage(function(data) { var storagesData = self.storageManagerFormatData(data); for (var i = 0, len = storagesData.length; i < len; i++) { //storagesData[i].logo = self.storages[storagesData[i].type].getLogo() var storageType = storagesData[i].type; storagesData[i].logo = self.storages[storageType].getLogo() } log('Storages List:'); log(storagesData); var template = $(self.getTemplate({ name: 'layout', data: { storages: storagesData } })); self.storageManagerBind(template, args, storagesData); $container.empty() .append(template); if(typeof(callback) === 'function') { callback(data); } }); }, _doStorageInitialRequest: function(callback) { var self = this; self.callApi({ resource: 'storage.add', data: { accountId : self.accountId, data : { 'attachments': {}, 'plan': {}, 'connections': {} }, removeMetadataAPI: true, generateError: settings.debug }, success: function(data) { if(typeof(callback) === 'function') { callback(data); } }, error: function(error) { var errorMessage = self.i18n.active().storage.universalErrorMessageTemplate.replace('%api%', 'Storage'); monster.ui.alert(errorMessage); log(error.status + ' - ' + error.error + ': ' + error.message + ' '); } }); }, getStorage: function(callback) { var self = this; self.callApi({ resource: 'storage.get', data: { accountId: self.accountId, removeMetadataAPI: true, generateError: false }, success: function(data) { log('Storage Data:'); log(data.data); callback(data.data); }, error: function(data, error, globalHandler) { self._doStorageInitialRequest(function() { self.getStorage(callback); }); } }); }, formatAttachmentSettings: function(storageData) { var type = ""; var attachments = storageData.attachments; if(storageData.hasOwnProperty('connections')) { //type is couchdb attachments = storageData.connections; type = "couchdb"; } var attachments = storageData.attachments; for(var i in attachments) if(attachments.hasOwnProperty(i)) { var thisItem = attachments[i]; var settings = {}; if (thisItem.settings) { settings = _.omitBy(thisItem.settings, _.isEmpty); //filter out empty values if (settings.port) { settings.port = Number(settings.port); } else { settings.port = 443; if (type == "couchdb") settings.port = 5984; } } thisItem.settings = settings; attachments[i] = thisItem; }; storageData.attachments = attachments; return storageData; }, storageManagerUpdateStorage: function(storageData, callback) { var self = this; if(!monster.util.isAdmin()) { log('Permission error. Use admin account for change storage settings'); return; } self.callApi({ resource: 'storage.update', data: { accountId: self.accountId, removeMetadataAPI: true, // or generateError: false data: self.formatAttachmentSettings(storageData) }, success: function(data, status) { if(typeof(callback) === 'function') { callback(data); } }, error: function(data, error, globalHandler) { if (error.status === 404) { callback(undefined); } else { globalHandler(data); } } }); }, storageManagerPatchStorage: function(storageData, callback) { var self = this; if(!monster.util.isAdmin()) { log('Permission error. Use admin account for change storage settings'); return; } self.callApi({ resource: 'storage.patch', data: { accountId: self.accountId, removeMetadataAPI: true, // or generateError: false data: self.formatAttachmentSettings(storageData) }, success: function(data, status) { if(typeof(callback) === 'function') { callback(data); } }, error: function(data, error, globalHandler) { if (error.status === 404) { callback(undefined); } else { globalHandler(data); } } }); }, storageManagerFormatData: function(data) { var activeStorageId = null; var storageType = ""; try { //activeStorageId = data.plan.modb.connection; //.handler; if(data && data.hasOwnProperty('plan') && data.plan.hasOwnProperty('modb') && data.plan.modb.hasOwnProperty('connection') ) { activeStorageId = data.plan.modb.connection; //.handler; storageType = "couchdb"; } else { activeStorageId = data.plan.modb.types.call_recording.attachments.handler; } } catch(e) { log('Active storage not found'); } var itemData; var storagesList = []; if (storageType == "couchdb" && data && data.hasOwnProperty('connections') && Object.keys(data.connections).length > 0) { var connections = data.connections; for(var i in connections) if(connections.hasOwnProperty(i)) { itemData = { id: i, // type: connections[i].handler, // type: connections[i], type: storageType, //"couchdb" name: connections[i].name, settings: connections[i].settings, isActive: false }; if(activeStorageId && itemData.id === activeStorageId) { itemData.isActive = true; } storagesList.push(itemData) } } if(data && data.hasOwnProperty('attachments') && Object.keys(data.attachments).length > 0) { var attachments = data.attachments; for(var i in attachments) if(attachments.hasOwnProperty(i)) { var storageType = attachments[i].handler; var settings = attachments[i].settings; //get custom s3 type by checking if URL is not AWS if (storageType == "s3" && ( (settings.hasOwnProperty('host') && settings.host != "s3.amazonaws.com" && settings.host != "") || (settings.hasOwnProperty('port') && settings.port != "443" && settings.port != 443 && settings.port != "") ) ) { storageType = "custom_s3"; } itemData = { id: i, //type: attachments[i].handler, type: storageType, name: attachments[i].name, settings: attachments[i].settings, isActive: false }; if(activeStorageId && itemData.id === activeStorageId) { itemData.isActive = true; } storagesList.push(itemData) } } return storagesList; }, storageManagerBind: function(template, args, data) { var self = this; template.on('click', '.js-edit-storage', function(e) { e.preventDefault(); var $editStorageBtn = $(this); self.getStorage(function(data) { var $storageItem = $editStorageBtn.closest('.js-storage-item'); var storageType = $storageItem.data('type'); var uuid = $storageItem.data('uuid'); var $container = $storageItem .find('.js-item-settings-wrapper') .hide(); if(data.attachments && data.attachments.hasOwnProperty(uuid)) { var storageData = data.attachments[uuid]; } else if(data.connections && data.connections.hasOwnProperty(uuid)) { var storageData = data.connections[uuid]; } var template = self.getTemplate({ name: 'item-settings', data: { formElements: self.storages[storageType].getFormElements(storageData) } }); $container.empty() .append(template); $container.slideDown(); self.storageManagerSettingsBind($container); }); }); template.on('click', '.js-remove-storage', function(e) { e.preventDefault(); var uuid = $(this).closest('.js-storage-item').data('uuid'); monster.ui.confirm(self.i18n.active().storage.confirmDeleteText, function() { self.storageManagerDeleteStorage(uuid, function() { $('.js-storage-item[data-uuid="' + uuid + '"]').slideUp(400, function() { $(this).remove(); }); self.storageManagerShowMessage(self.i18n.active().storage.successRemovingMessage); }); }, undefined, { type: 'warning', title: self.i18n.active().storage.confirmDeleteTitle, confirmButtonText: self.i18n.active().storage.confirmDelete }); }); template.on('click', '.js-create-storage', function(e) { e.preventDefault(); var $newStorageItem = $('.js-storage-items .js-new-storage-item'); if ($newStorageItem.length === 0) { self.storageManagerShowNewItemPanel(); } else { $newStorageItem.addClass('flash-effect'); (function($newStorageItem){ var timeoutId = setTimeout(function() { $newStorageItem.removeClass('flash-effect'); }, 2000) })($newStorageItem) } }); template.on('click', '.storage-logo', function(e) { e.preventDefault(); var $selectedLogo = $(this).closest('.storage-logo'); var storageType = $selectedLogo.data('type'); $('.storage-logo').removeClass('storage-logo-selected'); //hide all storage forms $selectedLogo.addClass('storage-logo-selected'); $('.js-tab-content-item').hide(); //hide all storage forms var $displayedStorageForm = $('#'+storageType+'-new-item-content'); //$displayedStorageForm.show(); $displayedStorageForm.slideDown(400, function(){}); }); template.on('click', '.js-set-default-storage', function(e) { e.preventDefault(); var uuid = $(this).closest('.js-storage-item').data('uuid'); var isAlreadyActive = $(this).closest('.js-storage-item').hasClass('active-storage'); if(isAlreadyActive) { self.storageManagerShowMessage(self.i18n.active().storage.alreadyActiveMessage, 'warning') } else { var storageType = $(this).closest('.js-storage-item').data('type'); self.storageManagerSetDefaultStorage(uuid, storageType); } }); }, storageManagerShowNewItemPanel: function(){ var self = this; var data = []; var keyword = ''; var storagesList = Object.keys(self.storages); for (var i = 0, len = storagesList.length; i < len; i++) { keyword = storagesList[i]; data.push({ name: keyword, type: keyword, logo: self.storages[keyword].getLogo(), tabId: keyword + '-new-item-content', tabLink: '#' + keyword + '-new-item-content', formElements: self.storages[keyword].getFormElements({}) }); } var template = $(self.getTemplate({ name: 'new-item', data: { storages: data } })); self.storageManagerNewItemBind(template); $('.js-storage-items').append(template); $('.js-new-storage-item').hide().slideDown(400, function(){}); $('.js-new-storage-tabs').tabs(); $('.js-tab-content-item').hide(); //hide all storage forms }, storageManagerNewItemBind: function(template) { var self = this; template.on('click', '.js-save', function (e) { e.preventDefault(); var $tab = $(this).closest('.js-tab-content-item'); var $form = $tab.find('.js-storage-settings-form'); var formData = monster.ui.getFormData($form[0]); var isNeedSetDefault = $tab.find('input[name="set_default"]').is(':checked'); var typeKeyword = $tab.data('type'); var newUuid = self.storageManagerGenerateUUID(); delete formData['set_default']; var storageData = self.storageManagerMakeConfig(typeKeyword, formData, newUuid); self.storageManagerPatchStorage(storageData, function(){ var renderArgs = { callback: function () { self.storageManagerShowMessage(self.i18n.active().storage.successSavingMessage, 'success'); } }; if(isNeedSetDefault) { self.storageManagerSetDefaultStorage(newUuid, typeKeyword, function () { self.storageManagerRender(renderArgs); }); } else { self.storageManagerRender(renderArgs); } }); }); template.on('click', '.js-cancel', function (e) { e.preventDefault(); $('.js-new-storage-item').slideUp(400, function(){ $('.js-new-storage-item').remove(); }); }); }, storageManagerMakeConfig (storageKeyword, data, uuid) { var self = this, storageData = { 'attachments': {} }; if(typeof(uuid) === 'undefined') { uuid = self.storageManagerGenerateUUID(); } if(storageKeyword && self.storages.hasOwnProperty(storageKeyword)) { if (storageKeyword == "couchdb") { storageData["connections"] = {}; data.settings.port = eval(data.settings.port); storageData.connections[uuid] = data; } else { storageData.attachments[uuid] = data; } return storageData; } else { monster.ui.alert('Please install storage correctly (' + storageKeyword + ')'); } }, storageManagerSetDefaultStorage: function(uuid, storageType, callback) { var self = this; if(!monster.util.isAdmin()) { log('Permission error. Use admin account for change storage settings'); return; } var newData = {}; if (storageType == "couchdb") { newData = { plan: { modb: { connection: uuid, types: { call_recording: { database:{ create_options:{} } }, mailbox_message: { database:{ create_options:{} } } } } // account: { // types: { // media: { // database:{ // create_options:{} // } // } // } // }, } }; } else { newData = { plan: { modb: { types: { call_recording: { attachments: { handler: uuid } }, mailbox_message: { attachments: { handler: uuid } } } }, account: { types: { media: { attachments: { handler: uuid } } } }, } }; } self.storageManagerPatchStorage(newData, function(data) { $('#storage_manager_wrapper').find('.js-storage-item') .removeClass('active-storage'); $('.js-storage-item[data-uuid="' + uuid + '"]').addClass('active-storage'); self.storageManagerOnSetDefault(data); callback && callback(data); }); }, storageManagerOnSetDefault: function(data) {}, storageManagerSettingsBind: function($settingsContainer) { var self = this; $settingsContainer.find('.js-cancel').on('click', function(e) { e.preventDefault(); $settingsContainer.slideUp(400, function(){ $settingsContainer.empty(); }); }); $settingsContainer.find('.js-save').on('click', function(e) { e.preventDefault(); var $storageItem = $(this).closest('.js-storage-item'); var $form = $storageItem.find('.js-storage-settings-form'); var formData = monster.ui.getFormData($form[0]); var storageName = formData.name; var typeKeyword = $storageItem.data('type'); var uuid = $storageItem.data('uuid'); var storageData = self.storageManagerMakeConfig(typeKeyword, formData, uuid); self.getStorage(function(existStorageData) { self.storageManagerPatchStorage(storageData, function(data) { // update item name $('.js-storage-item[data-uuid="' + uuid + '"]').find('.js-storage-name').text(storageName); self.storageManagerShowMessage(self.i18n.active().storage.successUpdate, 'success'); }); }); }); }, storageManagerDeleteStorage: function(uuid, callback) { var self = this; if(!monster.util.isAdmin()) { log('Permission error. Use admin account for change storage settings'); return; } self.getStorage(function(storagesData) { var resultData = {}; if(storagesData.hasOwnProperty('connections')) { resultData.connections = storagesData.connections; } if(storagesData.hasOwnProperty('attachments')) { resultData.attachments = storagesData.attachments; } if(storagesData.hasOwnProperty('plan')) { resultData.plan = storagesData.plan; } if(resultData.connections && resultData.connections.hasOwnProperty(uuid)) { resultData.attachments = {}; delete resultData.connections[uuid]; } if(resultData.attachments && resultData.attachments.hasOwnProperty(uuid)) { delete resultData.attachments[uuid]; } try { if(resultData.plan.modb.types.call_recording.attachments.handler === uuid) { resultData.plan = {}; } else if(resultData.plan.modb.types.call_recording.connection === uuid) { resultData.plan = {}; } } catch (e) {} self.storageManagerUpdateStorage(resultData, function() { if(typeof(callback) === 'function') { callback(); } }); }) }, storageManagerGenerateUUID: function() { return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); }, storageManagerShowMessage: function(msg, msgType) { var msgTypeClass; if(typeof(msgType) === 'undefined') { msgType = 'info'; } switch(msgType) { case 'warning': msgTypeClass = 'storage-msg-warning'; break; case 'success': msgTypeClass = 'storage-msg-success'; break; default: // 'info' msgTypeClass = 'storage-msg-info'; } var $msg = $('
') .appendTo($('.js-storage-msg-box')).hide().fadeIn(); $msg.animate({ backgroundColor: '#ffffff' }, 1000 ); window.setTimeout(function(){ $msg.fadeOut(400, function() { $msg.remove(); }) }, 4000); } }; return storageManager; });