(function () { 'use strict'; var app = angular.module('user'); var templatePath = modulesSharedResourcesUrl + 'Modules/UserSettings/Views/'; app.directive('userSettings', [ '$injector', 'config', 'common', 'auth', 'userDataContext', 'userSettingsDataContext', 'userSettingsService', 'validation', '$rootScope', 'myUsersDataContext', 'user', 'datacontext', 'terminology', 'virusScanModalService', directive]); function directive($injector, config, common, auth, userDataContext, userSettingsDataContext, userSettingsService, validation, $rootScope, myUsersDataContext, user, datacontext, terminology, virusScanModalService) { return { restrict: 'E', templateUrl: templatePath + 'settings.html', scope: { showMenu: '=', includeProfile: '=', includeContact: '=', includeSocials: '=', includeAddresses: '=', includeTelephones: '=', includeFrameworks: '=', includeMembership: '=', includeMembershipLeave: '=', includePassword: '=', includeIntegrations: '=', includeNotifications: '=', includeBackpackIntegrations: '=', includeDeletedBadges: '=', includeRelationships: '=' }, link: link }; function link($scope) { $scope.productVersion = productVersion; // Conditionally inject backpack context if ($scope.includeBackpackIntegrations) { var backpackDatacontext = $injector.get('backpackDatacontext'); } // Conditionally inject framework context if ($scope.includeFrameworks) { var frameworks = $injector.get('frameworks'); } // Conditionally inject integration context if ($scope.includeIntegrations) { var CanvasAdminService = $injector.get('CanvasAdminService'); var OrganisationAdminService = $injector.get('OrganisationAdminService'); } // Conditionally inject relationship context if ($scope.includeRelationships) { var relationshipsDataContext = $injector.get('relationshipsDataContext'); } var getLogFn = common.logger.getLogFn; var log = getLogFn('userSettings'); var logSuccess = getLogFn('userSettings', "success"); var logWarning = getLogFn('userSettings', "warning"); var logError = getLogFn('userSettings', "error"); $scope.avatarFileName = null; $scope.isValidMozillaEmail = true; $scope.isSaving = false; $scope.terminology = terminology; $scope.templatePaths = [ { url: templatePath + 'profile.html' }, { url: templatePath + 'contact.html' }, { url: templatePath + 'frameworks.html' }, { url: templatePath + 'membership.html' }, { url: templatePath + 'password.html' }, { url: templatePath + 'integrations.html' }, { url: templatePath + 'notifications.html' }, { url: templatePath + 'relationships.html' }, { url: templatePath + 'backpackIntegrations.html' }, { url: templatePath + 'settingsmenu.html' } ]; $scope.validation = validation.userValidationConfig(); $scope.files = []; $scope.invalidEmails = []; $scope.connectedToEvernote = false; $scope.uploadStatus = ""; $scope.isFrameworksTab = false; $scope.selectedGroup = { name: "" }; $scope.countryList = ["Afghanistan", "Albania", "Algeria", "Andorra", "Angola", "Anguilla", "Antigua & Barbuda", "Argentina", "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", "Bahamas", "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia", "Bosnia & Herzegovina", "Botswana", "Brazil", "British Virgin Islands", "Brunei", "Bulgaria", "Burkina Faso", "Burundi", "Cambodia", "Cameroon", "Cape Verde", "Cayman Islands", "Chad", "Chile", "China", "Colombia", "Congo", "Cook Islands", "Costa Rica", "Cote D Ivoire", "Croatia", "Cruise Ship", "Cuba", "Cyprus", "Czech Republic", "Denmark", "Djibouti", "Dominica", "Dominican Republic", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Estonia", "Ethiopia", "Falkland Islands", "Faroe Islands", "Fiji", "Finland", "France", "French Polynesia", "French West Indies", "Gabon", "Gambia", "Georgia", "Germany", "Ghana", "Gibraltar", "Greece", "Greenland", "Grenada", "Guam", "Guatemala", "Guernsey", "Guinea", "Guinea Bissau", "Guyana", "Haiti", "Honduras", "Hong Kong", "Hungary", "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Isle of Man", "Israel", "Italy", "Jamaica", "Japan", "Jersey", "Jordan", "Kazakhstan", "Kenya", "Kuwait", "Kyrgyz Republic", "Laos", "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg", "Macau", "Macedonia", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Mauritania", "Mauritius", "Mexico", "Moldova", "Monaco", "Mongolia", "Montenegro", "Montserrat", "Morocco", "Mozambique", "Namibia", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand", "Nicaragua", "Niger", "Nigeria", "Norway", "Oman", "Pakistan", "Palestine", "Panama", "Papua New Guinea", "Paraguay", "Peru", "Philippines", "Poland", "Portugal", "Puerto Rico", "Qatar", "Reunion", "Romania", "Russia", "Rwanda", "Saint Pierre & Miquelon", "Samoa", "San Marino", "Satellite", "Saudi Arabia", "Senegal", "Serbia", "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "South Africa", "South Korea", "Spain", "Sri Lanka", "St Kitts & Nevis", "St Lucia", "St Vincent", "St. Lucia", "Sudan", "Suriname", "Swaziland", "Sweden", "Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "Timor L'Este", "Togo", "Tonga", "Trinidad & Tobago", "Tunisia", "Turkey", "Turkmenistan", "Turks & Caicos", "Uganda", "Ukraine", "United Arab Emirates", "United Kingdom", "Uruguay", "Uzbekistan", "Venezuela", "Vietnam", "Virgin Islands (US)", "Yemen", "Zambia", "Zimbabwe"]; $scope.availableInterests = availableInterests; $scope.changePasswordLink = "https://" + config.b2cName + ".b2clogin.com/" + b2cName + ".onmicrosoft.com/oauth2/v2.0/authorize?p=B2C_1A_MKMCHANGEPASSWORD&nonce=defaultNonce&scope=openid&response_type=id_token&client_id=" + b2cClientId + "&redirect_uri=" + encodeURIComponent(config.siteUrl) + "&apigatewayUrl=" + encodeURIComponent(config.apigatewayUrl); // Hide the settings menu when the user tabs out document.addEventListener('keydown', function (key) { var signOutLink = $('.right-pane.in-view a'); if (key.code == "Tab" && !key.shiftKey && signOutLink && signOutLink[0] == document.activeElement) { $scope.changeMenu('Hide'); $scope.$apply(); } }); // Focus an element with the given selector $scope.focusElement = function (selector) { $(selector).focus(); } activate(); function activate() { getProfile(); if ($scope.includeFrameworks) getFrameworks(); if ($scope.includeMembership) getMyGroups(); NProgress.done(); log('Activated userSettings View'); } //get the user details function getProfile() { userDataContext.getProfile().then(function (theUser) { $scope.user = theUser; $scope.originalUsername = angular.copy($scope.user.userName); if (!$scope.user.cvDetails) $scope.user.cvDetails = {}; $scope.isSaving = false; if ($scope.includeNotifications) getNotificationSchedule(); if ($scope.includeRelationships) getRelationships(); }); } //get the groups for the user function getMyGroups() { return myUsersDataContext.getOrganisations().then(function (theGroups) { $scope.groups = theGroups; }); } // Get the users notification schedule function getNotificationSchedule() { return userSettingsDataContext.getNotificationSchedule().then(function (theSchedule) { if (!theSchedule) { $scope.createNotificationSchedule(); } else { $scope.notificationSchedule = theSchedule; } }).catch(function (error) { if (error === "Not found.") $scope.createNotificationSchedule(); }); } // Get the relationships for the user function getRelationships() { relationshipsDataContext.getRelationshipTypes().then(function (types) { $scope.relationships = []; relationshipsDataContext.getRelationshipsForUser($scope.user.userId).then(function (relationships) { angular.forEach(types, function (value) { var relationship = relationships.filter(function (r) { return r.relationshipTypeId === value.id && r.firstActor === $scope.user.userId })[0]; if (relationship) { user.getUserProfile(relationship.secondActor).then(function (data) { relationship.user = data; relationship.name = value.name; $scope.relationships.push(relationship); }); }; }); $scope.relationshipsLoaded = true; }); }); } $scope.createNotificationSchedule = function () { var schedule = { active: true, appCode: config.appCode, userId: $scope.user.userId, delivery: { emailDelivery: { isEnabled: true, emailAddresses: [ $scope.user.email.email ] }, smsDelivery: { phoneNumber: $scope.user.telephones.length > 0 ? $scope.user.telephones[0].number : null } }, interest: { interestedIn: $scope.availableInterests }, recurrence: 'daily' }; userSettingsDataContext.createNotificationSchedule(schedule).then(function () { userSettingsDataContext.getNotificationSchedule().then(function (theSchedule) { $scope.notificationSchedule = theSchedule; }); }); }; //save user details $scope.save = function (changedUser) { function actualSave() { saveSettings(changedUser).then(function () { $scope.showMenu = false; $("body").css({ overflowY: "visible" }); }); } $scope.isSaving = true; //handle upload of avatar image if ($scope.files.length > 0) { var file = $scope.files[0]; // we're not interested in multiple file uploads here if (file.type !== 'image/jpeg' && file.type !== 'image/png' && file.type !== 'image/gif' || file.type === 'image/tiff') { $scope.avatarFileName = null; $scope.isSaving = false; $scope.files = []; logWarning("Please ensure avatar image is an image file"); return; } else { var reader = new FileReader(); reader.readAsDataURL(file); reader.onload = function (event) { changedUser.fileAsBase64 = reader.result; actualSave(); } } } else { actualSave(); } } $scope.doesEmailExist = function (emailModel) { emailModel.exists = false; $scope.invalidEmails = []; for (i in $scope.user.emailAddresses) { if ($scope.user.emailAddresses[i].exists) { $scope.invalidEmails.push(emailModel.email); } } //HTML encode the username so that e.g. '+' is handled correctly var email = encodeURIComponent(emailModel.email); userSettingsDataContext.isEmailAvailable(email).then(function (data) { //Decode the email back again email = decodeURIComponent(email); if (data === true) { emailModel.exists = true; $scope.invalidEmails.push(emailModel.email); } }); } $scope.doesUsernameExist = function (user) { user.userNameExists = false; //HTML encode the username so that e.g. '+' is handled correctly var username = encodeURIComponent(user.userName); userSettingsDataContext.isUsernameAvailable(username).then(function (data) { //Decode the email back again username = decodeURIComponent(username); if (data === false && username !== $scope.originalUsername) { user.userNameExists = true; } }); } $scope.changeMenu = function (active) { $scope.rightPaneSubProfile = false; $scope.rightPaneSubContact = false; $scope.rightPaneSubFrameworks = false; $scope.rightPaneSubMembership = false; $scope.rightPaneSubPasswordShow = false; $scope.rightPaneSubBackpackShow = false; $scope.rightPaneSubIntegrationsShow = false; $scope.rightPaneSubNotificationsShow = false; $scope.rightPaneSubBackpacksIntegrationsShow = false; $scope.rightPaneSubRelationships = false; if (active == 'Profile') { $scope.rightPaneSubProfile = true; } if (active == 'Contact') { $scope.rightPaneSubContact = true; } if (active == 'Frameworks') { $scope.rightPaneSubFrameworks = true; } if (active == 'Membership') { $scope.rightPaneSubMembership = true; } if (active == 'Password') { $scope.rightPaneSubPasswordShow = true; } if (active == 'Integrations') { $scope.rightPaneSubIntegrationsShow = true; } if (active == 'Notifications') { $scope.rightPaneSubNotificationsShow = true; } if (active == 'backpackIntegrations') { $scope.rightPaneSubBackpacksIntegrationsShow = true; } if (active == 'Relationships') { $scope.rightPaneSubRelationships = true; } if (active == 'Hide') { $scope.showMenu = !$scope.showMenu; $("body").css({ overflowY: "visible" }); } else { // After scope applies the change to bring the right pane into view, focus the first input or checkbox setTimeout(function () { var inputs = $(".right-pane-sub.in-view input"); var checkboxes = $(".right-pane-sub.in-view input:checked"); if (checkboxes.length > 0) { checkboxes.eq(0).focus(); } else { inputs.eq(0).focus(); } }, 30); } } // Watch for change in issuer selection $scope.$watch('showMenu', function () { $scope.changeMenu(); }); //save user settings function saveSettings(changedUser) { changedUser.applicationId = config.applicationId; // Double check that the email is not already in use (may have been checked in ui already) return userDataContext.saveProfile(changedUser).then(function () { logSuccess("User settings saved"); if (changedUser.userName !== $scope.originalUsername) { auth.logOut(); window.location = '#!/signin'; window.location.reload(); } clearImageForm(); $rootScope.$broadcast('UpdateProfile'); $rootScope.$broadcast('UpdateUser'); getProfile(); //errorData user details (e.g. show correct avatar) }).catch(function (errorData) { $scope.isSaving = false; if (errorData === "Virus scan positive.") { virusScanModalService.virusModal(); } else { logError("Error saving settings. Please ensure all areas have been correctly completed."); } $scope.saveClicked = false; }); } //set the files (avatar image) array to those selected by the user $scope.onAvatarFileSelect = function ($files) { $scope.files = $files; } //clear the form once the avatar image is uploaded function clearImageForm() { $scope.uploadStatus = ""; $scope.progress = 0; $scope.files = []; angular.forEach( angular.element("input[type='file']"), function (inputElem) { angular.element(inputElem).val(null); }); } function imageUploadError() { logError("problem uploading avatar image"); } //avatar upload progress function imageUploadProgress(percentComplete) { $scope.progress = percentComplete; $scope.uploadStatus = "Uploading... " + percentComplete + "%"; } //handle the sucessful upload of an avatar image - set the image details for the user function imageUploadSuccess(changedUser, data) { data.url = data.url.replace(/^http:\/\//i, 'https://'); data.url = data.url.replace(/upload\//i, 'upload/w_250/'); $scope.user.avatarUrl = data.url; saveSettings(changedUser); } $scope.saveMozillaEmail = function () { var email = { userId: $rootScope.badgeUserConfig.id, email: $rootScope.badgeUserConfig.mozillaEmailAddress } backpackDatacontext.saveBadgeUserMozillaEmail(email).then(function (data) { logSuccess('User settings saved successfully'); var userBackpack = { emailaddress: $rootScope.badgeUserConfig.mozillaEmailAddress, backpackid: $rootScope.badgeUserConfig.backpack.id }; backpackDatacontext.getBadgesForEmail(userBackpack).then(function (data) { $rootScope.$broadcast('UpdateBadges'); }); }); } $scope.verfiyMozillaEmail = function (email) { $scope.checkingEmail = true; var emailModel = { email: $rootScope.badgeUserConfig.mozillaEmailAddress, userId: $rootScope.badgeUserConfig.id, } backpackDatacontext.validateBadgeUserMozillaEmail(emailModel).then(function (data) { if (data) { $scope.isValidMozillaEmail = data; } else { $scope.isValidMozillaEmail = true; } $scope.checkingEmail = false; }); } $scope.syncEmail = function (email, index) { $scope.syncStarted = true; $scope.userBackpack = { emailaddress: email, backpackid: $rootScope.badgeUserConfig.backpack.id }; backpackDatacontext.getBadgesForEmail($scope.userBackpack).then(function (data) { $rootScope.$broadcast('UpdateBadges'); logSuccess('Badges successfully synced for ' + email); $scope.syncStarted = false; }); } $scope.syncAllEmails = function () { $scope.syncStarted = true; $scope.allSyncStarted = true; var syncCount = 0; for (var i in $rootScope.verifiedEmails) { var userBackpack = { emailaddress: $rootScope.verifiedEmails[i], backpackid: $rootScope.badgeUserConfig.backpack.id }; backpackDatacontext.getBadgesForEmail(userBackpack).then(function (data) { syncCount = syncCount + 1; $rootScope.$broadcast('UpdateBadges'); if (syncCount == $rootScope.verifiedEmails.length) { logSuccess('Badges successfully synced'); $scope.syncStarted = false; $scope.allSyncStarted = false; } }); } } //save the user's chosen frameworks function saveFrameworks() { var editedFrameworks = []; if (!$scope.frameworks) return; for (var i = 0; i < $scope.frameworks.length; i++) { editedFrameworks.push( { id: $scope.frameworks[i].id, deactivated: $scope.frameworks[i].deactivated }); } user.editIndividualFrameworks(editedFrameworks); } $scope.saveFrameworks = function () { var editedFrameworks = []; if (!$scope.frameworks) return; for (var i = 0; i < $scope.frameworks.length; i++) { editedFrameworks.push( { id: $scope.frameworks[i].id, deactivated: $scope.frameworks[i].deactivated }); } logSuccess('Frameworks saved successfully'); user.editIndividualFrameworks(editedFrameworks); } //get the frameworks for the user function getFrameworks() { return userDataContext.getMyIndividualFrameworks().then(function (theFrameworks) { if (theFrameworks.length > 0) { return frameworks.getFrameworkList(theFrameworks).then(function (data) { $scope.frameworks = data; }); } else $scope.frameworks = []; }); } //get the group names that are discoverable and match the entered value $scope.getDiscoverableGroupNames = function (val) { $scope.loadingAvailableGroups = true; var emails = []; for (i in $scope.user.emailAddresses) { if ($scope.user.emailAddresses[i]) { if ($scope.user.emailAddresses[i].email) { emails.push(vm.user.emailAddresses[i].email) } else { emails.push(vm.user.emailAddresses[i]); } } } return myUsersDataContext.getDiscoverableOrgNames(emails, val).then(function (data) { $scope.availableGroups = data; $scope.loadingAvailableGroups = false; }); } //join a group $scope.joinGroup = function (group, isOrg) { if (group.type == 0) { isOrg = true; } myUsersDataContext.joinToOrganisation(group.id).then(function () { $scope.selectedGroup = { name: "" }; getMyGroups(); $scope.availableGroups = []; if (isOrg) { logSuccess("Joined organisation"); } else { logSuccess("Joined group"); } }); } //leave a group $scope.leaveGroup = function (group, isOrg) { myUsersDataContext.leaveOrganisation(group.id).then(function () { $scope.selectedGroup = { name: "" }; getMyGroups(); if (isOrg) { logSuccess("Left organisation"); } else { logSuccess("Left group"); } }).catch(function (e) { logWarning("You cannot leave the root organisation!"); }); } $scope.newSocialMedia = function (type) { var newSocialMedia = userSettingsService.newSocialMedia(); newSocialMedia.type = type; $scope.user.socialMedias.push(newSocialMedia); } $scope.newTelephone = function (type) { var newTelephone = userSettingsService.newTelephone(); newTelephone.type = type; if ($scope.user.telephones.length == 0) { newTelephone.primary = true; } $scope.user.telephones.push(newTelephone); } $scope.newEmailAddress = function (type) { var newEmailAddress = userSettingsService.newEmailAddress(); newEmailAddress.emailAddressType = type; $scope.user.emailAddresses.push(newEmailAddress); } $scope.newAddress = function (type) { var newAddress = userSettingsService.newAddress(); newAddress.type = type; if ($scope.user.addresses.length == 0) { newAddress.primary = true; } $scope.user.addresses.push(newAddress); } $scope.removeEmailAddress = function (emailModel) { for (i in $scope.user.emailAddresses) { if ($scope.user.emailAddresses[i].email == emailModel.email) { if ($scope.user.emailAddresses[i].id == emailModel.id) { if (!$scope.user.emailAddresses[i].primary) { $scope.user.emailAddresses.splice(i, 1); break; } } else if ($scope.user.emailAddresses[i].email && !$scope.user.emailAddresses[i].id) { if (!$scope.user.emailAddresses[i].primary) { $scope.user.emailAddresses.splice(i, 1); break; } } else if ($scope.user.emailAddresses[i].email == null || $scope.user.emailAddresses[i].email == "") { $scope.user.emailAddresses.splice(i, 1); break; } } } for (i in $scope.invalidEmails) { if ($scope.invalidEmails[i] == emailModel.email) { $scope.invalidEmails.splice(i, 1); } } } $scope.makeEmailAddressPrimary = function (emailModel) { for (i in $scope.user.emailAddresses) { if ($scope.user.emailAddresses[i].primary) { $scope.user.emailAddresses[i].primary = false; } } emailModel.primary = true; } $scope.makeTelephonePrimary = function (telephoneModel) { for (i in $scope.user.telephones) { if ($scope.user.telephones[i].primary) { $scope.user.telephones[i].primary = false; } } telephoneModel.primary = true; } $scope.makeAddressPrimary = function (addressModel) { for (i in $scope.user.addresses) { if ($scope.user.addresses[i].primary) { $scope.user.addresses[i].primary = false; } } addressModel.primary = true; } $scope.getIntegrations = function () { OrganisationAdminService.getTopLevelOrg().then(function (org) { $scope.topLevelOrg = org; //Get myprogress data datacontext.getMyProgressIntegrations($scope.topLevelOrg.id).then(function (data) { //Get canvas data datacontext.getCanvasIntegrations($scope.topLevelOrg.id).then(function (canvasData) { for (var i in canvasData) { if (canvasData[i].connectionType == 0 || canvasData[i].connectionType == 7) //0=myprogress, 7=canvas data.push(canvasData[i]); } $scope.integrations = data; $scope.integrationsLoaded = true; }); }); }); CanvasAdminService.getCurrentUser().then(function (data) { $scope.canvasUser = data; }); } $scope.connectCanvas = function (integration) { var url = integration.systemUrl + 'login/oauth2/auth?client_id=' + integration.primaryKey + '&response_type=code&state=' + integration.id + '&redirect_uri=' + config.myShowcaseAdminSiteUrl + '%23!%2Fcanvas/connect'; window.location = url; } $scope.disconnectCanvas = function () { OrganisationAdminService.getTopLevelOrg().then(function (org) { CanvasAdminService.disconnectCanvas(org.id).then(function (data) { $scope.canvasUser = null; }); }); } $scope.resendEmailVerification = function (email) { userSettingsDataContext.resendEmailVerification(email, null).then(function (data) { logSuccess("Email verification resent"); }); } $scope.updateNotificationSchedule = function () { userSettingsDataContext.updateNotificationSchedule($scope.notificationSchedule); } $scope.selectAllInterests = function () { $scope.notificationSchedule.interest.interestedIn = $scope.availableInterests; $scope.updateNotificationSchedule(); } $scope.selectOnlyInterests = function () { $scope.notificationSchedule.interest.interestedIn = []; $scope.updateNotificationSchedule(); } } }; })();