(function () { 'use strict'; var mod = angular.module('mybadgesAdmin'); var templatePath = modulesSharedResourcesUrl + 'Modules/MyBadgesAdmin/Views/'; // directive for listing created badges mod.directive('badgesList', ['myBadgesDataContext', '$timeout', 'common', '$rootScope', '$location', '$modal', '$q', 'myBadgesAdminService', 'myUsersDataContext', 'myBadgesService', 'myBadgesAdminDataContext', 'myBadgesAdminConfig', 'OrganisationAdminService', 'features', '$injector', function (myBadgesDataContext, $timeout, common, $rootScope, $location, $modal, $q, myBadgesAdminService, myUsersDataContext, myBadgesService, myBadgesAdminDataContext, myBadgesAdminConfig, OrganisationAdminService, features, $injector) { return { restrict: 'E', templateUrl: templatePath + 'badgeslist.html', scope: { features: '=', checkTaskBadge: '=', showSocialMediaClicks: '=' }, link: link }; function link(scope, $scope, elem, attrs) { // set initial page variables var getLogFn = common.logger.getLogFn; var log = getLogFn('graphicsList'); var logSuccess = getLogFn('graphicsList', "success"); var logError = getLogFn('badgesList', "warning"); scope.pageTitle = 'Badges'; scope.orderByPredicateBadge = '-dateCreated'; scope.orderByChoiceBadge = 'Order by creation date'; scope.badgeView = false; scope.tagFilter = ''; var initializing = true; if (scope.checkTaskBadge) { var taskAdminService = $injector.get('taskAdminService'); } // Define the status filters scope.filters = [ { name: 'Draft', value: 0 }, { name: 'Published', value: 1 }, { name: 'Withdrawn', value: 2 } ]; // Set the initail filter values scope.filterValues = [0, 1]; // Apply the status filters scope.applyStatusFilter = function (value, index) { return scope.filterValues.indexOf(value.status) !== -1; } // function to change view to creating a badge scope.createBadgeView = function (pageTitle, template, edit) { scope.badgeView = true; scope.editView = edit; scope.pageTitle = pageTitle; scope.badge = angular.copy(template); } // Get issuers for the dropdown menu function getIssuers() { myBadgesAdminService.getIssuersForUser().then(function (data) { scope.issuers = data; if (scope.issuers.length > 0) { scope.containsValidIssuer = true; $rootScope.containsValidIssuer = true; // scope.activeTabs = 1; } else { // scope.activeTabs = 0; } // $rootScope.activeTab = scope.activeTabs; $rootScope.pageLoaded = true; }); } // Get all the graphics the current user can access function getGraphics() { myBadgesAdminDataContext.getGraphicsForUser().then(function (data) { for (var a = 0; a < data.graphics.length; a++) { if (data.graphics[a].status === 1) { scope.publishedGraphicsExist = true; } } }); } function addRule(template) { OrganisationAdminService.getCurrentOrg().then(function (data) { myBadgesAdminDataContext.addRule(template, data.id).then(function (data) { return true; }); }); } // Get all the badge templates accessible by the current user function getBadgeTemplates() { myBadgesAdminService.getBadgeTemplates().then(function (data) { scope.templates = data; scope.loadedyet = true; scope.allTags = []; scope.allSkills = []; scope.allIssuers = []; // Build a list of tags to filter by for (var i = 0; i < scope.templates.length; i++) { for (var j = 0; j < scope.templates[i].tags.length; j++) { if (scope.allTags.indexOf(scope.templates[i].tags[j]) == -1) scope.allTags.push(scope.templates[i].tags[j]); } for (var j = 0; j < scope.templates[i].skills.length; j++) { if (scope.allSkills.indexOf(scope.templates[i].skills[j]) == -1) scope.allSkills.push(scope.templates[i].skills[j]); } } // Build a list of issuers to filter by for (var i = 0; i < scope.templates.length; i++) { if (scope.allIssuers.indexOf(scope.templates[i].issuer.name) == -1) scope.allIssuers.push(scope.templates[i].issuer.name); } }); } getIssuers(); getBadgeTemplates(); getGraphics(); // Modal to preview a badge template scope.previewTemplate = function (template) { $modal.open({ templateUrl: templatePath + 'previewtemplate.html', controller: previewTemplateController, size: 'lg', windowClass: 'publish-modal', backdrop: 'static', resolve: { template: function () { return template; } } }); } // Controller for previewing badge template var previewTemplateController = function (common, $scope, $modalInstance, template) { $scope.template = template; $scope.socialMediaClicks = scope.showSocialMediaClicks; // close the modal $scope.cancel = function () { $modalInstance.dismiss('cancel'); }; } // Set a template to published scope.publishTemplate = function (template) { template.status = 1; myBadgesAdminService.updateBadgeTemplate(template).then(function () { addRule(template); getBadgeTemplates(); logSuccess('Badge template successfully published'); }); } // Copy a template scope.cloneFormTemplate = function (template) { template.status = 0; template.organisationIds = [$rootScope.currentOrg]; template.name = 'copy- ' + template.name; template.name.substring(0, 100); myBadgesAdminService.createBadgeTemplate(template).then(function (data) { logSuccess('Badge template successfully copied'); getBadgeTemplates(); }); } // badges have been updated scope.$on('UpdateBadges', function () { return getBadgeTemplates(); }); // trigger all subscribers to the SaveBadgeTemplate event scope.saveBadgeTemplate = function () { $rootScope.$broadcast('SaveBadgeTemplate', function () { }); $rootScope.hasChanged = false; } // trigger all subscribers to the PublishBadgeTemplate event scope.publishBadgeTemplate = function () { $rootScope.$broadcast('PublishBadgeTemplate', function () { }); $rootScope.hasChanged = false; } // trigger all subscribers to the SaveBadgeTemplate event scope.saveCurrentBadgeTemplate = function () { $rootScope.$broadcast('SaveCurrentBadgeTemplate', function () { }); $rootScope.hasChanged = false; } // trigger all subscribers to the UpdateBadgeTemplate event scope.updateBadgeTemplate = function () { $rootScope.$broadcast('UpdateBadgeTemplate', function () { }); $rootScope.hasChanged = false; } // Set a template to published scope.publishCurrentTemplate = function () { scope.badge.status = 1; addRule(scope.badge); scope.saveBadgeTemplate(scope.badge); } // Delete a template scope.deleteTemplate = function (templateId) { myBadgesAdminService.deleteBadgeTemplate(templateId).then(function () { getBadgeTemplates(); logSuccess('Badge template successfully deleted'); }); } // Withdraw a template scope.retireTemplate = function (template) { //If the badge is being used on a PUBLISHED task, don't allow it to be retired - it's okay if the task is not published though if (scope.checkTaskBadge) { taskAdminService.badgeIsOnTask(template.id).then(function (result) { if (result.isInUse) { //It's on at least one task //var taskNames = result.taskBadges.map(t => `${t.taskRecordName}`.join(', ')); var taskNames = ""; for (var i in result.taskBadges) { taskNames += result.taskBadges[i].taskRecordName + ', '; } logError('Badge is being used on tasks (' + taskNames.slice(0, -2) + ') and cannot be withdrawn'); return; } else { template.status = 2; myBadgesAdminService.changeBadgeTemplateStatus(template).then(function () { getBadgeTemplates(); logSuccess('Badge template successfully withdrawn'); }); } }); } else { template.status = 2; myBadgesAdminService.changeBadgeTemplateStatus(template).then(function () { getBadgeTemplates(); logSuccess('Badge template successfully withdrawn'); }); } } // function to change view to creating a badge scope.backToBadgeList = function (hasChanged) { $rootScope.hasChanged = false; $rootScope.activeTab = 2; scope.badgeView = false; scope.editView = false; scope.pageTitle = 'Badges'; } } }]); // directive for listing graphics mod.directive('graphicsList', ['$rootScope', '$timeout', 'common', '$http', 'myBadgesDataContext', '$upload', '$location', '$modal', '$q', 'myBadgesAdminService', 'myUsersDataContext', 'myBadgesService', 'myBadgesAdminDataContext', 'myBadgesAdminConfig','OrganisationAdminService', function ($rootScope, $timeout, common, $http, myBadgesDataContext, $upload, $location, $modal, $q, myBadgesAdminService, myUsersDataContext, myBadgesService, myBadgesAdminDataContext, myBadgesAdminConfig, OrganisationAdminService) { return { restrict: 'E', templateUrl: templatePath + 'graphicslist.html', scope: { features: '=' }, link: link }; function link(scope, $scope, elem, attrs) { var getLogFn = common.logger.getLogFn; var log = getLogFn('graphicsList'); var logSuccess = getLogFn('graphicsList', "success"); // set initial page variables scope.pageTitle = 'Badges'; scope.badgeView = false; scope.loadedyet = false; scope.orgIds = []; scope.orderByPredicate = 'dateCreated'; scope.orderByChoice = 'Order by creation date'; scope.infiniteAmount = 10; scope.infiniteAmountAdd = 5; scope.disableScroll = true; scope.searchQueryText = ''; $rootScope.graphicChanged = false; $scope.filterValues = [0, 1]; var initializing = true; // function to change view to creating a graphic $rootScope.createGraphicView = function () { scope.graphicBuilderView = true; scope.pageTitle = 'Create a graphic'; } function showGoBackConfirm() { var modalHtml = ''; modalHtml += ''; $rootScope.hasChanged = false; $modal.open({ template: modalHtml, controller: goBackController, size: 'sm', windowClass: 'center-modal', backdrop: 'static', resolve: { backToGraphicsList: function () { return scope.backToGraphicsList; }, } }); } var goBackController = function ($scope, $modalInstance, backToGraphicsList) { $scope.cancel = function () { $modalInstance.dismiss('cancel'); }; $scope.ok = function () { $modalInstance.dismiss('cancel'); $rootScope.$broadcast('UpdateGraphics'); backToGraphicsList(); } } // function to change view to creating a graphic scope.backToGraphicsListConfirm = function (graphicChanged) { if (graphicChanged) { showGoBackConfirm(); } else { scope.backToGraphicsList(); } } scope.filters = [ { name: 'Draft', value: 0 }, { name: 'Published', value: 1 }, { name: 'Withdrawn', value: 2 } ]; scope.filterValues = [0, 1]; // Apply the status filters scope.applyStatusFilter = function (value, index) { return scope.filterValues.indexOf(value.status) !== -1; } // function to change view to creating a graphic scope.backToGraphicsList = function () { $rootScope.showBuilder = false; $rootScope.$broadcast('UpdateGraphics'); scope.graphicBuilderView = false; scope.pageTitle = 'Badges'; } // function to change view to editing a graphic scope.editGraphic = function (graphic, modal) { modal.dismiss('cancel'); scope.currentGraphic = graphic; scope.isEdit = true; scope.graphicBuilderView = true; scope.pageTitle = 'Create a graphic'; } // graphics have been updated scope.$on('UpdateGraphics', function () { return getGraphics(); }); // Get all the graphics the current user can access function getGraphics() { myBadgesAdminDataContext.getGraphicsForUser().then(function (data) { scope.graphics = data.graphics; for (var a = 0; a < scope.graphics.length; a++) { if (scope.graphics[a].status === 1) { $scope.publishedGraphicsExist = true; } } //scope.pageGraphics(); scope.loadedyet = true; }); } getGraphics(); scope.pageGraphics = function () { scope.graphicsPaginated = scope.graphics.splice(0, scope.infiniteAmount) scope.infiniteAmount = scope.infiniteAmount + scope.infiniteAmountAdd; scope.disableScroll = false; } // delete a graphic scope.deleteGraphic = function (graphicId) { // Save the graphic on succesfull file upload myBadgesAdminDataContext.deleteGraphic(graphicId).then(function (data) { logSuccess('Graphic successfully deleted'); $rootScope.$broadcast('UpdateGraphics'); }); } // publish a graphic scope.publishGraphic = function (graphic) { // publish the graphic graphic.originatorId = $rootScope.currentOrg; graphic.status = 1; myBadgesAdminDataContext.updateGraphic(graphic).then(function (data) { $rootScope.$broadcast('UpdateGraphics'); $rootScope.$broadcast('UpdateBadges'); logSuccess('Graphic successfully published'); }); } // withdraw a graphic scope.withdrawGraphic = function (graphic) { // withdraw the graphic graphic.originatorId = $rootScope.currentOrg; graphic.status = 2; myBadgesAdminDataContext.updateGraphic(graphic).then(function (data) { $rootScope.$broadcast('UpdateGraphics'); $rootScope.$broadcast('UpdateBadges'); logSuccess('Graphic successfully withdrawn'); }); } // copy a graphic scope.copyGraphic = function (graphic) { // withdraw the graphic myBadgesAdminDataContext.cloneGraphic(graphic.id).then(function (data) { $rootScope.$broadcast('UpdateGraphics'); logSuccess('Graphic successfully copied'); }); } // Modal to upload a new graphic scope.uploadNewGraphic = function (graphic, isEdit, editGraphic) { if (isEdit) graphic = angular.copy(graphic); $modal.open({ templateUrl: templatePath + 'uploadgraphic.html', controller: uploadNewGraphicController, size: 'lg', backdrop: 'static', resolve: { graphic: function () { return graphic; }, isEdit: function () { return isEdit; }, orgIds: function () { return scope.orgIds; }, editGraphic: function () { return editGraphic; }, } }); } // graphics have been updated scope.$on('CreateNewGraphic', function () { return scope.createNewGraphic(); }); scope.$on('CreateNew', function () { return scope.createNew(); }); scope.createNew = function () { var index = 1; $modal.open({ templateUrl: templatePath + 'createmodal.html', size: 'sm', controller: createNewController, backdrop: 'static', }); } var createNewController = function ($scope, $modalInstance) { $scope.createNewGraphic = function (graphic, isEdit, editGraphic) { var index = 1; $rootScope.$broadcast('UpdateTab', function (index) { }); $modal.open({ templateUrl: templatePath + 'creategraphicmodal.html', controller: createNewGraphicController, size: 'sm', backdrop: 'static', resolve: { graphic: function () { return graphic; }, isEdit: function () { return false; }, currentGraphic: function () { return $scope.currentGraphic; }, editGraphic: function () { return editGraphic; }, } }); } $scope.uploadNewGraphic = function (graphic, isEdit, editGraphic) { if (isEdit) graphic = angular.copy(graphic); $modal.open({ templateUrl: templatePath + 'uploadgraphic.html', controller: uploadNewGraphicController, size: 'lg', backdrop: 'static', resolve: { graphic: function () { return graphic; }, isEdit: function () { return isEdit; }, orgIds: function () { return scope.orgIds; }, editGraphic: function () { return editGraphic; }, } }); } } // Modal to create new editable graphic scope.createNewGraphic = function (graphic, isEdit, editGraphic) { var index = 1; $rootScope.$broadcast('UpdateTab', function (index) { }); $modal.open({ templateUrl: templatePath + 'creategraphicmodal.html', size: 'sm', backdrop: 'static', resolve: { graphic: function () { return graphic; }, isEdit: function () { return isEdit; }, currentGraphic: function () { return scope.currentGraphic; }, editGraphic: function () { return editGraphic; }, } }); } // Modal to preview a graphic scope.previewGraphic = function (graphic) { $modal.open({ templateUrl: templatePath + 'previewgraphic.html', controller: previewGraphicController, size: 'sm', backdrop: 'static', resolve: { graphic: function () { return graphic; } } }); } // Controller for previewing graphic var previewGraphicController = function (common, $scope, $modalInstance, graphic) { $scope.graphic = graphic; $scope.linkedTemplates = []; myBadgesAdminService.getBadgeTemplates().then(function (data) { for (var i = 0; i < data.length; i++) { if (data[i].graphicId === $scope.graphic.id) $scope.linkedTemplates.push(data[i]) } }); // close the modal $scope.cancel = function () { $modalInstance.dismiss('cancel'); }; } // Controller for creating new graphic var createNewGraphicController = function (common, $scope, $modalInstance, graphic, currentGraphic, editGraphic) { scope.currentGraphic = currentGraphic; OrganisationAdminService.getCurrentOrg().then(function (org) { $scope.editGraphic = editGraphic; $scope.graphic = { name: '', description: '', url: null, source: org.id, lastUpdatedBy: null, originatorId: org.id, ownerType: 0, organisations: [org.id] }; }); $scope.ok = function () { $scope.savingGraphic = true; // Save the new graphic on succesfull file upload myBadgesAdminDataContext.createNewGraphic($scope.graphic).then(function (data) { logSuccess('Graphic successfully created'); $modalInstance.dismiss('cancel'); scope.currentGraphic = data; $rootScope.createGraphicView(); $scope.savingGraphic = false; }); } // close the modal $scope.cancel = function () { $modalInstance.dismiss('cancel'); }; } // Controller for uploading a new graphic var uploadNewGraphicController = function (common, $scope, $modalInstance, graphic, isEdit, orgIds, editGraphic) { $scope.fileName = 'Choose file'; $scope.isEdit = isEdit; $scope.editGraphic = function(graphic) { editGraphic(graphic, $modalInstance) } OrganisationAdminService.getCurrentOrg().then(function (org) { if (isEdit) { $scope.graphic = graphic; $scope.graphic.originatorId = org.id; $scope.imageAdded = true; } else { $scope.graphic = { name: '', description: '', url: null, source: 1, lastUpdatedBy: null, originatorId: org.id, ownerType: 0, organisations: [org.id] }; $scope.imageAdded = false; } }); // Called when image file has been selected $scope.onGraphicSelect = function (files) { $scope.file = files[0]; if ($scope.file && $scope.file.name) { // we're not interested in multiple file uploads here $scope.errorMessage = ''; $scope.graphicHasChanged = true; $scope.fileName = $scope.file.name; files.originalImageFileName = $scope.file.name; files.imageFileSize = $scope.file.size; files.imageFileType = $scope.file.type; $scope.files = files; // check if the user has actually selected an image file else throw an error if ($scope.file.type !== 'image/jpeg' && $scope.file.type !== 'image/png') { $scope.errorMessage = "Please upload a jpeg or a png image file."; return; } // check if the user has selected an image below our maximum file size of 20MB if ($scope.file.size < 20000000) { $scope.imageAdded = true; var reader = new FileReader(); reader.onload = function (e) { $scope.$apply(function () { // get loaded data and render preview. $scope.graphicPreview = e.target.result; }); }; // Generate base 64 image for preview reader.readAsDataURL($scope.file); } else { $scope.errorMessage = 'Image is too large!'; return; } } else { $scope.graphicPreview = null; $scope.imageAdded = false; $scope.graphicHasChanged = true; return; } } //upload graphic to cloudinary function uploadImage(obj, file, success, progress, error, uploadPath) { var data = { upload_preset: cloudinaryUploadPreset, tags: 'mybadges,' }; //images are uploaded to Cloudinary $upload.upload({ url: cloudinaryApiBaseUrl + cloudinaryName + uploadPath, data: data, file: file }).progress(function (e) { var percent = Math.round((e.loaded * 100.0) / e.total); return progress(percent); }).success(function (data, status, headers, config) { return success(obj, data); }).error(function (data) { return error(); }); } //called when a logo is uploaded function UploadSuccess(files, data) { //ensure we always use https data.url = data.url.replace(/^http:\/\//i, 'https://'); //Set the size of the new graphic to 200px data.url = data.url.replace(/upload\//i, 'upload/w_300,h_300,c_pad/'); data.url = data.url.replace(/.jpg/i, '.png'); // Set the newly generated cloudinary url into the graphic object $scope.graphic.url = data.url $scope.graphic.source = 1; if ($scope.isEdit) { // update the graphic $scope.graphic.lastUpdatedBy = $rootScope.currentUser.id; myBadgesAdminDataContext.updateGraphic($scope.graphic).then(function (data) { $rootScope.$broadcast('UpdateGraphics'); logSuccess('Graphic successfully updated'); $scope.isEdit = false; $scope.savingGraphic = false; $modalInstance.dismiss('cancel'); }); } else { // Save the new graphic on succesfull file upload myBadgesAdminDataContext.createNewGraphic($scope.graphic).then(function (data) { $rootScope.$broadcast('UpdateGraphics'); logSuccess('Graphic successfully created'); $scope.isEdit = false; $scope.savingGraphic = false; $modalInstance.dismiss('cancel'); }); } return; } // Generate the image upload process percentage function UploadProgress(percentComplete) { $scope.progress = percentComplete; $scope.uploadStatus = "Uploading... " + percentComplete + "%"; } function UploadError() { // Throw an error } $scope.saveGraphic = function (publish) { if (publish) { $scope.graphic.status = 1; } // Check to see if there is a new graphic $scope.savingGraphic = true; if ($scope.graphicHasChanged) { // Upload the image to cloudinary uploadImage($scope.files, $scope.file, UploadSuccess, UploadProgress, UploadError, cloudinaryUploadPath); } else { // update the graphicwithout uploading the image $scope.graphic.lastUpdatedBy = $rootScope.currentUser.id; myBadgesAdminDataContext.updateGraphic($scope.graphic).then(function (data) { $rootScope.$broadcast('UpdateGraphics'); logSuccess('Graphic successfully updated'); $scope.savingGraphic = false; $modalInstance.dismiss('cancel'); }); } } // close the modal $scope.cancel = function () { $modalInstance.dismiss('cancel'); }; } } }]); // directive for listing issuable badges mod.directive('issueList', ['myBadgesDataContext', 'datacontext','$timeout', 'common', '$rootScope', '$location', '$modal', '$q', 'myBadgesAdminService', 'myUsersDataContext', 'myBadgesService', 'myBadgesAdminDataContext', 'myBadgesAdminConfig','OrganisationAdminService', function (myBadgesDataContext, datacontext, $timeout, common, $rootScope, $location, $modal, $q, myBadgesAdminService, myUsersDataContext, myBadgesService, myBadgesAdminDataContext, myBadgesAdminConfig, OrganisationAdminService) { return { restrict: 'E', templateUrl: templatePath + 'issue.html', scope: { features: '=', licences: '=', showSocialMediaClicks: '=' }, link: link }; function link(scope, $scope, elem, attrs) { // set initial page variables var getLogFn = common.logger.getLogFn; var log = getLogFn('graphicsList'); var logSuccess = getLogFn('graphicsList', "success"); var logError = getLogFn('graphicsList', "warning"); scope.pageTitle = 'Badges'; scope.badgeView = false; scope.loadedyet = false; scope.tagFilter = ''; scope.socialMediaClicks = scope.showSocialMediaClicks; var initializing = true; function addRule(template) { OrganisationAdminService.getCurrentOrg().then(function (data) { myBadgesAdminDataContext.addRule(template, data.id).then(function (data) { return true; }); }); } // Get all the badge templates accessible by the current user function getBadgeTemplates() { myBadgesAdminService.getBadgeTemplates().then(function (data) { scope.templates = data; scope.loadedyet = true; scope.allTags = []; scope.allSkills = []; scope.allIssuers = []; for (var i = 0; i < scope.templates.length; i++) { for (var j = 0; j < scope.templates[i].tags.length; j++) { if (scope.allTags.indexOf(scope.templates[i].tags[j]) == -1) scope.allTags.push(scope.templates[i].tags[j]); } for (var k = 0; k < scope.templates[i].skills.length; k++) { if (scope.allSkills.indexOf(scope.templates[i].skills[k]) == -1) scope.allSkills.push(scope.templates[i].skills[k]); } } for (var i = 0; i < scope.templates.length; i++) { if (scope.allIssuers.indexOf(scope.templates[i].issuer.name) == -1) scope.allIssuers.push(scope.templates[i].issuer.name); } }); } getBadgeTemplates(); // Modal to preview a badge template scope.badgeSummary = function (template) { $modal.open({ templateUrl: templatePath + 'badgesummary.html', controller: myBadgesAdminService.badgeSummaryController, size: 'lg', windowClass: 'publish-modal', backdrop: 'static', resolve: { template: function () { return template; }, showSocialMediaClicks: function () { return scope.showSocialMediaClicks; } } }); }; // Modal to issue a badge template scope.issueTemplate = function (template) { $modal.open({ templateUrl: templatePath + 'issuebadge.html', controller: issueTemplateController, size: 'lg', windowClass: 'publish-modal', backdrop: 'static', resolve: { template: function () { return template; }, features: function () { return scope.features; }, licences: function () { return scope.licences; } } }); } // Controller for issuing badge template var issueTemplateController = function (common, $scope, $rootScope, $modalInstance, template, features, licences, $location) { $scope.licences = licences; $scope.template = template; $scope.orderByChoice = 'Order by date added'; $scope.orderByPredicate = '-dateCreated' // Set up the empty array to hold the users emails and name $scope.emails = []; $scope.errors = []; $scope.issueSuccess = false; $scope.chosenOrganisations = []; $scope.tabActivity = [false, false, false]; // Set up the user object with name and email // Status is wether the baking has been completed or not // Reset the model and also set the form to pristine $scope.attributesDone = true; if ($scope.template.customData.length > 0) { $scope.attributesDone = false; } $scope.tabActivity[0] = true; var path = $location.path(); if (path == '/issue/file') { $scope.tabActivity[0] = false; $scope.tabActivity[2] = true; } if (path == '/issue/group') { $scope.tabActivity[0] = false; $scope.tabActivity[3] = true; } $scope.active = function () { return $scope.tabActivity.indexOf(false) }; $scope.features = features; $scope.confirmAttribute = function () { $scope.attributesDone = true; }; // get not baked issued records function getIssuedRecords(publish) { myBadgesAdminDataContext.getIssuedByTemplate($scope.template.id, 0).then(function (data) { $scope.errors = []; $scope.emails = []; if (publish) { for (var i = 0; i < data.issuedBadges.length; i++) { if (data.issuedBadges[i].error && $scope.emails.indexOf(data.issuedBadges[i].id)) { $scope.containsErrors = true; $scope.issuingInProgress = false; } } $scope.issueSuccess = true; $scope.percentage = 100; $scope.issuingInProgress = false; $rootScope.$broadcast('UpdateLicence'); $scope.containsErrors = false; } for (var i = 0; i < data.issuedBadges.length; i++) { if (data.issuedBadges[i].error) { $scope.errors.push(data.issuedBadges[i]) } else { $scope.emails.push(data.issuedBadges[i]) } } }); } getIssuedRecords(); // new issue record template $scope.issuee = { email: '', name: '', badgeTemplateId: $scope.template.id, customData: $scope.template.customData, status: 0 // 0 - Not baked 1 - Baked, } // Add a new email from the on page form $scope.addNewEmail = function (form) { var exists = false; if ($scope.emails.length > 0) { for (var i = 0; i < $scope.emails.length; i++) { if ($scope.emails[i].email.indexOf($scope.issuee.email) == 0) { var exists = true; } } if (!exists) { myBadgesAdminDataContext.issueBadge($scope.issuee).then(function (data) { logSuccess('Recipient added successfully'); getIssuedRecords(); }); } } else { myBadgesAdminDataContext.issueBadge($scope.issuee).then(function (data) { logSuccess('Recipient added successfully'); getIssuedRecords(); }); } // Reset the model and also set the form to pristine if (form) { form.$setPristine(); } $scope.issuee = { email: '', name: '', badgeTemplateId: $scope.template.id, status: 0, customData: $scope.template.customData } } $scope.onFileSelect = function ($files) { if (!$files[0]) return; $scope.fileName = $files[0].name; if (($files[0].type !== 'application/vnd.ms-excel' && $files[0].type !== 'text/csv') || $scope.fileName.slice($scope.fileName.length - 3, $scope.fileName.length) === 'xls') { $scope.fileIsBad = true; return; } else { $scope.emailsToAdd = []; $scope.fileIsBad = false; $scope.csvValid = true; $scope.emailResults = []; $scope.emailColumn = null; $scope.isJustEmails = false; $scope.fileContainsNoEmails = false; $scope.noUsersSelected = false; Papa.parse($files[0], { complete: function (results) { console.log("Finished:", results.data); if (results.data) { // loop through first emement to determine the index of the email column if (results.data[0]) { for (var i = 0; i < results.data[0].length; i++) { if (results.data[0][i].indexOf('@') !== -1) { $scope.isJustEmails = true; break; } // Check for a column that may contain emails if (results.data[0][i] == 'email' || results.data[0][i] == 'Email' || results.data[0][i] == 'EMAIL' || results.data[0][i] == 'EmailAddress' || results.data[0][i] == 'emailaddress' || results.data[0][i] == 'Emailaddress' || results.data[0][i] == 'emailAddress' || results.data[0][i] == 'PRIMARYEMAIL' || results.data[0][i] == 'EMAILADDRESS' || results.data[0][i] == 'IM_ID' || results.data[0][i] == 'Username' || results.data[0][i] == 'username' || results.data[0][i] == 'User Name' || results.data[0][i] == 'UserName') { $scope.emailColumn = i; } // Check for a column that may contain firstname if (results.data[0][i] == 'name' || results.data[0][i] == 'Name' || results.data[0][i] == 'NAME' || results.data[0][i] == 'firstname' || results.data[0][i] == 'firstName' || results.data[0][i] == 'FirstName' || results.data[0][i] == 'first name' || results.data[0][i] == 'first Name' || results.data[0][i] == 'First Name' || results.data[0][i] == 'FIRSTNAME') { $scope.firstNameColumn = i; } // Check for a column that may contain lastname if (results.data[0][i] == 'surname' || results.data[0][i] == 'Surname' || results.data[0][i] == 'SURNAME' || results.data[0][i] == 'lastname' || results.data[0][i] == 'lastName' || results.data[0][i] == 'LastName' || results.data[0][i] == 'last name' || results.data[0][i] == 'last Name' || results.data[0][i] == 'Last Name' || results.data[0][i] == 'LASTNAME') { $scope.lastNameColumn = i; } } } // If we didn't find an email column it could be down to the file having a title, check second element if (!$scope.emailColumn && !$scope.isJustEmails) { if (results.data[1]) { for (var i = 0; i < results.data[1].length; i++) { // Check for a column that may contain emails if (results.data[1][i] == 'email' || results.data[1][i] == 'Email' || results.data[1][i] == 'EMAIL' || results.data[1][i] == 'EmailAddress' || results.data[1][i] == 'emailaddress' || results.data[1][i] == 'Emailaddress' || results.data[1][i] == 'emailAddress' || results.data[1][i] == 'EMAILADDRESS' || results.data[1][i] == 'PRIMARYEMAIL' || results.data[1][i] == 'IM_ID' || results.data[1][i] == 'Username' || results.data[1][i] == 'username' || results.data[1][i] == 'User Name' || results.data[1][i] == 'UserName') { $scope.emailColumn = i; $scope.emailSecondLine = true; } } } } // Loop through the rest of the data using the found email colum as the object property if ($scope.emailColumn) { if ($scope.emailSecondLine) { var start = 2; } else { var start = 1; } for (i = start; i < results.data.length; i++) { if (results.data[i][$scope.emailColumn]) { if (results.data[i][$scope.emailColumn].indexOf('@') !== -1) { var emailResult = {}; var name = null; emailResult.email = results.data[i][$scope.emailColumn]; if ($scope.firstNameColumn !== null) { name = results.data[i][$scope.firstNameColumn] } if ($scope.lastNameColumn !== null && results.data[i][$scope.lastNameColumn]) { name = name + ' ' + results.data[i][$scope.lastNameColumn] } if (name) { emailResult.name = name; } else { emailResult.name = 'Imported User'; } $scope.emailResults.push(emailResult); $scope.emailsToAdd.push(results.data[i][$scope.emailColumn]); } } } $scope.emailsToAdd = removeDuplicates($scope.emailsToAdd); $scope.emailResults = removeDuplicateModels($scope.emailResults); } // There was no column titles so just loop through the rest the data and check if each ones an email else if ($scope.isJustEmails) { for (i = 0; i < results.data[0].length; i++) { if (results.data[0]) { if (results.data[0][i].indexOf('@') !== -1) { $scope.emailResults.push({ email: results.data[0][i], name: 'Imported User' }); $scope.emailsToAdd.push(results.data[0][i]); } } } $scope.emailsToAdd = removeDuplicates($scope.emailsToAdd); $scope.emailResults = removeDuplicateModels($scope.emailResults); } else { $scope.fileContainsNoEmails = true; } $scope.emailColumn = null; $scope.firstNameColumn = null; $scope.lastNameColumn = null; $scope.emailSecondLine = false; $scope.$apply(); } else { $scope.noResults = true; } } }); } }; function removeDuplicateModels(myArr) { var unique = [] for (var i = 0; i < myArr.length; i++) { var exists = false; for (var j = 0; j < unique.length; j++) { if (unique[j].email == myArr[i].email) exists = true } if (!exists) { unique.push(myArr[i]) } } return unique; } function removeDuplicates(myArr) { var unique_array = myArr.filter(function (elem, index, self) { return index == self.indexOf(elem); }); return unique_array } $scope.pushImportedUsers = function (issue) { if ($scope.emailsToAdd.length > 0) { for (var i = 0; i < $scope.emailsToAdd.length; i++) { for (var j = 0; j < $scope.emailResults.length; j++) { if ($scope.emailsToAdd[i] === $scope.emailResults[j].email) { $scope.issuee = { email: $scope.emailResults[j].email, name: $scope.emailResults[j].name, badgeTemplateId: $scope.template.id, status: 0, customData:$scope.template.customData }; $scope.addNewEmail(); $scope.emailsToAdd.splice(i, 1); } } } } else { $scope.noUsersSelected = true; } $scope.emailResults = []; } $scope.tryToRetryIssue = function (issue) { var exists = false; // Reset the error issue.error = null; for (var i = 0; i < $scope.emails.length; i++) { if ($scope.emails[i].email.indexOf(issue.email) == 0) { var exists = true; } } if (!exists) { // Update the issuing record to a null error myBadgesAdminDataContext.updateIssuedBadge(issue).then(function (data) { logSuccess('User successfully added to issue list'); getIssuedRecords(); }); } else { // Update the issuing record to a null error myBadgesAdminDataContext.deleteIssuedBadge(issue.id).then(function (data) { getIssuedRecords(); }); } } $scope.setIssuers = function () { datacontext.getOrgsUsers($scope.chosenOrganisations).then(function (data) { if (data.length > 0) { for (var j = 0; j < data.length; j++) { $scope.issuee = { email: data[j].email, name: data[j].firstName + " " + data[j].lastName, badgeTemplateId: $scope.template.id, status: 0, userId: data[j].id, customData: $scope.template.customData }; $scope.addNewEmail(); } logSuccess(data.length + " recipients found"); } else { logError('No recipients found in the selection.'); } $scope.chosenOrganisations = []; $scope.tabActivity[0] = true; }); } // Issue the badges $scope.issueBadges = function () { $scope.IssueIds = []; $scope.issuingInProgress = true; // Set the percentage variables $scope.percentage = 0; $scope.numberIssuedSuccesfully = 0; $scope.numberToIssue = $scope.emails.length; // Group all issue ids into an array for processing for (var i = 0; i < $scope.emails.length; i++) { $scope.IssueIds.push($scope.emails[i].id); } OrganisationAdminService.getTopLevelOrg().then(function (data) { logSuccess('Badges have been sent for issuing - Please Wait...'); $scope.issuingInProgress = true; $scope.percentage = 1; $scope.numberIssuedSuccesfully = 0; $rootScope.$broadcast('createClientOnlyNotification', { description: "Badges sent for issuing", notificationType: "badgeIssuingStarted", id: $scope.template.id, total: $scope.numberToIssue, issued: 0, failed: 0, progress: false, finished: false } ); myBadgesAdminDataContext.bakeAndIssue($scope.IssueIds, $rootScope.currentUser.firstName + " " + $rootScope.currentUser.lastName, data.id).then(function (data) { // We call these to tell the user that all badges have been issued and turn the issuing state to false getIssuedRecords(); $rootScope.$broadcast('UpdateBadges'); getIssuedRecords(true); $scope.numberIssuedSuccesfully = $scope.numberToIssue; $scope.template.totalIssued = $scope.template.totalIssued + $scope.numberIssuedSuccesfully; }); $modalInstance.dismiss('cancel'); // Tell the user that the badges have succesfully been sent to the server for issuing }); // Call the baking service with a group of issue ids } /* * Issue a single badge */ $scope.issueSingleBadge = function(issueData) { myBadgesAdminDataContext.issueBadgeThenBake(issueData).then(function (data) { logSuccess('Single badge issued successfully'); }); }; $scope.$on('BadgeIssuingFinished', function (issuedBadgeId, status) { $scope.numberIssuedSuccesfully++; $scope.percentage = (100 / $scope.numberToIssue) * $scope.numberIssuedSuccesfully; getIssuedRecords(); }); // Add a new email from the on page form $scope.removeEmail = function (issueeId, index) { myBadgesAdminDataContext.deleteIssuedBadge(issueeId).then(function (data) { getIssuedRecords(); logSuccess('User removed successfully'); }); } // Add a new email from the on page form $scope.removeError = function (issueeId, index) { myBadgesAdminDataContext.deleteIssuedBadge(issueeId).then(function (data) { getIssuedRecords(); logSuccess('Error removed successfully'); }); } // Save the email template against the badge record $scope.saveEmailTemplate = function () { $scope.template.organisationIds = [$rootScope.currentOrg]; myBadgesAdminService.updateBadgeTemplate($scope.template).then(function (data) { logSuccess('Badge template successfully updated'); }); } // close the modal $scope.cancel = function () { $modalInstance.dismiss('cancel'); }; } } }]); mod.directive('onFinishRender', function ($timeout) { return { restrict: 'A', link: function (scope, element, attr) { if (scope.$last === true) { $timeout(function () { scope.$emit('ngRepeatFinished'); }); } } } }); // directive for creating badges (has own scope) mod.directive('createGraphic', ['myBadgesDataContext', 'common', '$rootScope', '$upload', '$location', '$modal', '$q', 'myBadgesAdminService', 'myUsersDataContext', 'myBadgesService', 'myBadgesAdminDataContext', 'myBadgesAdminConfig', function (myBadgesDataContext, common, $rootScope, $upload, $location, $modal, $q, myBadgesAdminService, myUsersDataContext, myBadgesService, myBadgesAdminDataContext, myBadgesAdminConfig, $filter) { return { restrict: 'E', templateUrl: templatePath + 'creategraphic.html', scope: { currentGraphic: '=' }, link: link }; function link(scope, $scope, elem, attrs) { $rootScope.$watch('features', function () { scope.features = $rootScope.features; }); var getLogFn = common.logger.getLogFn; var log = getLogFn('graphicsList'); var logSuccess = getLogFn('graphicsList', "success"); // set initial page variables $rootScope.showBuilder = true; scope.tags = ['badge']; scope.groupActive = 1; scope.groupIconActive = 'Leisure'; scope.fileNameBackground = 'Choose a background image'; scope.fileNameIcon = 'Choose file'; scope.debounceValue = 100; scope.idealTextColor = function(bgColor) { if (bgColor === 'transparent') return; var nThreshold = 105; var components = getRGBComponents(bgColor); var bgDelta = (components.R * 0.299) + (components.G * 0.587) + (components.B * 0.114); return ((255 - bgDelta) < nThreshold) ? "#000000" : "#ffffff"; } function getRGBComponents(color) { var r = color.substring(1, 3); var g = color.substring(3, 5); var b = color.substring(5, 7); return { R: parseInt(r, 16), G: parseInt(g, 16), B: parseInt(b, 16) }; } function getBase64Image(img) { var canvas = document.createElement("canvas"); canvas.width = img.width; canvas.height = img.height; var ctx = canvas.getContext("2d"); ctx.drawImage(img, 0, 0); var dataURL = canvas.toDataURL("image/png"); return dataURL.replace(/^data:image\/(png|jpg);base64,/, ""); } // Get all the builder assets scope.canvasTemplates = myBadgesAdminService.getCanvasTemplates(); scope.canvasObj = myBadgesAdminService.getCanvasObj(); scope.canvasObj.createdBy = $rootScope.currentUser.id; scope.canvasObjReset = angular.copy(myBadgesAdminService.getCanvasObj()); scope.availableFonts = myBadgesAdminService.getAvailableFonts(); scope.availableShapes = myBadgesAdminService.getAvailableShapes(); scope.availableInnerShapes = myBadgesAdminService.getAvailableInnerShapes(); scope.availableBanners = myBadgesAdminService.getAvailableBanners(); scope.availableIcons = myBadgesAdminService.getAvailableIcons(); scope.canvasObj.shape.snap = true; scope.canvasObj.innerShape.snap = true; scope.canvasObj.banner.snap = true; scope.canvasObj.icon.snap = true; // Reset the individual builder sections scope.resetSection = function (object, name) { scope.canvasObj[name] = angular.copy(scope.canvasObjReset[name]); if (name === 'background') { scope.canvasObj.background.src = null; scope.drawBackgroundCanvas(); } scope.drawTextCanvas(); scope.drawSubTextCanvas(); scope.drawShapeCanvas(); scope.drawInnerShapeCanvas(); scope.drawBannerCanvas(); scope.drawIconCanvas(); }; // Handle layering of canvas' decrement scope.decrement = function (pos, obj) { if (scope.canvasTemplates[pos].pos === -1) { return scope.canvasTemplates[pos].pos; } scope.canvasTemplates[pos].pos = scope.canvasTemplates[pos].pos - 1; scope.canvasObj[obj].order = scope.canvasTemplates[pos].pos; }; // Handle layering of canvas' increment scope.increment = function (pos, obj) { if (scope.canvasTemplates[pos].pos === scope.canvasTemplates.length + 1) { return scope.canvasTemplates[pos].pos; } scope.canvasTemplates[pos].pos = scope.canvasTemplates[pos].pos + 1; scope.canvasObj[obj].order = scope.canvasTemplates[pos].pos; }; // Wait until the canvas DOM elements have finished rendering before running the following scope.$on('ngRepeatFinished', function (ngRepeatFinishedEvent) { // Draw the background canvas scope.drawBackgroundCanvas = function () { if (scope.hasLoaded) scope.hasChanged = true; var canvasBackground = document.getElementById('backgroundCanvas'); var contextBackground = canvasBackground.getContext('2d'); // Clear the canvas and redraw contextBackground.canvas.height = 300; contextBackground.canvas.width = 300; contextBackground.clearRect(0, 0, canvasBackground.width, canvasBackground.height); contextBackground.globalAlpha = scope.canvasObj.background.opacity; if (!scope.canvasObj.background.src) { contextBackground.fillStyle = scope.canvasObj.background.color; contextBackground.fillRect(0, 0, 300, 300); } else { var background = new Image(); background.crossOrigin = "Anonymous"; background.src = scope.canvasObj.background.src; background.onload = function () { contextBackground.globalAlpha = scope.canvasObj.background.opacity; contextBackground.drawImage(background, 0, 0, 300, 300); stackBlurCanvasRGB('backgroundCanvas', 0, 0, 300, 300, scope.canvasObj.background.blur) } } } // Draw the text canvas scope.drawTextCanvas = function () { if (scope.hasLoaded) scope.hasChanged = true; var canvasText = document.getElementById('textCanvas'); var contextText = canvasText.getContext('2d'); // Clear the canvas and redraw contextText.canvas.height = 300; contextText.canvas.width = 300; contextText.clearRect(0, 0, canvasText.width, canvasText.height); contextText.font = scope.canvasObj.text.size + 'px ' + scope.canvasObj.text.font; contextText.fillStyle = scope.canvasObj.text.color; // Move registration point to the center of the canvas contextText.translate(300 / 2, 300 / 2); // Rotate contextText.rotate(scope.canvasObj.text.rotation * Math.PI / 180); // Move registration point back to the top left corner of canvas contextText.translate(-300 / 2, -300 / 2); var splitText = scope.canvasObj.text.textValue.split("\n"); for (var i = 0; i < splitText.length; i++) { contextText.fillText(splitText[i], scope.canvasObj.text.posX, scope.canvasObj.text.posY + ((scope.canvasObj.text.size * i) + (scope.canvasObj.text.size))); } } // Draw the sub text canvas scope.drawSubTextCanvas = function (clear) { if (scope.hasLoaded) scope.hasChanged = true; var canvasSubText = document.getElementById('subTextCanvas'); var contextSubText = canvasSubText.getContext('2d'); // Clear the canvas and redraw contextSubText.canvas.height = 300; contextSubText.canvas.width = 300; contextSubText.clearRect(0, 0, canvasSubText.width, canvasSubText.height); contextSubText.font = scope.canvasObj.subText.size + 'px ' + scope.canvasObj.subText.font; contextSubText.fillStyle = scope.canvasObj.subText.color; // Move registration point to the center of the canvas contextSubText.translate(300 / 2, 300 / 2); // Rotate contextSubText.rotate(scope.canvasObj.subText.rotation * Math.PI / 180); // Move registration point back to the top left corner of canvas contextSubText.translate(-300 / 2, -300 / 2); var splitSubText = scope.canvasObj.subText.textValue.split("\n"); for (var i = 0; i < splitSubText.length; i++) { contextSubText.fillText(splitSubText[i], scope.canvasObj.subText.posX, scope.canvasObj.subText.posY + ((scope.canvasObj.subText.size * i) + (scope.canvasObj.subText.size))); } } // Draw the curved text canvas scope.drawCurvedTextCanvas = function () { if (scope.hasLoaded) scope.hasChanged = true; var canvasCurvedText = document.getElementById('curvedTextCanvas'); var contextCurvedText = canvasCurvedText.getContext('2d'); // Clear the canvas and redraw contextCurvedText.canvas.height = 300; contextCurvedText.canvas.width = 300; contextCurvedText.clearRect(0, 0, canvasCurvedText.width, canvasCurvedText.height); contextCurvedText.font = scope.canvasObj.curvedText.size + 'px ' + scope.canvasObj.curvedText.font; contextCurvedText.fillStyle = scope.canvasObj.curvedText.color; var strlength = scope.canvasObj.curvedText.textValue.length; var increase = scope.canvasObj.curvedText.increase; var oneway = scope.canvasObj.curvedText.textValue; var backway = oneway.split("").reverse().join(""); var angle = Math.PI * scope.canvasObj.curvedText.angle; if (increase > 10) { scope.drawTextAlongArc(contextCurvedText, backway, scope.canvasObj.curvedText.posX, scope.canvasObj.curvedText.posY - (strlength * increase), scope.canvasObj.curvedText.radius - (strlength * increase), angle); } else { scope.drawTextAlongArc(contextCurvedText, oneway, scope.canvasObj.curvedText.posX, scope.canvasObj.curvedText.posY - (strlength * increase), scope.canvasObj.curvedText.radius - (strlength * increase), angle); } //scope.context.fillText(scope.canvasObj.curvedText.text, scope.canvasObj.curvedText.posX, scope.canvasObj.curvedText.posY); } /* Function to create the text arc */ scope.drawTextAlongArc = function (context, str, centerX, centerY, radius, angle) { var len = str.length, s; context.save(); context.translate(centerX, centerY); context.rotate(-1 * angle / 2); context.rotate(-1 * (angle / len) / 2); for (var n = 0; n < len; n++) { context.rotate(angle / len); context.save(); context.translate(0, -1 * radius); s = str[n]; context.fillText(s, 0, 0); context.restore(); } context.restore(); } // Draw the shape canvas scope.drawShapeCanvas = function () { if (scope.hasLoaded) scope.hasChanged = true; var canvasShape = document.getElementById('shapeCanvas'); var contextShape = canvasShape.getContext('2d'); var tintCanvasShape = document.createElement('canvas'); tintCanvasShape.width = 300; tintCanvasShape.height = 300; var tintCtxShape = tintCanvasShape.getContext('2d'); // Clear the canvas and redraw contextShape.canvas.height = 300; contextShape.canvas.width = 300; contextShape.clearRect(0, 0, canvasShape.width, canvasShape.height); // Snap function if (scope.canvasObj.shape.snap) { scope.canvasObj.shape.height = scope.canvasObj.shape.width + 35; } var shape = new Image(); shape.src = scope.canvasObj.shape.src; // can also be a remote URL e.g. http:// shape.onload = function () { contextShape.globalAlpha = scope.canvasObj.shape.opacity; tintCtxShape.globalAlpha = scope.canvasObj.shape.opacity; // Move registration point to the center of the canvas contextShape.translate(300 / 2, 300 / 2); // Rotate contextShape.rotate(scope.canvasObj.shape.rotation * Math.PI / 180); // Move registration point back to the top left corner of canvas contextShape.translate(-300 / 2, -300 / 2); tintCtxShape.fillStyle = scope.canvasObj.shape.color; tintCtxShape.fillRect(0, 0, 300, 300); tintCtxShape.globalCompositeOperation = "destination-atop"; tintCtxShape.drawImage(shape, 0, 0, 300, 300); contextShape.drawImage(shape, scope.canvasObj.shape.posX, scope.canvasObj.shape.posY, scope.canvasObj.shape.width, scope.canvasObj.shape.height); if (scope.canvasObj.shape.opacity > 0.85) contextShape.globalAlpha = 0.85; contextShape.drawImage(tintCanvasShape, scope.canvasObj.shape.posX, scope.canvasObj.shape.posY, scope.canvasObj.shape.width, scope.canvasObj.shape.height); } } // Draw the inner shape canvas scope.drawInnerShapeCanvas = function () { if (scope.hasLoaded) scope.hasChanged = true; var canvasInnerShape = document.getElementById('innerShapeCanvas'); var contextInnerShape = canvasInnerShape.getContext('2d'); var tintCanvasInnerShape = document.createElement('canvas'); tintCanvasInnerShape.width = 300; tintCanvasInnerShape.height = 300; var tintCtxInnerShape = tintCanvasInnerShape.getContext('2d'); // Clear the canvas and redraw contextInnerShape.canvas.height = 300; contextInnerShape.canvas.width = 300; contextInnerShape.clearRect(0, 0, canvasInnerShape.width, canvasInnerShape.height); // Move registration point to the center of the canvas contextInnerShape.translate(300 / 2, 300 / 2); // Rotate contextInnerShape.rotate(scope.canvasObj.innerShape.rotation * Math.PI / 180); // Move registration point back to the top left corner of canvas contextInnerShape.translate(-300 / 2, -300 / 2); // Snap function if (scope.canvasObj.innerShape.snap) { scope.canvasObj.innerShape.height = scope.canvasObj.innerShape.width; } var innerShape = new Image(); innerShape.src = scope.canvasObj.innerShape.src; // can also be a remote URL e.g. http:// innerShape.onload = function () { contextInnerShape.globalAlpha = scope.canvasObj.innerShape.opacity; tintCtxInnerShape.globalAlpha = scope.canvasObj.innerShape.opacity; tintCtxInnerShape.fillStyle = scope.canvasObj.innerShape.color; tintCtxInnerShape.fillRect(0, 0, 300, 300); tintCtxInnerShape.globalCompositeOperation = "destination-atop"; tintCtxInnerShape.drawImage(innerShape, 0, 0, 300, 300); contextInnerShape.drawImage(innerShape, scope.canvasObj.innerShape.posX, scope.canvasObj.innerShape.posY, scope.canvasObj.innerShape.width, scope.canvasObj.innerShape.height); if (scope.canvasObj.innerShape.opacity > 0.95) contextInnerShape.globalAlpha = 0.95; contextInnerShape.drawImage(tintCanvasInnerShape, scope.canvasObj.innerShape.posX, scope.canvasObj.innerShape.posY, scope.canvasObj.innerShape.width, scope.canvasObj.innerShape.height); } } // Draw the banner canvas scope.drawBannerCanvas = function () { if (scope.hasLoaded) scope.hasChanged = true; var canvasBanner = document.getElementById('bannerCanvas'); var contextBanner = canvasBanner.getContext('2d'); var tintCanvasBanner = document.createElement('canvas'); tintCanvasBanner.width = 300; tintCanvasBanner.height = 300; var tintCtxBanner = tintCanvasBanner.getContext('2d'); // Clear the canvas and redraw contextBanner.canvas.height = 300; contextBanner.canvas.width = 300; contextBanner.clearRect(0, 0, canvasBanner.width, canvasBanner.height); // Move registration point to the center of the canvas contextBanner.translate(300 / 2, 300 / 2); // Rotate contextBanner.rotate(scope.canvasObj.banner.rotation * Math.PI / 180); // Move registration point back to the top left corner of canvas contextBanner.translate(-300 / 2, -300 / 2); // Snap function if (scope.canvasObj.banner.snap) { scope.canvasObj.banner.height = scope.canvasObj.banner.width; } var banner = new Image(); banner.src = scope.canvasObj.banner.src; // can also be a remote URL e.g. http:// banner.onload = function () { contextBanner.globalAlpha = scope.canvasObj.banner.opacity; tintCtxBanner.globalAlpha = scope.canvasObj.banner.opacity; tintCtxBanner.fillStyle = scope.canvasObj.banner.color; tintCtxBanner.fillRect(0, 0, 300, 300); tintCtxBanner.globalCompositeOperation = "destination-atop"; tintCtxBanner.drawImage(banner, 0, 0, 300, 300); contextBanner.drawImage(banner, scope.canvasObj.banner.posX, scope.canvasObj.banner.posY, scope.canvasObj.banner.width, scope.canvasObj.banner.height); if (scope.canvasObj.banner.opacity > 0.5) contextBanner.globalAlpha = 0.5; contextBanner.drawImage(tintCanvasBanner, scope.canvasObj.banner.posX, scope.canvasObj.banner.posY, scope.canvasObj.banner.width, scope.canvasObj.banner.height); } } // Draw the icon canvas scope.drawIconCanvas = function () { if (scope.hasLoaded) scope.hasChanged = true; var cloudinaryRegExp = new RegExp('res.cloudinary.com'); if (cloudinaryRegExp.test(scope.canvasObj.icon.src)) { var cloudinaryImage = true; } else { var cloudinaryImage = false; } var canvasIcon = document.getElementById('iconCanvas'); var contextIcon = canvasIcon.getContext('2d'); var tintCanvasIcon = document.createElement('canvas'); tintCanvasIcon.width = 300; tintCanvasIcon.height = 300; var tintCtxIcon = tintCanvasIcon.getContext('2d'); // Clear the canvas and redraw contextIcon.canvas.height = 300; contextIcon.canvas.width = 300; contextIcon.clearRect(0, 0, canvasIcon.width, canvasIcon.height); // Move registration point to the center of the canvas contextIcon.translate(300 / 2, 300 / 2); // Rotate contextIcon.rotate(scope.canvasObj.icon.rotation * Math.PI / 180); // Move registration point back to the top left corner of canvas contextIcon.translate(-300 / 2, -300 / 2); // Snap function if (scope.canvasObj.icon.snap) { scope.canvasObj.icon.height = scope.canvasObj.icon.width; } var icon = new Image(); icon.setAttribute('crossOrigin', 'anonymous'); icon.src = scope.canvasObj.icon.src; // can also be a remote URL e.g. http:// icon.onload = function () { contextIcon.globalAlpha = scope.canvasObj.icon.opacity; tintCtxIcon.globalAlpha = scope.canvasObj.icon.opacity; tintCtxIcon.fillStyle = scope.canvasObj.icon.color; tintCtxIcon.fillRect(0, 0, 300, 300); tintCtxIcon.globalCompositeOperation = "destination-atop"; tintCtxIcon.drawImage(icon, 0, 0, 300, 300); contextIcon.drawImage(icon, scope.canvasObj.icon.posX, scope.canvasObj.icon.posY, scope.canvasObj.icon.width, scope.canvasObj.icon.height); if (scope.canvasObj.icon.opacity > 0.75) contextIcon.globalAlpha = 0.75; if (!cloudinaryImage) contextIcon.drawImage(tintCanvasIcon, scope.canvasObj.icon.posX, scope.canvasObj.icon.posY, scope.canvasObj.icon.width, scope.canvasObj.icon.height); } } scope.onFileSelect = function (files, type) { scope.file = files[0]; // we're not interested in multiple file uploads here scope.errorMessage = ''; scope.graphicHasChanged = true; if (scope.file && scope.file.name) { if (type === 'background') { scope.fileNameBackground = scope.file.name; } if (type === 'icon') { scope.fileNameIcon = scope.file.name; } files.originalImageFileName = scope.file.name; files.imageFileSize = scope.file.size; files.imageFileType = scope.file.type; // check if the user has actually selected an image file else throw an error if (scope.file.type !== 'image/jpeg' && scope.file.type !== 'image/png') { scope.errorMessage = "Please upload either a jpeg or a png file."; return; } } else { scope.graphicHasChanged = true; return; } //upload graphic to cloudinary function uploadImage(obj, file, success, progress, error, uploadPath) { var data = { upload_preset: cloudinaryUploadPreset, tags: 'mybadges' }; //images are uploaded to Cloudinary $upload.upload({ url: cloudinaryApiBaseUrl + cloudinaryName + uploadPath, data: { upload_preset: cloudinaryUploadPreset, tags: 'badgeelement', context: 'photo=' + 'badge', file: file } }).progress(function (e) { var percent = Math.round((e.loaded * 100.0) / e.total); return progress(percent); }).success(function (data, status, headers, config) { return success(obj, data); }).error(function (data) { return error(); }); } //called when a logo is uploaded function ElementUploadSuccess(files, data) { data.url = data.url.replace(/^http:\/\//i, 'https://'); scope.showFinished = false; if (type === 'background') { scope.canvasObj.background.src = data.url scope.drawBackgroundCanvas(); } if (type === 'icon') { scope.canvasObj.icon.src = data.url scope.drawIconCanvas(); } files = null; } // Generate the image upload process percentage function UploadProgress(percentComplete) { $scope.progress = percentComplete; $scope.uploadStatus = "Uploading... " + percentComplete + "%"; } function UploadError() { // Throw an error } // check if the user has selected an image below our maximum file size of 20MB if (scope.file.size < 20000000) { scope.imageAdded = true; uploadImage(scope.file, scope.file, ElementUploadSuccess, UploadProgress, UploadError, cloudinaryUploadPath); } else { scope.errorMessage = 'Image is too large!'; return; } } // Initiate canvas's function initiate() { scope.drawCurvedTextCanvas(); scope.drawShapeCanvas(); scope.drawBackgroundCanvas(); scope.drawTextCanvas(); scope.drawSubTextCanvas(); scope.drawInnerShapeCanvas(); scope.drawBannerCanvas(); scope.drawIconCanvas(); scope.orginalObj = angular.copy(scope.canvasObj); } WebFont.load({ google: { families: [ 'Lobster', 'Oswald', 'Open Sans Condensed', 'Indie Flower', 'Anton', 'Pacifico', 'Sigmar One', 'Shadows Into Light', 'Quicksand', 'Orbitron', 'Amatic SC', 'Dancing Script', 'Pathway Gothic One', 'Righteous', 'Bangers', 'Kaushan Script', 'Russo One', 'Quattrocento Sans', 'Chewy', 'Yellowtail', 'Satisfy', 'Economica', 'Coming Soon', 'Rock Salt', 'Special Elite', 'Pinyon Script', 'Homenaje', 'Overlock', 'Julius Sans One' ] }, custom: { families: [ 'Entypo', 'Heydings Controls', 'Heydings Icons', 'Web Symbols' ], urls: ['/assets/fonts.css'] }, active: function () { scope.$apply(); initiate(); scope.loadedCanvas = true; scope.hasLoaded = true; scope.$apply(); }, }); // Check if we are editing and if so then get the layering data for selected graphic if (scope.currentGraphic) { myBadgesAdminDataContext.getLayeringByGraphic(scope.currentGraphic.id).then(function (data) { scope.canvasObj = data.graphicBuilderLayeringModel; initiate(); }); } scope.saveLayeringData = function (mode, back) { if (mode === 'publish') { scope.currentGraphic.status = 1; } scope.canvasObj.badgeGraphicId = scope.currentGraphic.id; scope.showFinished = true; scope.createPngFile(back); } scope.createPngFile = function (back) { scope.showFinished = true; scope.errorMessageBlank = ''; scope.canvasIsBlank = false; scope.hasChanged = false; scope.backgroundCanvas = document.getElementById('backgroundCanvas'); scope.textCanvas = document.getElementById('textCanvas'); scope.subTextCanvas = document.getElementById('subTextCanvas'); scope.shapeCanvas = document.getElementById('shapeCanvas'); scope.innerShapeCanvas = document.getElementById('innerShapeCanvas'); scope.bannerCanvas = document.getElementById('bannerCanvas'); scope.iconCanvas = document.getElementById('iconCanvas'); scope.curvedTextCanvas = document.getElementById('curvedTextCanvas'); scope.canvas = document.getElementById('finishedCanvas'); scope.context = scope.canvas.getContext('2d'); // Clear the canvas and redraw scope.context.canvas.height = 300; scope.context.canvas.width = 300; scope.temp = $('#rmb-preview').children(); var blank = document.createElement('canvas'); blank.width = 300; blank.height = 300; for (var a = 0; a < scope.temp.length; a++) { if (scope.temp[a].id == 'backgroundCanvas') scope.context.drawImage(scope.backgroundCanvas, 0, 0); if (scope.temp[a].id == 'textCanvas') scope.context.drawImage(scope.textCanvas, 0, 0); if (scope.temp[a].id == 'subTextCanvas') scope.context.drawImage(scope.subTextCanvas, 0, 0); if (scope.temp[a].id == 'shapeCanvas') scope.context.drawImage(scope.shapeCanvas, 0, 0); if (scope.temp[a].id == 'innerShapeCanvas') scope.context.drawImage(scope.innerShapeCanvas, 0, 0); if (scope.temp[a].id == 'bannerCanvas') scope.context.drawImage(scope.bannerCanvas, 0, 0); if (scope.temp[a].id == 'iconCanvas') scope.context.drawImage(scope.iconCanvas, 0, 0); if (scope.temp[a].id == 'curvedTextCanvas') scope.context.drawImage(scope.curvedTextCanvas, 0, 0); } scope.imgData = scope.canvas.toDataURL(); if (scope.canvas.toDataURL() === blank.toDataURL()) { scope.canvasIsBlank = true; scope.errorMessageBlank = 'Your canvas is empty.'; } //upload graphic to cloudinary function uploadImage(obj, file, success, progress, error, uploadPath) { var data = { upload_preset: cloudinaryUploadPreset, tags: 'mybadges' }; //images are uploaded to Cloudinary $upload.upload({ url: cloudinaryApiBaseUrl + cloudinaryName + uploadPath, data: { upload_preset: cloudinaryUploadPreset, tags: 'mybadges', context: 'photo=' + 'badge', file: file } }).progress(function (e) { var percent = Math.round((e.loaded * 100.0) / e.total); return progress(percent); }).success(function (data, status, headers, config) { return success(obj, data); }).error(function (data) { return error(); }); } //called when a logo is uploaded function UploadSuccess(files, data) { data.url = data.url.replace(/^http:\/\//i, 'https://'); scope.showFinished = false; scope.currentGraphic.url = data.url scope.currentGraphic.originatorId = $rootScope.currentOrg; if (!scope.canvasIsBlank) { if (!scope.canvasObj.id) { myBadgesAdminDataContext.createNewLayering(scope.canvasObj).then(function (data) { myBadgesAdminDataContext.updateGraphic(scope.currentGraphic).then(function (data) { $rootScope.$broadcast('UpdateGraphics'); logSuccess('Graphic successfully updated'); }); }); } else { myBadgesAdminDataContext.updateLayering(scope.canvasObj).then(function (data) { myBadgesAdminDataContext.updateGraphic(scope.currentGraphic).then(function (data) { $rootScope.$broadcast('UpdateGraphics'); logSuccess('Graphic successfully updated'); }); }); } } if(!scope.canvasIsBlank) { back(); } scope.showFinished = false; } // Generate the image upload process percentage function UploadProgress(percentComplete) { $scope.progress = percentComplete; $scope.uploadStatus = "Uploading... " + percentComplete + "%"; } function UploadError() { // Throw an error } uploadImage(scope.imgData, scope.imgData, UploadSuccess, UploadProgress, UploadError, cloudinaryUploadPath); } }); } }]); // directive for creating badges (has own scope) mod.directive('createBadge', ['myBadgesDataContext', '$timeout', 'common', '$location', '$modal', '$q', 'myBadgesAdminService', 'myUsersDataContext', 'myBadgesService', 'myBadgesAdminDataContext', 'myBadgesAdminConfig', '$rootScope', '$filter', 'OrganisationAdminService', function (myBadgesDataContext, $timeout, common, $location, $modal, $q, myBadgesAdminService, myUsersDataContext, myBadgesService, myBadgesAdminDataContext, myBadgesAdminConfig, $rootScope, $filter, OrganisationAdminService) { return { restrict: 'E', templateUrl: templatePath + 'createbadge.html', link: link }; /* ** Binding prefixes ********************************* * 1. "@" ( Text binding / one-way binding ) * 2. "=" ( Direct model binding / two-way binding ) * 3. "&" ( Behaviour binding / Method binding ) ***************************************************** */ function link(scope, $scope, elem, attrs) { $rootScope.$watch('features', function () { scope.features = $rootScope.features; }); var getLogFn = common.logger.getLogFn; var log = getLogFn('graphicsList'); var logSuccess = getLogFn('create template', "success"); // set initial page variables scope.orgIds = []; scope.issuers = []; scope.badgeCustomData = { label: null, value: null }; scope.newSkill = { text: null }; scope.orderByPredicateCreate = '-dateCreated'; scope.orderByChoiceGraphic = 'Order by creation date' scope.saving = false; $scope.organisations = []; var initializing = true; if (scope.badge == null) { scope.badge = { criteriaType: 0, customData: [], skills: [] }; } if (scope.badge.criteria != null) { scope.badge.criteriaText = scope.badge.criteria.value; } if (scope.badge.skills) { scope.badge.skills = scope.badge.skills.sort(); } if (scope.badge.tags) { scope.badge.tags = scope.badge.tags.sort(); } if (scope.badge.expiryUnit == null) { scope.badge.expiryUnit = "0"; } scope.orgIds = $rootScope.orgIds; getBadgeTemplates(); getIssuers(); getGraphics(); getLanguages(); // Get issuers for the dropdown menu function getIssuers() { myBadgesAdminService.getIssuersForUser().then(function (data) { scope.issuers = data; // Once the issuers are retrieved, set the selected issuer if editing a badge if (scope.badge.issuer != null) { var issuer = $filter('filter')(scope.issuers, { id: scope.badge.issuer.id }, true); if (issuer) { scope.badge.issuer = issuer[0]; } } if (scope.issuers.length === 1) { scope.badge.issuer = scope.issuers[0]; } }); } function getLanguages() { scope.languages = [ { code: "en-US", name: "English - United States" }, { code: "en-GB", name: "English - United Kingdom" }, {code: "af-ZA", name: "Afrikaans-South Africa" }, {code: "sq-AL", name: "Albanian-Albania" }, {code: "ar-DZ", name: "Arabic-Algeria" }, {code: "ar-BH", name: "Arabic-Bahrain" }, {code: "ar-EG", name: "Arabic-Egypt" }, {code: "ar-IQ", name: "Arabic-Iraq" }, {code: "ar-JO", name: "Arabic-Jordan" }, {code: "ar-KW", name: "Arabic-Kuwait" }, {code: "ar-LB", name: "Arabic-Lebanon" }, {code: "ar-LY", name: "Arabic-Libya" }, {code: "ar-MA", name: "Arabic-Morocco" }, {code: "ar-OM", name: "Arabic-Oman" }, {code: "ar-QA", name: "Arabic-Qatar" }, {code: "ar-SA", name: "Arabic-Saudi Arabia" }, {code: "ar-SY", name: "Arabic-Syria" }, {code: "ar-TN", name: "Arabic-Tunisia" }, {code: "ar-AE", name: "Arabic-United Arab Emirates" }, {code: "ar-YE", name: "Arabic-Yemen" }, {code: "hy-AM", name: "Armenian-Armenia" }, {code: "Cy-az-AZ", name: "Azeri (Cyrillic)" }, {code: "Lt-az-AZ", name: "Azeri (Latin)" }, {code: "eu-ES", name: "Basque-Basque" }, {code: "be-BY", name: "Belarusian-Belarus" }, {code: "bg-BG", name: "Bulgarian-Bulgaria" }, {code: "ca-ES", name: "Catalan-Catalan" }, {code: "zh-CN", name: "Chinese-China" }, {code: "zh-HK", name: "Chinese-Hong Kong" }, {code: "zh-MO", name: "Chinese-Macau" }, {code: "zh-SG", name: "Chinese-Singapore" }, {code: "zh-TW", name: "Chinese-Taiwan" }, {code: "zh-CHS", name: "Chinese (Simplified)" }, {code: "zh-CHT", name: "Chinese (Traditional)" }, {code: "hr-HR", name: "Croatian-Croatia" }, {code: "cs-CZ", name: "Czech-Czech Republic" }, {code: "da-DK", name: "Danish-Denmark" }, {code: "div-MV", name: "Dhivehi-Maldives" }, {code: "nl-BE", name: "Dutch-Belgium" }, {code: "nl-NL", name: "Dutch-The Netherlands" }, {code: "en-AU", name: "English-Australia" }, {code: "en-BZ", name: "English-Belize" }, {code: "en-CA", name: "English-Canada" }, {code: "en-CB", name: "English-Caribbean" }, {code: "en-IE", name: "English-Ireland" }, {code: "en-JM", name: "English-Jamaica" }, {code: "en-NZ", name: "English-New Zealand" }, {code: "en-PH", name: "English-Philippines" }, {code: "en-ZA", name: "English-South Africa" }, {code: "en-TT", name: "English-Trinidad and Tobago" }, {code: "en-ZW", name: "English-Zimbabwe" }, {code: "et-EE", name: "Estonian-Estonia" }, {code: "fo-FO", name: "Faroese-Faroe Islands" }, {code: "fa-IR", name: "Farsi-Iran" }, {code: "fi-FI", name: "Finnish-Finland" }, {code: "fr-BE", name: "French-Belgium" }, {code: "fr-CA", name: "French-Canada" }, {code: "fr-FR", name: "French-France" }, {code: "fr-LU", name: "French-Luxembourg" }, {code: "fr-MC", name: "French-Monaco" }, {code: "fr-CH", name: "French-Switzerland" }, {code: "gl-ES", name: "Galician-Galician" }, {code: "ka-GE", name: "Georgian-Georgia" }, {code: "de-AT", name: "German-Austria" }, {code: "de-DE", name: "German-Germany" }, {code: "de-LI", name: "German-Liechtenstein" }, {code: "de-LU", name: "German-Luxembourg" }, {code: "de-CH", name: "German-Switzerland" }, {code: "el-GR", name: "Greek-Greece" }, {code: "gu-IN", name: "Gujarati-India" }, {code: "he-IL", name: "Hebrew-Israel" }, {code: "hi-IN", name: "Hindi-India" }, {code: "hu-HU", name: "Hungarian-Hungary" }, {code: "is-IS", name: "Icelandic-Iceland" }, {code: "id-ID", name: "Indonesian-Indonesia" }, {code: "it-IT", name: "Italian-Italy" }, {code: "it-CH", name: "Italian-Switzerland" }, {code: "ja-JP", name: "Japanese-Japan" }, {code: "kn-IN", name: "Kannada-India" }, {code: "kk-KZ", name: "Kazakh-Kazakhstan" }, {code: "kok-IN", name: "Konkani-India" }, {code: "ko-KR", name: "Korean-Korea" }, {code: "ky-KZ", name: "Kyrgyz-Kazakhstan" }, {code: "lv-LV", name: "Latvian-Latvia" }, {code: "lt-LT", name: "Lithuanian-Lithuania" }, {code: "mk-MK", name: "Macedonian (FYROM)" }, {code: "ms-BN", name: "Malay-Brunei" }, {code: "ms-MY", name: "Malay-Malaysia" }, {code: "mr-IN", name: "Marathi-India" }, {code: "mn-MN", name: "Mongolian-Mongolia" }, {code: "nb-NO", name: "Norwegian (Bokm�l)" }, {code: "nn-NO", name: "Norwegian (Nynorsk)" }, {code: "pl-PL", name: "Polish-Poland" }, {code: "pt-BR", name: "Portuguese-Brazil" }, {code: "pt-PT", name: "Portuguese-Portugal" }, {code: "pa-IN", name: "Punjabi-India" }, {code: "ro-RO", name: "Romanian-Romania" }, {code: "ru-RU", name: "Russian-Russia" }, {code: "sa-IN", name: "Sanskrit-India" }, {code: "Cy-sr-SP", name: "Serbian (Cyrillic)" }, {code: "Lt-sr-SP", name: "Serbian (Latin)" }, {code: "sk-SK", name: "Slovak-Slovakia" }, {code: "sl-SI", name: "Slovenian-Slovenia" }, {code: "es-AR", name: "Spanish-Argentina" }, {code: "es-BO", name: "Spanish-Bolivia" }, {code: "es-CL", name: "Spanish-Chile" }, {code: "es-CO", name: "Spanish-Colombia" }, {code: "es-CR", name: "Spanish-Costa Rica" }, {code: "es-DO", name: "Spanish-Dominican Republic" }, {code: "es-EC", name: "Spanish-Ecuador" }, {code: "es-SV", name: "Spanish-El Salvador" }, {code: "es-GT", name: "Spanish-Guatemala" }, {code: "es-HN", name: "Spanish-Honduras" }, {code: "es-MX", name: "Spanish-Mexico" }, {code: "es-NI", name: "Spanish-Nicaragua" }, {code: "es-PA", name: "Spanish-Panama" }, {code: "es-PY", name: "Spanish-Paraguay" }, {code: "es-PE", name: "Spanish-Peru" }, {code: "es-PR", name: "Spanish-Puerto Rico" }, {code: "es-ES", name: "Spanish-Spain" }, {code: "es-UY", name: "Spanish-Uruguay" }, {code: "es-VE", name: "Spanish-Venezuela" }, {code: "sw-KE", name: "Swahili-Kenya" }, {code: "sv-FI", name: "Swedish-Finland" }, {code: "sv-SE", name: "Swedish-Sweden" }, {code: "syr-SY", name: "Syriac-Syria" }, {code: "ta-IN", name: "Tamil-India" }, {code: "tt-RU", name: "Tatar-Russia" }, {code: "te-IN", name: "Telugu-India" }, {code: "th-TH", name: "Thai-Thailand" }, {code: "tr-TR", name: "Turkish-Turkey" }, {code: "uk-UA", name: "Ukrainian-Ukraine" }, {code: "ur-PK", name: "Urdu-Pakistan" }, {code: "Cy-uz-UZ", name: "Uzbek (Cyrillic)-Uzbekistan" }, {code: "Lt-uz-UZ", name: "Uzbek (Latin)-Uzbekistan" }, {code: "vi-VN", name: "Vietnamese-Vietnam" } ]; var currentLang = navigator.language || navigator.userLanguage; console.log('$translate.use. Lang is: ' + currentLang); if (scope.badge.language == null) { scope.badge.language = currentLang; } } // Get all the badge templates for the users organisation function getBadgeTemplates() { myBadgesAdminService.getBadgeTemplates().then(function (data) { scope.templates = data.templates; scope.loadedyet = true; }); } function addRule(template) { OrganisationAdminService.getCurrentOrg().then(function (data) { myBadgesAdminDataContext.addRule(template, data.id).then(function (data) { return true; }); }); } // Save a badge template scope.saveTemplate = function (callback) { scope.saving = true; $rootScope.hasChanged = false; if (scope.badge.issuer) { scope.badge.organisationIds = [scope.badge.issuer.organisationId]; } scope.badge.organisationIds.push($rootScope.currentOrg); myBadgesAdminService.createBadgeTemplate(scope.badge).then(function (data) { if (scope.badge.status === 1) { addRule(data); logSuccess('Badge successfully published'); } else { logSuccess('Badge successfully created'); } scope.saving = false; $rootScope.$broadcast('UpdateBadges'); return callback(data); }); }; // Update a badge template scope.updateTemplate = function (callback) { scope.saving = true; $rootScope.hasChanged = false; if (scope.badge.issuer) { scope.badge.organisationIds = [scope.badge.issuer.organisationId]; } scope.badge.organisationIds.push($rootScope.currentOrg); myBadgesAdminService.updateBadgeTemplate(scope.badge).then(function (data) { if (scope.badge.status === 1) { addRule(scope.badge); logSuccess('Badge successfully published'); } else { logSuccess('Badge successfully updated'); } scope.saving = false; $rootScope.$broadcast('UpdateBadges'); return callback(data); }); }; // Determine if the badge model has changed scope.badgeHasChanged = function () { $rootScope.hasChanged = true; } // Set properties on a template making it ready to be saved as draft function setTemplateProperties() { if (scope.badge.criteriaType === 0) { scope.badge.criteria = { type: scope.badge.criteriaType, value: scope.badge.criteriaText, url: scope.badge.criteriaText, } } if (scope.badge.criteriaType === 1) { scope.badge.criteria = { type: scope.badge.criteriaType, value: scope.badge.criteriaUrl, url: scope.badge.criteriaUrl, } } scope.badge.category = 0; scope.badge.issuerId = scope.badge.issuer.id; scope.badge.createdBy = $rootScope.currentUser.id; scope.badge.tags = getTagsFromArray(scope.badge.tags); scope.badge.organisationIds = [$rootScope.currentOrg]; } function getTagsFromArray(tagsArray) { var tagNames = []; for (i in tagsArray) { tagNames.push(tagsArray[i].text); } return tagNames.sort(); } scope.addCustomData = function (form) { scope.badge.customData.push(scope.badgeCustomData); scope.badgeCustomData = { label: null, value: null }; form.$setPristine(); } scope.addSkill = function (form) { scope.badge.skills.push(scope.newSkill.text); scope.newSkill = { text: null }; form.$setPristine(); } scope.$on('SaveBadgeTemplate', function () { $rootScope.hasChanged = false; setTemplateProperties(); scope.saveTemplate(function (data) { scope.backToBadgeList(); $rootScope.$broadcast('UpdateBadges'); }); }); scope.$on('PublishBadgeTemplate', function () { $rootScope.hasChanged = false; setTemplateProperties(); scope.badge.status = 1; if (scope.badge.id) { scope.updateTemplate(function (data) { scope.backToBadgeList(); addRule(scope.badge); $rootScope.$broadcast('UpdateBadges'); }); } else { scope.saveTemplate(function (data) { scope.backToBadgeList(); $rootScope.$broadcast('UpdateBadges'); }); } }); scope.$on('SaveCurrentBadgeTemplate', function () { $rootScope.hasChanged = false; setTemplateProperties(); scope.badge.status = '1'; scope.saveTemplate(function (data) { scope.backToBadgeList(); logSuccess('Badge successfully created and published'); addRule(scope.badge); $rootScope.$broadcast('UpdateBadges'); }); }); // Subscribe to the UpdateBadgeTemplate event and // update the badge template stored in scope when triggered scope.$on('UpdateBadgeTemplate', function () { $rootScope.hasChanged = false; setTemplateProperties(); scope.updateTemplate(function (data) { scope.backToBadgeList(); $rootScope.$broadcast('UpdateBadges'); }); }); // Get all the graphics the current user can access function getGraphics() { myBadgesAdminDataContext.getGraphicsForUser().then(function (data) { scope.graphics = data.graphics; if (scope.badge.graphicId === undefined) { scope.selectedGraphic = false; } else if (scope.badge.graphic) { if (scope.badge.graphic.url !== 'https://uiframework.mkmapps.com/latest/lib/products/myshowcase/images/Badges/badges-placeholder.png' && scope.badge.graphicId !== null) scope.selectedGraphic = true; } else { scope.selectedGraphic = false; } var containsPublished; for (var a = 0; a < scope.graphics.length; a++) { if (scope.graphics[a].status === 1) { containsPublished = true; } if (scope.graphics[a].id === scope.badge.graphicId) { if (scope.graphics[a].status === 2) { scope.graphics[a].status = 1; scope.withdrawnGraphic = scope.graphics[a]; scope.graphicNoLongerPublished = true; //scope.selectedGraphic = false; } } } if (containsPublished) { scope.noPublishedGraphics = false; } else { scope.noPublishedGraphics = true; } scope.loadedyet = true; }); } // Modal to preview an issuer scope.previewIssuer = function (issuer) { // scope.selectedIssuer = ''; //getIssuers(); $modal.open({ templateUrl: templatePath + 'previewissuer.html', controller: previewIssuerController, size: 'sm', backdrop: 'static', resolve: { issuer: function () { return issuer; } } }); } // Controller for previewing badge template var previewIssuerController = function (common, $scope, $modalInstance, issuer) { $scope.selectedIssuer = issuer; // close the modal $scope.cancel = function () { $modalInstance.dismiss('cancel'); }; } // publish a graphic scope.publishGraphic = function (graphic) { // publish the graphic graphic.originatorId = $rootScope.currentOrg; graphic.status = 1; myBadgesAdminDataContext.updateGraphic(graphic).then(function (data) { $rootScope.$broadcast('UpdateGraphics'); addRule(scope.badge); logSuccess('Graphic successfully published'); scope.graphicNoLongerPublished = false; }); } scope.selectGraphic = function (graphic) { if (scope.badge.graphicId === graphic.id) { scope.selectedGraphic = false; scope.badge.graphicId = null; scope.badge.graphic = null; } else { scope.selectedGraphic = true; scope.badge.graphicId = graphic.id; scope.badge.graphic = graphic; } }; scope.removeItem = function (item) { scope.badge.customData.splice(scope.badge.customData.indexOf(item), 1); } scope.removeSkill = function (item) { scope.badge.skills.splice(scope.badge.skills.indexOf(item), 1); } scope.saveTestTemplate = function () { scope.badge = { issuerId: 'C1EC160A-F520-E611-BEBC-001999850D79', graphicId: '0805CF1E-0624-E611-BEBC-001999850D79', criteriaType: 0, criteriaValue: "Badge criteria gobbledygook", name: "Test badge template 1", description: "Test badge template 1", emailText: "You earned this, be proud", category: 0, tags: ["test", "template", "gobbledygook"], organisationIds: scope.orgIds }; scope.saveTemplate(); }; } }]); // directive for creating badges mod.directive('myBadgesReportingSummary', ['myBadgesDataContext', 'config', 'datacontext', '$filter', 'common', '$rootScope', '$location', '$modal', '$q', 'myBadgesAdminService', 'myUsersDataContext', 'myBadgesService', 'myBadgesAdminDataContext', 'myBadgesAdminConfig', 'OrganisationAdminService', 'branding', '$timeout', 'user', function (myBadgesDataContext, config, datacontext, $filter, common, $rootScope, $location, $modal, $q, myBadgesAdminService, myUsersDataContext, myBadgesService, myBadgesAdminDataContext, myBadgesAdminConfig, OrganisationAdminService, branding, $timeout, user) { return { restrict: 'E', scope: { hideTitle: '=', advancedReporting: '=' }, templateUrl: templatePath + 'summary.html', link: link }; function link($scope, elem, attrs) { var templatePath2 = config.modulesSharedResourcesUrl + 'Modules/MyBadgesAdmin/Views/'; var getLogFn = common.logger.getLogFn; var log = getLogFn('myBadgesReporting'); var vm = this; var initializing = true; $scope.branding = branding; $scope.chosenOrgs = []; $scope.showStartDate = false; $scope.showEndDate = false; $scope.graphicsForSelectedOrgs = 0; $scope.badgesForSelectedOrgs = 0; $scope.issuedBadgesForSelectedOrgs = 0; $scope.issuedForDateData = []; $scope.issuedForDateDataAccumulative = []; $scope.dateLabels = []; $scope.series = ['Badges issued on this period']; $scope.showIssuingData = true; $scope.generatingChart = true; $scope.generatingBadgeChart = true; $scope.accumlative = true; $scope.breakdown = false; $scope.showGraphicData = false; $scope.showBadgeData = false; $scope.showBadgeDraft = true; $scope.showBadgePublished = true; $scope.showBadgeWithdrawn = true; $scope.showGraphicDraft = true; $scope.showGraphicPublished = true; $scope.showGraphicWithdrawn = true; $scope.showBreakdown = false; $scope.issuedBadgesForSelectedOrgs = '...'; $scope.badgesForSelectedOrgs = '...'; $scope.graphicsForSelectedOrgs = '...'; var initalized = false; $scope.options = { scaleShowGridLines: true, pointDot: true, legend: true, maintainAspectRatio: false, responsive: true, scaleOverride: true, scaleStartValue: 0, scaleIntegersOnly: true, elements: { line: { tension: 0 } }, scales: { yAxes: [ { id: 'y-axis-1', type: 'linear', display: true, position: 'left', ticks: { min: 0, beginAtZero: true, } }, ] } }; $scope.years = []; $scope.months = [ { month: 'January', days: '31' }, { month: 'February', days: '28' }, { month: 'March', days: '31' }, { month: 'April', days: '30' }, { month: 'May', days: '31' }, { month: 'June', days: '30' }, { month: 'July', days: '31' }, { month: 'August', days: '31' }, { month: 'September', days: '30' }, { month: 'October', days: '31' }, { month: 'November', days: '30' }, { month: 'December', days: '31' }, ]; $scope.today = new Date(); $scope.dd = $scope.today.getDate(); $scope.mm = $scope.today.getMonth() + 1; //January is 0! $scope.yyyy = $scope.today.getFullYear(); $scope.selectedYear = $scope.yyyy; $scope.selectedMonth = $scope.months[$scope.mm - 1].month; $scope.yearCount = $scope.yyyy - 2015; for (var i = 0; i < $scope.yearCount; i++) { $scope.years.push(i); } $scope.filterModel = { startDate: '1 June 2016', endDate: $filter('date')($scope.today, 'dd MMMM yyyy'), badgeTemplateIds: null, dateGrouping: 2 }; $scope.badgeOptions = { scaleOverride: true, scaleStartValue: 0, scales: { xAxes: [{ display: false }], yAxes: [ { id: 'y-axis-1', type: 'linear', display: true, position: 'left', ticks: { min: 0, beginAtZero: true, } }, ] } }; activate(); function activate() { log('Activated Reporting View'); NProgress.done(); if ($location.search().showHelp) { vm.isHelpOpen = true; } } // Daterange filter $scope.dateRangeFilter = function (property, startDate, endDate) { if (!$scope.showIssuingData && $scope.chosenOrgs.length > 0) { return function (item) { if (item[property] === null) return false; var itemDateTime = $filter('date')(item[property], 'EEE dd MMMM yyyy hh:mm'); var startDateTime = startDate + ' 00:00'; var endDateTime = endDate + ' 23:59'; var c = new Date(itemDateTime).getTime(); var s = new Date(startDateTime).getTime(); var e = new Date(endDateTime).getTime(); if (c >= s && c <= e) return true; return false; }; } }; // Determine what will be the best grouping depending on given date range $scope.setDateRange = function () { var startDate = new Date($scope.filterModel.startDate).getTime(); var endDate = new Date($scope.filterModel.endDate).getTime(); var timeDifference = endDate - startDate; if (timeDifference <= 6678400000) { $scope.filterModel.dateGrouping = 2; } if (timeDifference <= 31536000000 && timeDifference >= 6678400000) { $scope.filterModel.dateGrouping = 3; } if (timeDifference > 31536000000) { $scope.filterModel.dateGrouping = 4; } $scope.filterModel.startDate = $filter('date')($scope.filterModel.startDate, 'dd MMMM yyyy'); $scope.filterModel.endDate = $filter('date')($scope.filterModel.endDate, 'dd MMMM yyyy'); if (!initalized) { initalized = true; } else { $scope.setData(); } }; // Select a year and apply to chart $scope.selectYear = function (year) { $scope.allSelected = false; $scope.selectedYear = year; $scope.selectedMonth = null; var orgIds = []; for (i in $scope.allOrgs) { if ($scope.chosenOrgs.indexOf($scope.allOrgs[i]) != -1) { orgIds.push($scope.allOrgs[i]); } } $scope.filterModel = { startDate: '1 January ' + year, endDate: '31 December ' + year, orgIds: orgIds, dateGrouping: 3 } $scope.setData(); }; // Select all and apply to chart $scope.selectAll = function () { $scope.allSelected = true; $scope.selectedYear = null; $scope.selectedMonth = null; var orgIds = []; for (i in $scope.allOrgs) { if ($scope.chosenOrgs.indexOf($scope.allOrgs[i]) != -1) { orgIds.push($scope.allOrgs[i]); } } $scope.filterModel = { startDate: '1 January 2015', endDate: '31 December ' + $scope.yyyy, orgIds: orgIds, dateGrouping: 4 }; $scope.setData(); }; // Select a month and apply to chart $scope.selectMonth = function (month) { $scope.allSelected = false; $scope.selectedMonth = month.month; var orgIds = []; for (i in $scope.allOrgs) { if ($scope.chosenOrgs.indexOf($scope.allOrgs[i]) != -1) { orgIds.push($scope.allOrgs[i]); } } $scope.filterModel = { startDate: '1 ' + month.month + ' ' + $scope.selectedYear, endDate: month.days + ' ' + month.month + ' ' + $scope.selectedYear, orgIds: orgIds, dateGrouping: 2 }; $scope.setData(); }; // Reset the view to initial state $scope.resetData = function () { $scope.filterModel.startDate = angular.copy($scope.resetToDate.startDate); $scope.filterModel.endDate = $filter('date')($scope.today, 'dd MMMM yyyy'); $scope.filterModel.dateGrouping = 2; $scope.showBreakdown = false; $scope.selectedYear = $scope.yyyy; $scope.selectedMonth = $scope.months[$scope.mm - 1].month; $scope.showIssuingData = true; $scope.showBadgeData = false; $scope.showBadgeDraft = true; $scope.showBadgePublished = true; $scope.showBadgeWithdrawn = true; $scope.showGraphicData = false; $scope.showGraphicDraft = true; $scope.showGraphicPublished = true; $scope.showGraphicWithdrawn = true; if ($scope.chosenOrgs.length === $scope.allOrgs.length) { $scope.setData(); } else { $scope.chosenOrgs = angular.copy($scope.allOrgs); } }; // Get all available issuers function getOrganisations() { myUsersDataContext.getOrganisationsFullFlat(0).then(function (data) { handleOrgs(data); }); } //Handle the retrieved orgs data function handleOrgs(data) { user.getProfile().then(function (user) { if (data.length > 0) { $scope.organisations = data; $scope.allOrgs = []; for (i in $scope.organisations) { $scope.allOrgs.push($scope.organisations[i].id); } $scope.chosenOrgs = angular.copy($scope.allOrgs); $scope.filterModel.startDate = $filter('date')(user.createdOn, 'dd MMMM yyyy'); $scope.resetToDate = angular.copy($scope.filterModel); $scope.filterModel.orgIds = $scope.chosenOrgs; $scope.setData('issue'); $scope.orgsLoaded = true; } else { $scope.orgsLoaded = true; $scope.noIssuers = true; } }); } getOrganisations(); $scope.ensureSelected = function (id) { $timeout(function () { if ($scope.chosenOrgs.length == 0) { $scope.chosenOrgs.push(id); } var orgIds = []; for (i in $scope.allOrgs) { if ($scope.chosenOrgs.indexOf($scope.allOrgs[i]) != -1) { orgIds.push($scope.allOrgs[i]); } } $scope.filterModel.orgIds = orgIds; $scope.setData('issue'); return; }, 200); }; // Get all badge templates for selected organisations function getIssuedBadgeTemplateForOrg(orgIds) { $scope.badgeTemplateIds = []; if (orgIds.length === 0) { $scope.badgeTemplates = 0; } else { datacontext.getTemplatesByOrgs(orgIds).then(function (data) { $scope.badgeTemplates = data; for (var i = 0; i < $scope.badgeTemplates.length; i++) { $scope.badgeTemplateIds.push($scope.badgeTemplates[i].id); } getTotalBadgesForTemplateByDate($scope.chosenOrgs); }); } } // Get all badge templates for selected organisations function getIssuedBadgeGraphicsForOrg(orgIds) { if (orgIds.length === 0) { $scope.badgeGraphics = 0; } else { datacontext.getGraphicsByOrg(orgIds).then(function (data) { $scope.badgeGraphics = data.graphics; }); } } // Get issued records for badge template $scope.getBadgeIssuedForTemplate = function (templateId) { $scope.showIssuedId = null; $scope.templateIssuedRecords = null; $scope.showIssuedId = templateId; datacontext.getIssuedByTemplate(templateId, 2).then(function (data) { $scope.templateIssuedRecords = data.issuedBadges; }); }; // Get templates associated with graphic $scope.getBadgeTemplatesForGraphic = function (graphicId) { $scope.linkedGraphicTemplates = []; $scope.showGraphicTemplatesId = graphicId; for (var i = 0; i < $scope.badgeTemplates.length; i++) { if ($scope.badgeTemplates[i].graphicId === graphicId) { $scope.linkedGraphicTemplates.push($scope.badgeTemplates[i]); } } }; // Get templates associated with graphic $scope.resetBadgeTemplatesForGraphic = function (graphicId) { $scope.linkedGraphicTemplates = []; $scope.showGraphicTemplatesId = null; }; // reset templates associated with graphic $scope.resetBadgeIssuedForTemplate = function () { $scope.showIssuedId = null; $scope.templateIssuedRecords = null; $scope.templateIssuedRecords = null; }; // Get total number of badges issued by an issuer in a given date range and grouping function getTotalBadgesByDate(orgIds) { $scope.issuedBadgesForSelectedOrgs = '...'; $scope.data = []; $scope.issuedForDateData = [[]]; $scope.issuedForDateDataAccumulative = [[]]; if ($scope.showIssuingData) { $scope.dateLabels = []; } if ($scope.filterModel.dateGrouping === 0) $scope.dateFormat = "m"; if ($scope.filterModel.dateGrouping === 1) $scope.dateFormat = "H"; if ($scope.filterModel.dateGrouping === 2) $scope.dateFormat = "EEE dd"; if ($scope.filterModel.dateGrouping === 3) $scope.dateFormat = "MMMM"; if ($scope.filterModel.dateGrouping === 4) $scope.dateFormat = "yyyy"; datacontext.getTotalBadgesForDateRange($scope.filterModel).then(function (data) { $scope.issuedBadgesForSelectedOrgs = data.total; if ($scope.showIssuingData || initializing) { if (data.total < 10) { $scope.options.scales.yAxes[0].ticks.max = 10; } else { $scope.options.scales.yAxes[0].ticks.max = undefined; } } for (var i = 0; i < data.groupingModels.length; i++) { $scope.issuedForDateData[0].push(data.groupingModels[i].total); $scope.issuedForDateDataAccumulative[0].push(data.groupingModels[i].accumulativeTotal); if ($scope.showIssuingData) { if (data.groupingModels[i].year && data.groupingModels[i].month === 0) { $scope.dateLabels.push(data.groupingModels[i].year); } else if (data.groupingModels[i].month && data.groupingModels[i].hour === 0) { $scope.dateLabels.push($scope.months[data.groupingModels[i].month - 1].month); } else if (data.groupingModels[i].hour && data.groupingModels[i].month === 0) { $scope.dateLabels.push(data.groupingModels[i].hour + ':00'); } else if (data.groupingModels[i].minute && data.groupingModels[i].month === 0) { $scope.dateLabels.push(data.groupingModels[i].minute); } else { $scope.dateLabels.push($filter('date')(data.groupingModels[i].date, $scope.dateFormat)); } } } if ($scope.showIssuingData && !$scope.showBadgeData && !$scope.showGraphicData) { if ($scope.branding) { $scope.colors = [$scope.branding.secondaryColour]; $scope.badgeColors = [$scope.branding.secondaryColour]; } else if (config.appCode == 'MSA') { $scope.colors = ['#4cae4c']; $scope.badgeColors = ['#4cae4c']; } else { $scope.colors = ['#E52886']; $scope.badgeColors = ['#E52886']; } $scope.series1 = ['Badges issued on up to this point']; $scope.series2 = ['Badges issued for this period']; $scope.accumlativeData = $scope.issuedForDateDataAccumulative; $scope.breakdownData = $scope.issuedForDateData; } $scope.generatingChart = false; }); } // Get total number of badges by an issuer in a given date range function getTotalBadgeTemplatesByDate(orgIds) { $scope.badgesForSelectedOrgs = '...'; $scope.badgeTemplateData = [[]]; $scope.badgeTemplateDataAccumlative = [[]]; if ($scope.showBadgeData) { $scope.dateLabels = []; } if ($scope.filterModel.dateGrouping === 0) $scope.dateFormat = "m"; if ($scope.filterModel.dateGrouping === 1) $scope.dateFormat = "H"; if ($scope.filterModel.dateGrouping === 2) $scope.dateFormat = "EEE dd"; if ($scope.filterModel.dateGrouping === 3) $scope.dateFormat = "MMMM"; if ($scope.filterModel.dateGrouping === 4) $scope.dateFormat = "yyyy"; datacontext.getTotalBadgeTemplatesInDateRange($scope.filterModel).then(function (data) { $scope.badgesForSelectedOrgs = data.total; $scope.badgesForSelectedOrgsDraft = data.totalDraft; $scope.badgesForSelectedOrgsPublished = data.totalPublished; $scope.badgesForSelectedOrgsWithdrawn = data.totalWithdrawn; if ($scope.showBadgeData || initializing) { if (data.total < 10) { $scope.options.scales.yAxes[0].ticks.max = 10; } else { $scope.options.scales.yAxes[0].ticks.max = undefined; } } var tempTotal = 0; var tempAccumulativeTotal = 0; for (var i = 0; i < data.groupingModels.length; i++) { tempTotal = 0; tempAccumulativeTotal = 0 if ($scope.showBadgeDraft) { tempTotal = tempTotal + data.groupingModels[i].totalDraft; tempAccumulativeTotal = tempAccumulativeTotal + data.groupingModels[i].accumulativeDraft; } if ($scope.showBadgePublished) { tempTotal = tempTotal + data.groupingModels[i].totalPublished; tempAccumulativeTotal = tempAccumulativeTotal + data.groupingModels[i].accumulativePublished; } if ($scope.showBadgeWithdrawn) { tempTotal = tempTotal + data.groupingModels[i].totalWithdrawn; tempAccumulativeTotal = tempAccumulativeTotal + data.groupingModels[i].accumulativeWithdrawn; } $scope.badgeTemplateData[0].push(tempTotal); $scope.badgeTemplateDataAccumlative[0].push(tempAccumulativeTotal); if ($scope.showBadgeData) { if (data.groupingModels[i].year && data.groupingModels[i].month === 0) { $scope.dateLabels.push(data.groupingModels[i].year); } else if (data.groupingModels[i].month && data.groupingModels[i].hour === 0) { $scope.dateLabels.push($scope.months[data.groupingModels[i].month - 1].month); } else if (data.groupingModels[i].hour && data.groupingModels[i].month === 0) { $scope.dateLabels.push(data.groupingModels[i].hour + ':00'); } else if (data.groupingModels[i].minute && data.groupingModels[i].month === 0) { $scope.dateLabels.push(data.groupingModels[i].minute); } else { $scope.dateLabels.push($filter('date')(data.groupingModels[i].date, $scope.dateFormat)); } } } if ($scope.showBadgeData && !$scope.showGraphicData && !$scope.showIssuingData) { $scope.colors = ['#ebaa4b']; $scope.series1 = ['Badges created up to this point']; $scope.series2 = ['Badges created on this period']; $scope.accumlativeData = $scope.badgeTemplateDataAccumlative; $scope.breakdownData = $scope.badgeTemplateData; } $scope.generatingChart = false; }); } // Get total number of graphics by an issuer in a given date range function getTotalGraphicsTemplatesByDate(orgIds) { $scope.graphicsForSelectedOrgs = '...'; $scope.badgeGraphicData = [[]]; $scope.badgeGraphicDataAccumlative = [[]]; if ($scope.showGraphicData) { $scope.dateLabels = []; } if ($scope.filterModel.dateGrouping === 0) $scope.dateFormat = "m"; if ($scope.filterModel.dateGrouping === 1) $scope.dateFormat = "H"; if ($scope.filterModel.dateGrouping === 2) $scope.dateFormat = "EEE dd"; if ($scope.filterModel.dateGrouping === 3) $scope.dateFormat = "MMMM"; if ($scope.filterModel.dateGrouping === 4) $scope.dateFormat = "yyyy"; datacontext.getTotalGraphicsInDateRange($scope.filterModel).then(function (data) { $scope.graphicsForSelectedOrgs = data.total; $scope.graphicsForSelectedOrgsDraft = data.totalDraft; $scope.graphicsForSelectedOrgsPublished = data.totalPublished; $scope.graphicsForSelectedOrgsWithdrawn = data.totalWithdrawn; if ($scope.showGraphicData || initializing) { if (data.total < 10) { $scope.options.scales.yAxes[0].ticks.max = 10; } else { $scope.options.scales.yAxes[0].ticks.max = undefined; } } var tempGraphicTotal = 0 var tempGraphicAccumalativeTotal = 0 for (var i = 0; i < data.groupingModels.length; i++) { tempGraphicTotal = 0; tempGraphicAccumalativeTotal = 0 if ($scope.showGraphicDraft) { tempGraphicTotal = tempGraphicTotal + data.groupingModels[i].totalDraft; tempGraphicAccumalativeTotal = tempGraphicAccumalativeTotal + data.groupingModels[i].accumulativeDraft; } if ($scope.showGraphicPublished) { tempGraphicTotal = tempGraphicTotal + data.groupingModels[i].totalPublished; tempGraphicAccumalativeTotal = tempGraphicAccumalativeTotal + data.groupingModels[i].accumulativePublished; } if ($scope.showGraphicWithdrawn) { tempGraphicTotal = tempGraphicTotal + data.groupingModels[i].totalWithdrawn; tempGraphicAccumalativeTotal = tempGraphicAccumalativeTotal + data.groupingModels[i].accumulativeWithdrawn; } $scope.badgeGraphicData[0].push(tempGraphicTotal); $scope.badgeGraphicDataAccumlative[0].push(tempGraphicAccumalativeTotal); if ($scope.showGraphicData) { if (data.groupingModels[i].year && data.groupingModels[i].month === 0) { $scope.dateLabels.push(data.groupingModels[i].year); } else if (data.groupingModels[i].month && data.groupingModels[i].hour === 0) { $scope.dateLabels.push($scope.months[data.groupingModels[i].month - 1].month); } else if (data.groupingModels[i].hour && data.groupingModels[i].month === 0) { $scope.dateLabels.push(data.groupingModels[i].hour + ':00'); } else if (data.groupingModels[i].minute && data.groupingModels[i].month === 0) { $scope.dateLabels.push(data.groupingModels[i].minute); } else { $scope.dateLabels.push($filter('date')(data.groupingModels[i].date, $scope.dateFormat)); } } } if ($scope.showGraphicData && !$scope.showBadgeData && !$scope.showIssuingData) { $scope.colors = ['#009EE3']; $scope.series1 = ['Badge graphics created up to this point']; $scope.series2 = ['Badge graphics created on this period']; $scope.accumlativeData = $scope.badgeGraphicDataAccumlative; $scope.breakdownData = $scope.badgeGraphicData; } $scope.generatingChart = false; }); } // Get total number of badges issued by an issuer in a given date range and grouping function getTotalBadgesForTemplateByDate(orgIds) { $scope.badgeSummaryData = []; $scope.badgeSummaryDataAccumalative = []; if ($scope.filterModel.dateGrouping === 0) $scope.dateFormat = "m"; if ($scope.filterModel.dateGrouping === 1) $scope.dateFormat = "H"; if ($scope.filterModel.dateGrouping === 2) $scope.dateFormat = "EEE dd"; if ($scope.filterModel.dateGrouping === 3) $scope.dateFormat = "MMMM"; if ($scope.filterModel.dateGrouping === 4) $scope.dateFormat = "yyyy"; $scope.filterModel.badgeTemplateIds = $scope.badgeTemplateIds; if ($scope.showBreakdown) { datacontext.getTotalBadgesForTemplateInDateRange($scope.filterModel).then(function (data) { for (var i = 0; i < data.length; i++) { $scope.badgeSummaryData[data[i].badgeTemplateId] = { data: [[]], order: data[i].order }; $scope.badgeSummaryDataAccumalative[data[i].badgeTemplateId] = { data: [[]], order: data[i].order }; if (data[i].issuedBadgesSummary.total === 0) $scope.badgeSummaryData[data[i].badgeTemplateId].order = 'hide'; for (var j = 0; j < data[i].issuedBadgesSummary.groupingModels.length; j++) { $scope.badgeSummaryData[data[i].badgeTemplateId].data[0].push(data[i].issuedBadgesSummary.groupingModels[j].total); $scope.badgeSummaryDataAccumalative[data[i].badgeTemplateId].data[0].push(data[i].issuedBadgesSummary.groupingModels[j].accumulativeTotal); } } $scope.generatingBadgeChart = false; }); } $scope.generatingBadgeChart = false; } $scope.generatePeriodSummary = function (points, evt) { var chosenGrouping = angular.copy($scope.filterModel.dateGrouping); if (points[0] && !$scope.generatingChart && !$scope.generatingBadgeChart) { // Set data if we have selected a year on the chart if (chosenGrouping === 4) { $scope.filterModel.dateGrouping = 3; $scope.filterModel.startDate = '1 ' + $scope.months[0].month + ' ' + $scope.dateLabels[points[0]._index]; $scope.filterModel.endDate = '1 ' + $scope.months[$scope.months.length - 1].month + ' ' + $scope.dateLabels[points[0]._index]; } // Set data if we have selected a month on the chart if (chosenGrouping === 3) { $scope.filterModel.dateGrouping = 2; $scope.selectedMonth = $scope.dateLabels[points[0]._index]; $scope.filterModel.startDate = '1 ' + $scope.months[points[0]._index].month + ' ' + $scope.selectedYear; $scope.filterModel.endDate = $scope.months[points[0]._index].days + ' ' + $scope.months[points[0]._index].month + ' ' + $scope.selectedYear; } // Set data if we have selected a day on the chart if (chosenGrouping === 2) { $scope.filterModel.dateGrouping = 1; var selectedDay = $scope.dateLabels[points[0]._index]; $scope.filterModel.startDate = selectedDay + ' ' + $scope.selectedMonth + ' ' + $scope.selectedYear; $scope.filterModel.endDate = selectedDay + ' ' + $scope.selectedMonth + ' ' + $scope.selectedYear; } // Set data if we have selected a hour on the chart if (chosenGrouping === 1) { $scope.filterModel.dateGrouping = 0; var selectedHour = $scope.dateLabels[points[0]._index]; $scope.filterModel.startDate = $scope.filterModel.startDate + ' ' + selectedHour + ':00'; $scope.filterModel.endDate = $scope.filterModel.endDate + ' ' + selectedHour + ':59'; } $scope.setData(); } }; // Set the required data onto the graph $scope.setData = function (type) { if (type == 'issue') { $scope.showIssuingData = true; $scope.showBadgeData = false; $scope.showGraphicData = false; } if (type == 'badges') { $scope.showIssuingData = false; $scope.showBadgeData = true; $scope.showGraphicData = false; } if (type == 'graphics') { $scope.showIssuingData = false; $scope.showBadgeData = false; $scope.showGraphicData = true; } if ($scope.filterModel.dateGrouping !== 0 || ($scope.showIssuingData || $scope.showBadgeData || $scope.showGraphicData) || $scope.chosenOrgs.length > 0) { $scope.generatingChart = true; $scope.generatingBadgeChart = true; } else { $scope.generatingChart = false; $scope.generatingBadgeChart = false; } getIssuedBadgeTemplateForOrg($scope.chosenOrgs); getIssuedBadgeGraphicsForOrg($scope.chosenOrgs); if ($scope.showGraphicData) { getTotalGraphicsTemplatesByDate($scope.chosenOrgs); initializing = false; return; } if ($scope.showBadgeData) { getTotalBadgeTemplatesByDate($scope.chosenOrgs); initializing = false; return; } if ($scope.showIssuingData) { getTotalBadgesByDate($scope.chosenOrgs); initializing = false; return; } }; // Modal to preview an issuer $scope.previewIssuer = function (issuer) { $modal.open({ templateUrl: templatePath2 + 'previewissuer.html', controller: previewIssuerController, size: 'sm', backdrop: 'static', resolve: { issuer: function () { return issuer; } } }); }; // Controller for previewing badge template var previewIssuerController = function (common, $scope, $modalInstance, issuer) { $scope.selectedIssuer = issuer; // close the modal $scope.cancel = function () { $modalInstance.dismiss('cancel'); }; }; } }]); mod.directive('myBadgesReportingDetail', ['myBadgesDataContext', 'config', 'datacontext', '$filter', 'common', '$rootScope', '$location', '$modal', '$q', 'myBadgesAdminService', 'myUsersDataContext', 'myBadgesService', 'myBadgesAdminDataContext', 'myBadgesAdminConfig', 'OrganisationAdminService', 'branding', '$timeout', 'user', function (myBadgesDataContext, config, datacontext, $filter, common, $rootScope, $location, $modal, $q, myBadgesAdminService, myUsersDataContext, myBadgesService, myBadgesAdminDataContext, myBadgesAdminConfig, OrganisationAdminService, branding, $timeout, user) { return { restrict: 'E', scope: { hideTitle: '=', advancedReporting: '=', showSocialMediaClicks: '=' }, templateUrl: templatePath + 'detail.html', link: link }; function link($scope, elem, attrs) { var getLogFn = common.logger.getLogFn; var log = getLogFn('myBadgesReporting'); var vm = this; var initializing = true; $scope.chosenOrgs = []; $scope.dateLabels = []; $scope.branding = branding; $scope.loaded = false; var initalized = false; $scope.years = []; $scope.months = [ { month: 'Jan', days: '31' }, { month: 'Feb', days: '28' }, { month: 'Mar', days: '31' }, { month: 'Apr', days: '30' }, { month: 'May', days: '31' }, { month: 'Jun', days: '30' }, { month: 'Jul', days: '31' }, { month: 'Aug', days: '31' }, { month: 'Sep', days: '30' }, { month: 'Oct', days: '31' }, { month: 'Nov', days: '30' }, { month: 'Dec', days: '31' } ]; if ($scope.branding) { $scope.colors = [$scope.branding.secondaryColour, $scope.branding.secondaryColour]; $scope.badgeColors = [$scope.branding.secondaryColour, $scope.branding.secondaryColour]; } $scope.today = new Date(); $scope.filterModel = { badgeTemplateIds: null, dateGrouping: 3 }; $scope.datasetOverride = [ { label: "Breakdown", borderWidth: 1, type: 'bar', yAxisID: 'y-axis-1' }, { label: "Cumalative", borderWidth: 3, hoverBackgroundColor: "rgba(255,99,132,0.4)", hoverBorderColor: "rgba(255,99,132,1)", type: 'line', yAxisID: 'y-axis-2' } ]; $scope.options = { responsive: true, maintainAspectRatio: false, scaleOverride: true, scaleStartValue: 0, scaleIntegersOnly: true, elements: { line: { tension: 0 } }, scales: { xAxes: [{ display: true }], yAxes: [ { id: 'y-axis-1', type: 'linear', display: true, position: 'left', ticks: { min: 0, precision: 0, beginAtZero: true }, callback: function (label, index, labels) { if (label > 1000) { return label / 1000 + 'k'; } else { return label; } } }, { id: 'y-axis-2', type: 'linear', display: true, position: 'right', ticks: { min: 0, precision: 0, beginAtZero: true }, callback: function (label, index, labels) { if (label > 1000) { return label / 1000 + 'k'; } else { return label; } } } ] } }; activate(); function activate() { log('Activated Reporting View'); NProgress.done(); if ($location.search().showHelp) { vm.isHelpOpen = true; } } // Daterange filter $scope.dateRangeFilter = function (property, startDate, endDate) { if ($scope.chosenOrgs.length > 0) { return function (item) { if (item[property] === null) return false; var itemDateTime = $filter('date')(item[property], 'EEE dd MMMM yyyy hh:mm'); var startDateTime = startDate + ' 00:00'; var endDateTime = endDate + ' 23:59'; var c = new Date(itemDateTime).getTime(); var s = new Date(startDateTime).getTime(); var e = new Date(endDateTime).getTime(); if (c >= s && c <= e) return true; return false; }; } }; // Determine what will be the best grouping depending on given date range $scope.setDateRange = function () { var startDate = new Date($scope.filterModel.startDate).getTime(); var endDate = new Date($scope.filterModel.endDate).getTime(); var timeDifference = endDate - startDate; if (timeDifference <= 6678400000) { $scope.filterModel.dateGrouping = 2; } if (timeDifference <= 31536000000 && timeDifference >= 6678400000) { $scope.filterModel.dateGrouping = 3; } if (timeDifference > 31536000000) { $scope.filterModel.dateGrouping = 4; } $scope.loaded = false; $scope.filterModel.startDate = $filter('date')($scope.filterModel.startDate, 'dd MMMM yyyy'); $scope.filterModel.endDate = $filter('date')($scope.filterModel.endDate, 'dd MMMM yyyy'); $scope.setData(); }; // Get all available issuers function getOrganisations() { myUsersDataContext.getOrganisationsFullFlatSimple(0).then(function (data) { handleOrgs(data); }); } //Handle the retrieved orgs data function handleOrgs(data) { user.getProfile().then(function (user) { if (data.length > 0) { $scope.organisations = data; $scope.allOrgs = []; for (i in $scope.organisations) { $scope.allOrgs.push($scope.organisations[i].id); } $scope.chosenOrgs = angular.copy($scope.allOrgs); $scope.filterModel.startDate = $filter('date')(moment().subtract(1, 'year').toDate(), "yyyy-MM-dd"); $scope.filterModel.endDate = $filter('date')(moment().toDate(), "yyyy-MM-dd"); $scope.resetToDate = angular.copy($scope.filterModel); $scope.filterModel.orgIds = $scope.chosenOrgs; $scope.setData('issue'); $scope.orgsLoaded = true; } else { $scope.orgsLoaded = true; $scope.noIssuers = true; } }); } getOrganisations(); // Get all badge templates for selected organisations function getIssuedBadgeTemplateForOrg(orgIds) { $scope.badgeTemplateIds = []; if (orgIds.length === 0) { $scope.badgeTemplates = 0; } else { datacontext.getTemplatesByOrgs(orgIds).then(function (data) { $scope.badgeTemplates = data; for (var i = 0; i < $scope.badgeTemplates.length; i++) { $scope.badgeTemplateIds.push($scope.badgeTemplates[i].id); } $scope.loaded = true; getTotalBadgesForTemplateByDate($scope.chosenOrgs); }); } } // Get issued records for badge template $scope.getBadgeIssuedForTemplate = function (templateId) { $scope.showIssuedId = null; $scope.templateIssuedRecords = null; $scope.showIssuedId = templateId; datacontext.getIssuedByTemplate(templateId, 2).then(function (data) { $scope.templateIssuedRecords = data.issuedBadges; }); }; // reset templates associated with graphic $scope.resetBadgeIssuedForTemplate = function () { $scope.showIssuedId = null; $scope.templateIssuedRecords = null; $scope.templateIssuedRecords = null; }; // Get total number of badges issued by an issuer in a given date range and grouping function getTotalBadgesForTemplateByDate() { $scope.badgeData = []; if ($scope.filterModel.dateGrouping === 0) $scope.dateFormat = "m"; if ($scope.filterModel.dateGrouping === 1) $scope.dateFormat = "H"; if ($scope.filterModel.dateGrouping === 2) $scope.dateFormat = "EEE dd"; if ($scope.filterModel.dateGrouping === 3) $scope.dateFormat = "MMMM"; if ($scope.filterModel.dateGrouping === 4) $scope.dateFormat = "yyyy"; $scope.filterModel.badgeTemplateIds = $scope.badgeTemplateIds; $scope.loaded = true; datacontext.getTotalBadgesForTemplateInDateRange($scope.filterModel).then(function (data) { for (var i = 0; i < data.length; i++) { $scope.badgeData[data[i].badgeTemplateId] = { data: [ [], [] ], dateLabels: [], loaded: false }; if (data[i].issuedBadgesSummary.total === 0) $scope.badgeData[data[i].badgeTemplateId].order = 'hide'; for (var j = 0; j < data[i].issuedBadgesSummary.groupingModels.length; j++) { if (data[i].issuedBadgesSummary.groupingModels[j].year && data[i].issuedBadgesSummary.groupingModels[j].month === 0) { $scope.badgeData[data[i].badgeTemplateId].dateLabels.push(data[i].issuedBadgesSummary.groupingModels[j].year); } else if (data[i].issuedBadgesSummary.groupingModels[j].month && data[i].issuedBadgesSummary.groupingModels[j].hour === 0) { $scope.badgeData[data[i].badgeTemplateId].dateLabels.push($scope.months[data[i].issuedBadgesSummary.groupingModels[j].month - 1].month); } else if (data[i].issuedBadgesSummary.groupingModels[j].hour && data[i].issuedBadgesSummary.groupingModels[j].month === 0) { $scope.badgeData[data[i].badgeTemplateId].dateLabels.push(data[i].issuedBadgesSummary.groupingModels[j].hour + ':00'); } else if (data[i].issuedBadgesSummary.groupingModels[j].minute && data[i].issuedBadgesSummary.groupingModels[j].month === 0) { $scope.badgeData[data[i].badgeTemplateId].dateLabels.push(data[i].issuedBadgesSummary.groupingModels[j].minute); } else { $scope.badgeData[data[i].badgeTemplateId].dateLabels.push($filter('date')(data[i].issuedBadgesSummary.groupingModels[j].date, $scope.dateFormat)); } $scope.badgeData[data[i].badgeTemplateId].data[0].push(data[i].issuedBadgesSummary.groupingModels[j].total); $scope.badgeData[data[i].badgeTemplateId].data[1].push(data[i].issuedBadgesSummary.groupingModels[j].accumulativeTotal); } $scope.badgeData[data[i].badgeTemplateId].loaded = true; } }); } // Set the required data onto the graph $scope.setData = function (type) { getIssuedBadgeTemplateForOrg($scope.chosenOrgs); }; // Modal to preview a badge template $scope.badgeSummary = function (template) { $modal.open({ templateUrl: templatePath + 'badgesummary.html', controller: myBadgesAdminService.badgeSummaryController, size: 'lg', windowClass: 'publish-modal', backdrop: 'static', resolve: { template: function () { return template; }, showSocialMediaClicks: function () { return $scope.showSocialMediaClicks; } } }); }; } }]); mod.directive('myBadgesReportingUsers', ['myBadgesDataContext', 'config', 'datacontext', '$filter', 'common', '$rootScope', '$location', '$modal', '$q', 'myBadgesAdminService', 'myUsersDataContext', 'myBadgesService', 'myBadgesAdminDataContext', 'myBadgesAdminConfig', 'OrganisationAdminService', 'brandingService', '$timeout', 'user', function (myBadgesDataContext, config, datacontext, $filter, common, $rootScope, $location, $modal, $q, myBadgesAdminService, myUsersDataContext, myBadgesService, myBadgesAdminDataContext, myBadgesAdminConfig, OrganisationAdminService, brandingService, $timeout, user) { return { restrict: 'E', scope: { hideTitle: '=', advancedReporting: '=', showSocialMediaClicks: '=' }, templateUrl: templatePath + 'users.html', link: link }; function link($scope, elem, attrs) { var getLogFn = common.logger.getLogFn; var log = getLogFn('myBadgesReporting'); var vm = this; $scope.chosenOrgs = []; $scope.loaded = false; var initalized = false; $scope.today = new Date(); $scope.filterModel = { badgeTemplateIds: null, dateGrouping: 3 }; $scope.pagination = { current: 1 }; activate(); function activate() { log('Activated Reporting View'); NProgress.done(); if ($location.search().showHelp) { vm.isHelpOpen = true; } } // Daterange filter $scope.dateRangeFilter = function (property, startDate, endDate) { if ($scope.chosenOrgs.length > 0) { return function (item) { if (item[property] === null) return false; var itemDateTime = $filter('date')(item[property], 'EEE dd MMMM yyyy hh:mm'); var startDateTime = startDate + ' 00:00'; var endDateTime = endDate + ' 23:59'; var c = new Date(itemDateTime).getTime(); var s = new Date(startDateTime).getTime(); var e = new Date(endDateTime).getTime(); if (c >= s && c <= e) return true; return false; }; } }; // Determine what will be the best grouping depending on given date range $scope.setDateRange = function () { var startDate = new Date($scope.filterModel.startDate).getTime(); var endDate = new Date($scope.filterModel.endDate).getTime(); $scope.loaded = false; $scope.setData(); }; // Get all available issuers function getOrganisations() { myUsersDataContext.getOrganisationsFullFlatSimple(0).then(function (data) { handleOrgs(data); }); } //Handle the retrieved orgs data function handleOrgs(data) { user.getProfile().then(function (user) { if (data.length > 0) { $scope.organisations = data; $scope.allOrgs = []; for (i in $scope.organisations) { $scope.allOrgs.push($scope.organisations[i].id); } $scope.chosenOrgs = angular.copy($scope.allOrgs); $scope.filterModel.startDate = $filter('date')(moment().subtract(1, 'year').toDate(), "yyyy-MM-dd"); $scope.filterModel.endDate = $filter('date')(moment().toDate(), "yyyy-MM-dd"); $scope.resetToDate = angular.copy($scope.filterModel); $scope.filterModel.orgIds = $scope.chosenOrgs; $scope.setData(); $scope.orgsLoaded = true; } else { $scope.orgsLoaded = true; $scope.noIssuers = true; } }); } getOrganisations(); // Get all badge templates for selected organisations function getRecipients() { var model = angular.copy($scope.filterModel); model.startDate = $filter('date')(moment(model.startDate).toDate(), "yyyy-MM-dd"); model.endDate = $filter('date')(moment(model.endDate).add(1, 'day').toDate(), "yyyy-MM-dd"); datacontext.getTotalRecipientsForDateRangeByOrg(model).then(function (data) { $scope.recipients = data; $scope.loaded = true; }); } // Set the required data onto the graph $scope.setData = function () { getRecipients($scope.chosenOrgs); }; } }]); mod.directive('myBadgesReportingSocial', ['myBadgesDataContext', 'config', 'datacontext', '$filter', 'common', '$rootScope', '$location', '$modal', '$q', 'myBadgesAdminService', 'myUsersDataContext', 'myBadgesService', 'myBadgesAdminDataContext', 'myBadgesAdminConfig', 'OrganisationAdminService', 'brandingService', '$timeout', 'user', function (myBadgesDataContext, config, datacontext, $filter, common, $rootScope, $location, $modal, $q, myBadgesAdminService, myUsersDataContext, myBadgesService, myBadgesAdminDataContext, myBadgesAdminConfig, OrganisationAdminService, brandingService, $timeout, user) { return { restrict: 'E', scope: { hideTitle: '=', advancedReporting: '=', showSocialMediaClicks: '=' }, templateUrl: templatePath + 'social.html', link: link }; function link($scope, elem, attrs) { var getLogFn = common.logger.getLogFn; var log = getLogFn('myBadgesReporting'); var vm = this; $scope.chosenOrgs = []; $scope.dateLabels = []; $scope.loaded = false; $scope.calendarView = 'month'; $scope.selectedPlatform = ''; $scope.colors = [ '#39569B', '#1C9DEB', '#0093BE', '#0170AD', '#31404e' ]; $scope.today = new Date(); $scope.filterModel = { badgeTemplateIds: null, dateGrouping: 3 }; $scope.setDataSetOverride = function (selectedPlatform) { console.log(selectedPlatform) $scope.datasetOverride = [ { label: "Facebook", borderWidth: 3, type: 'line', yAxisID: 'y-axis', hidden: selectedPlatform !== 'Facebook' && selectedPlatform }, { label: "Twitter", borderWidth: 3, type: 'line', yAxisID: 'y-axis', hidden: selectedPlatform !== 'Twitter' && selectedPlatform }, { label: "Yammer", borderWidth: 3, type: 'line', yAxisID: 'y-axis', hidden: selectedPlatform !== 'Yammer' && selectedPlatform }, { label: "Linkedin", borderWidth: 3, type: 'line', yAxisID: 'y-axis', hidden: selectedPlatform !== 'Linkedin' && selectedPlatform }, { label: "Unknown", borderWidth: 3, type: 'line', yAxisID: 'y-axis', hidden: selectedPlatform !== 'Unknown' && selectedPlatform } ]; }; $scope.setDataSetOverride($scope.selectedPlatform); $scope.options = { responsive: true, maintainAspectRatio: false, scaleOverride: true, scaleStartValue: 0, scaleIntegersOnly: true, elements: { line: { tension: 0 } }, scales: { xAxes: [{ display: true, gridLines: { offsetGridLines: false }, ticks: { callback: function (label, index, labels) { if ($scope.calendarView === 'day') return moment(label).format('d'); if ($scope.calendarView === 'week') return moment(label).format('ww'); if ($scope.calendarView === 'month') return moment(label).format('MMM'); if ($scope.calendarView === 'year') return moment(label).format('YYYY'); } } }], yAxes: [ { id: 'y-axis', type: 'linear', display: true, ticks: { min: 0, precision: 0, beginAtZero: true }, callback: function (label, index, labels) { if (label > 1000) { return label / 1000 + 'k'; } else { return label; } } } ] } }; activate(); function activate() { log('Activated Reporting View'); NProgress.done(); if ($location.search().showHelp) { vm.isHelpOpen = true; } } // Daterange filter $scope.dateRangeFilter = function (property, startDate, endDate) { if ($scope.chosenOrgs.length > 0) { return function (item) { if (item[property] === null) return false; var itemDateTime = $filter('date')(item[property], 'EEE dd MMMM yyyy hh:mm'); var startDateTime = startDate + ' 00:00'; var endDateTime = endDate + ' 23:59'; var c = new Date(itemDateTime).getTime(); var s = new Date(startDateTime).getTime(); var e = new Date(endDateTime).getTime(); if (c >= s && c <= e) return true; return false; }; } }; // Determine what will be the best grouping depending on given date range $scope.setDateRange = function () { var start = new Date($scope.filterModel.startDate).getTime(); var end = new Date($scope.filterModel.endDate).getTime(); var dif = end - start; if (dif < 5184000000) { $scope.calendarView = 'day'; } else if (dif < 8640000000) { $scope.calendarView = 'week'; } else if (dif < 31622400000) { $scope.calendarView = 'month'; } else { $scope.calendarView = 'year'; } $scope.filterModel.startDate = $filter('date')($scope.filterModel.startDate, 'dd MMMM yyyy'); $scope.filterModel.endDate = $filter('date')($scope.filterModel.endDate, 'dd MMMM yyyy'); $scope.loaded = false; $scope.setData(); }; // Get all available issuers function getOrganisations() { myUsersDataContext.getOrganisationsFullFlatSimple(0).then(function (data) { handleOrgs(data); }); } //Handle the retrieved orgs data function handleOrgs(data) { user.getProfile().then(function (user) { if (data.length > 0) { $scope.organisations = data; $scope.allOrgs = []; for (i in $scope.organisations) { $scope.allOrgs.push($scope.organisations[i].id); } $scope.chosenOrgs = angular.copy($scope.allOrgs); $scope.filterModel.startDate = $filter('date')(moment().subtract(1, 'year').toDate(), "yyyy-MM-dd"); $scope.filterModel.endDate = $filter('date')(moment().toDate(), "yyyy-MM-dd"); $scope.resetToDate = angular.copy($scope.filterModel); $scope.filterModel.orgIds = $scope.chosenOrgs; $scope.setData(); $scope.orgsLoaded = true; } else { $scope.orgsLoaded = true; $scope.noIssuers = true; } }); } getOrganisations(); // Get all badge templates for selected organisations function getIssuedBadgeTemplateForOrg(orgIds) { $scope.badgeTemplateIds = []; $scope.badgeData = []; $scope.labels = []; $scope.format = ''; if ($scope.calendarView === 'day') $scope.format = 'YYYY-MM-DD'; if ($scope.calendarView === 'week') $scope.format = 'W'; if ($scope.calendarView === 'month') $scope.format = 'YYYY-MM'; if ($scope.calendarView === 'year') $scope.format = 'YYYY'; $scope.dateStart = moment($scope.filterModel.startDate).startOf($scope.calendarView); $scope.dateEnd = moment($scope.filterModel.endDate).endOf($scope.calendarView); var interim = $scope.dateStart.clone(); while ($scope.dateEnd > interim || interim.format($scope.format) === $scope.dateEnd.format($scope.format)) { $scope.labels.push(interim.format($scope.format)); interim.add(1, $scope.calendarView); } $scope.facebookCount = 0; $scope.twitterCount = 0; $scope.yammerCount = 0; $scope.linkedinCount = 0; $scope.unknownCount = 0; if (orgIds.length === 0) { $scope.badgeTemplates = 0; } else { datacontext.getTemplatesByOrgs(orgIds).then(function (data) { $scope.badgeTemplates = data; for (var i = 0; i < $scope.badgeTemplates.length; i++) { getSocialTrackingRecords($scope.badgeTemplates[i]); } $scope.loaded = true; }); } } function getSocialTrackingRecords(badgeTemplate) { $scope.badgeData[badgeTemplate.id] = { data: [ $scope.labels.map(function () { return 0; }), $scope.labels.map(function () { return 0; }), $scope.labels.map(function () { return 0; }), $scope.labels.map(function () { return 0; }), $scope.labels.map(function () { return 0; }) ], loaded: false }; badgeTemplate.facebookCount = 0; badgeTemplate.twitterCount = 0; badgeTemplate.yammerCount = 0; badgeTemplate.linkedinCount = 0; badgeTemplate.unknownCount = 0; badgeTemplate.total = 0; if (badgeTemplate.issuedBadgeIds) { myBadgesAdminDataContext.getSocialTrackingsForIssuedBadge(badgeTemplate.id, badgeTemplate.issuedBadgeIds).then(function (data) { angular.forEach($filter('orderBy')(data, 'dateCreated'), function (tracking) { if (moment(tracking.dateCreated).isBetween($scope.filterModel.startDate, $scope.filterModel.endDate, 'day', '[]')) { var index = $scope.labels.indexOf(moment(tracking.dateCreated).format($scope.format)); switch (tracking.platform) { case 0: $scope.facebookCount++; badgeTemplate.facebookCount++; for (var i = index; i <= $scope.labels.length; i++) { $scope.badgeData[badgeTemplate.id].data[0][i]++; } break; case 1: $scope.twitterCount++; badgeTemplate.twitterCount++; for (var i = index; i <= $scope.labels.length; i++) { $scope.badgeData[badgeTemplate.id].data[1][i]++; } break; case 2: $scope.yammerCount++; badgeTemplate.yammerCount++; for (var i = index; i <= $scope.labels.length; i++) { $scope.badgeData[badgeTemplate.id].data[2][i]++; } break; case 3: $scope.linkedinCount++; badgeTemplate.linkedinCount++; for (var i = index; i <= $scope.labels.length; i++) { $scope.badgeData[badgeTemplate.id].data[3][i]++; } break; case 4: $scope.unknownCount++; badgeTemplate.unknownCount++; for (var i = index; i <= $scope.labels.length; i++) { $scope.badgeData[badgeTemplate.id].data[4][i]++; } break; default: } } badgeTemplate.total++; }); badgeTemplate.socialTrackings = data; $scope.badgeData[badgeTemplate.id].loaded = true; return badgeTemplate; }); } } // Set the required data onto the graph $scope.setData = function (type) { getIssuedBadgeTemplateForOrg($scope.chosenOrgs); }; // Modal to preview a badge template $scope.badgeSummary = function (template) { $modal.open({ templateUrl: templatePath + 'badgesummary.html', controller: myBadgesAdminService.badgeSummaryController, size: 'lg', windowClass: 'publish-modal', backdrop: 'static', resolve: { template: function () { return template; }, showSocialMediaClicks: function () { return true; } } }); }; } }]); })();