From d4299760e32db886f3e98178353155d3ad030ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Guti=C3=A9rrez?= Date: Tue, 11 Dec 2018 15:23:28 -0600 Subject: [PATCH 01/35] UI-3273: Update main callflow on user save only if exists (#108) --- submodules/users/users.js | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/submodules/users/users.js b/submodules/users/users.js index 723b76c..d0f23be 100644 --- a/submodules/users/users.js +++ b/submodules/users/users.js @@ -1003,29 +1003,40 @@ define(function(require) { } }, callflow: function(callback) { - if (isUserNameDifferent || shouldUpdateTimeout) { - self.usersGetMainCallflow(userToSave.id, function(mainCallflow) { + if (!isUserNameDifferent && !shouldUpdateTimeout) { + callback(null, null); + return; + } + + monster.waterfall([ + function(waterfallCallback) { + self.usersGetMainCallflow(userToSave.id, function(mainCallflow) { + waterfallCallback(null, mainCallflow); + }); + }, + function(mainCallflow, waterfallCallback) { + if (_.isNil(mainCallflow)) { + waterfallCallback(null, null); + return; + } + if (isUserNameDifferent) { mainCallflow.name = newName + self.appFlags.users.smartPBXCallflowString; } - if (shouldUpdateTimeout) { - if ('flow' in mainCallflow) { - var flow = mainCallflow.flow; - while (flow.module !== 'user' && '_' in flow.children) { - flow = flow.children._; - } - flow.data.timeout = parseInt(userToSave.extra.ringingTimeout); + if (shouldUpdateTimeout && 'flow' in mainCallflow) { + var flow = mainCallflow.flow; + while (flow.module !== 'user' && '_' in flow.children) { + flow = flow.children._; } + flow.data.timeout = parseInt(userToSave.extra.ringingTimeout); } self.usersUpdateCallflow(mainCallflow, function(updatedCallflow) { callback(null, updatedCallflow); }); - }); - } else { - callback(null, null); - } + } + ], callback); } }, function(error, results) { monster.ui.toast({ From cb785bdc8380dd522b1ef528f82200f9b5a01fc0 Mon Sep 17 00:00:00 2001 From: Ricardo Merino Date: Thu, 20 Dec 2018 14:39:25 -0600 Subject: [PATCH 02/35] UI-3269: Update "add user" form and add new section "add device" (#109) * Remove this * Update add user modal to show labels instead of icons * Fill brand field on add device section * add device form * Save user device * Binding form events from single function * Add extra button Create User and Add Device * Code style * Create user and device form based on mockup * Handling form validation * Create User and Add another button * Revert "Remove this" This reverts commit 7102cf9b4a087321ac2d8ac7dc2b97a44311ed18. * Styled notification email * Use single chosen field to select device model * improvements * Improve form validation message * Delete unused template * Code style improvements * Fix typo on lodash flatMap statement Device family as argument * code style improvements * Create function to render add user modal * Handle error on user creation to prevent form buttons state * Render users list without auto scroll when save and new btn is clicked * Fix device data validation --- i18n/en-US.json | 20 +- submodules/users/users.js | 383 +++++++++++++++++++-------- submodules/users/users.scss | 91 +++++-- submodules/users/views/creation.html | 175 +++++++----- 4 files changed, 464 insertions(+), 205 deletions(-) diff --git a/i18n/en-US.json b/i18n/en-US.json index d9d4ec9..0e6a2ff 100644 --- a/i18n/en-US.json +++ b/i18n/en-US.json @@ -483,6 +483,7 @@ }, "dialogCreationUser": { "createUser": "Create User", + "createUserAndAddAnother": "Create User and Add Another", "createVmbox": "Create a voicemail box for this user", "errorOnCreation": "An error occured while trying to create this user:", "extension": "Main Extension Number", @@ -491,14 +492,27 @@ "lastName": "Last Name", "loginEmail": "Email used for Login", "notificationEmail": "Notification E-mail", - "password": "Password (Min. 6 characters)", + "password": "Password", + "passwordPlaceholder": "Password (Min. 6 characters)", "sendToDifferentEmail": "Send emails to an alternate address", - "title": "Create User", + "title": "Add User and Device", "vmboxAlreadyExist": "VMBox Number is already taken, please choose a different Voicemail Box Number.", "vmboxNumber": "VM Box #", "__comment": "UI-814: Adding the option to automatically send email on user creation", "__version": "3.20_s3", - "sendWelcomeEmail": "Send credentials to this user" + "sendWelcomeEmail": "Send credentials to this user", + "addDevice": { + "deviceMake": { + "label": "Device Make", + "none": "None" + }, + "deviceModel": { + "label": "Device Model" + }, + "macAddress": "MAC Address", + "name": "Device Name", + "title": "Add Device" + } }, "editionForm": { "changePIN": "Change PIN", diff --git a/submodules/users/users.js b/submodules/users/users.js index d0f23be..389c39e 100644 --- a/submodules/users/users.js +++ b/submodules/users/users.js @@ -6,7 +6,14 @@ define(function(require) { var app = { - requests: {}, + requests: { + /* Provisioner */ + 'common.chooseModel.getProvisionerData': { + apiRoot: monster.config.api.provisioner, + url: 'phones', + verb: 'GET' + } + }, subscribe: { 'voip.users.render': 'usersRender' @@ -677,106 +684,7 @@ define(function(require) { }); template.find('.users-header .add-user').on('click', function() { - monster.parallel({ - callflows: function(callback) { - self.usersListCallflows(function(callflows) { - callback(null, callflows); - }); - }, - vmboxes: function(callback) { - self.usersListVMBoxes({ - success: function(vmboxes) { - callback(null, vmboxes); - } - }); - } - }, function(err, results) { - var originalData = self.usersFormatAddUser(results), - userTemplate = $(self.getTemplate({ - name: 'creation', - data: originalData, - submodule: 'users' - })), - userCreationForm = userTemplate.find('#form_user_creation'), - validationOptions = { - ignore: ':hidden:not(select)', - rules: { - 'callflow.extension': { - checkList: originalData.listExtensions - }, - 'vmbox.number': { - checkList: originalData.listVMBoxes - }, - 'user.password': { - minlength: 6 - } - }, - messages: { - 'user.first_name': { - required: self.i18n.active().validation.required - }, - 'user.last_name': { - required: self.i18n.active().validation.required - }, - 'callflow.extension': { - required: self.i18n.active().validation.required - } - } - }; - - if (originalData.licensedUserRoles) { - validationOptions.rules['user.extra.licensedRole'] = { - checkList: [ 'none' ] - }; - validationOptions.messages['user.extra.licensedRole'] = { - checkList: self.i18n.active().validation.required - }; - } - - monster.ui.mask(userTemplate.find('#extension'), 'extension'); - - monster.ui.chosen(userTemplate.find('#licensed_role')); - - monster.ui.validate(userCreationForm, validationOptions); - - // Force select element validation on change event - // (Not handled by jQuery Validation plugin because the select - // element is hidden by the Chosen jQuery plugin. For more info, see: - // https://github.com/jquery-validation/jquery-validation/issues/997) - userCreationForm.find('select').on('change', function() { - userCreationForm.validate().element(this); - }); - - monster.ui.showPasswordStrength(userTemplate.find('#password')); - - userTemplate.find('#create_user').on('click', function() { - if (monster.ui.valid(userTemplate.find('#form_user_creation'))) { - var $this = $(this), - dataForm = monster.ui.getFormData('form_user_creation'), - formattedData = self.usersFormatCreationData(dataForm); - - $this - .prop('disabled', true); - - self.usersCreate(formattedData, function(data) { - popup.dialog('close').remove(); - - self.usersRender({ userId: data.user.id }); - }, function() { - $this - .prop('disabled', false); - }); - } - }); - - userTemplate.find('#notification_email').on('change', function() { - userTemplate.find('.email-group').toggleClass('hidden'); - }); - - var popup = monster.ui.dialog(userTemplate, { - title: self.i18n.active().users.dialogCreationUser.title - }); - }); + self.usersRenderAddModalDialog(); }); template.on('click', '.cancel-link', function() { @@ -1738,6 +1646,198 @@ define(function(require) { }); }, + usersBindAddUserEvents: function(args) { + var self = this, + template = args.template, + data = args.data, + popup = args.popup; + + template.find('.create_user').on('click', function() { + var action = $(this).data('action'); + + if (monster.ui.valid(template.find('#form_user_creation'))) { + var $buttons = template.find('.create_user'), + dataForm = _.merge(monster.ui.getFormData('form_user_creation'), { + user: { + device: { + family: template.find('#device_model').find(':selected').data('family') + } + } + }), + formattedData = self.usersFormatCreationData(dataForm); + + $buttons.prop('disabled', true); + + self.usersCreate(formattedData, function(data) { + popup.dialog('close').remove(); + + switch (action) { + case 'add_new': + self.usersRender(); + self.usersRenderAddModalDialog(); + break; + default: + self.usersRender({ userId: data.user.id }); + break; + } + }, function() { + $buttons.prop('disabled', false); + }); + } + }); + + template.find('#notification_email').on('change', function() { + template.find('.email-group').toggleClass('hidden'); + }); + + template.find('#device_brand').on('change', function() { + var brand = $(this).val(), + selectedBrand = [], + $deviceModel = template.find('.device-model'), + $deviceName = template.find('.device-name'), + $deviceMac = template.find('.device-mac'), + $deviceModelSelect = template.find('#device_model'); + + if (brand !== 'none') { + self.usersDeviceFormReset(template); + $deviceModel.slideDown(); + $deviceName.slideDown(); + $deviceMac.slideDown(); + + selectedBrand = _.find(data.listProvisioners, function(provisioner) { + return provisioner.name === brand; + }); + + $deviceModelSelect + .find('option') + .remove() + .end(); + + selectedBrand.models.map(function(model) { + var option = $('