diff --git a/public/dist/application.js b/public/dist/application.js new file mode 100644 index 00000000..9598b6ff --- /dev/null +++ b/public/dist/application.js @@ -0,0 +1,2294 @@ +'use strict'; + +// Init the application configuration module for AngularJS application +var ApplicationConfiguration = (function() { + // Init module configuration options + var applicationModuleName = 'medform'; + var applicationModuleVendorDependencies = ['ngResource', 'ngAnimate', 'ui.router', 'ui.bootstrap', 'ui.utils', 'ngRaven']; + + // Add a new vertical module + var registerModule = function(moduleName, dependencies) { + // Create angular module + angular.module(moduleName, dependencies || []); + + // Add the module to the AngularJS configuration file + angular.module(applicationModuleName).requires.push(moduleName); + }; + + return { + applicationModuleName: applicationModuleName, + applicationModuleVendorDependencies: applicationModuleVendorDependencies, + registerModule: registerModule + }; +})(); +'use strict'; + +//Start by defining the main module and adding the module dependencies +angular.module(ApplicationConfiguration.applicationModuleName, ApplicationConfiguration.applicationModuleVendorDependencies); + +// Setting HTML5 Location Mode +angular.module(ApplicationConfiguration.applicationModuleName).config(['$locationProvider', + function($locationProvider) { + $locationProvider.hashPrefix('!'); + } +]); +angular.module(ApplicationConfiguration.applicationModuleName).run(['$rootScope', '$state', '$stateParams', + function($rootScope, $state, $stateParams) { + + $rootScope.$state = $state; + $rootScope.$stateParams = $stateParams; + + // add previous state property + $rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState) { + console.log(fromState); + $state.previous = fromState; + + //Redirect home to listForms if user is authenticated + if(toState.name === 'home'){ + if($rootScope.authentication.isAuthenticated()){ + event.preventDefault(); // stop current execution + $state.go('listForms'); // go to login + } + } + }); + + } +]); + +//Then define the init function for starting up the application +angular.element(document).ready(function() { + //Fixing facebook bug with redirect + if (window.location.hash === '#_=_') window.location.hash = '#!'; + + //Then init the app + angular.bootstrap(document, [ApplicationConfiguration.applicationModuleName]); +}); +'use strict'; + +// Use Application configuration module to register a new module +ApplicationConfiguration.registerModule('core', ['users']); + +'use strict'; + +// Use Application configuration module to register a new module +ApplicationConfiguration.registerModule('forms', ['ngFileUpload', 'users']); +'use strict'; + +// Use Application configuration module to register a new module +ApplicationConfiguration.registerModule('users'); +'use strict'; + +// Setting up route +angular.module('core').config(['$stateProvider', '$urlRouterProvider', + function($stateProvider, $urlRouterProvider, Authorization) { + // Redirect to home view when route not found + $urlRouterProvider.otherwise('/'); + + // Home state routing + $stateProvider. + state('home', { + url: '/', + templateUrl: 'modules/core/views/home.client.view.html' + }); + + // $urlRouterProvider.otherwise( function($injector) { + // var $state = $injector.get('$state'); + // $state.go('home'); + // }); + + } +]); +'use strict'; + +angular.module('core').controller('HeaderController', ['$rootScope','$scope','Menus', '$state', 'Auth', 'User', + function ($rootScope, $scope, Menus, $state, Auth, User) { + $scope.user = $rootScope.user = Auth.ensureHasCurrentUser(User); + $scope.authentication = $rootScope.authentication = Auth; + $rootScope.languages = $scope.languages = ['english', 'french', 'spanish']; + + $scope.isCollapsed = false; + $scope.hideNav = false; + $scope.menu = Menus.getMenu('topbar'); + + $scope.signout = function() { + var promise = User.logout(); + promise.then(function() { + Auth.logout(); + // Auth.ensureHasCurrentUser(null); + $rootScope.user = null; + $state.go('home'); + }, + function(reason) { + console.log('Logout Failed: ' + reason); + }); + }; + + $scope.toggleCollapsibleMenu = function() { + $scope.isCollapsed = !$scope.isCollapsed; + }; + + // Collapsing the menu after navigation + $scope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) { + $scope.isCollapsed = false; + $scope.hideNav = false; + if ( angular.isDefined( toState.data ) ) { + + if ( angular.isDefined( toState.data.hideNav ) ) { + $scope.hideNav = toState.data.hideNav; + } + } + }); + + // Principal.identity().then(function(user){ + // $rootScope.user = user; + // console.log('topbar') + // console.log($scope.user); + // }, + // function(error){ + // console.log(error); + // }).then(function(){ + // $scope.signout = function() { + // $http.get('/auth/signout').success(function(response) { + // $state.go('home'); + // }).error(function(error) { + // $scope.error = (error.message || error); + // }); + + // Principal.signout().then( + // function(result){ + // $state.go('home'); + // }, + // function(error){ + // $scope.error = (error.message || error); + // } + // ); + // if( angular.isDefined(response_obj.error) ){ + // $scope.error = response_obj.error; + // } else{ + // $state.go('home'); + // } + + // }; + + // }); + + } +]); +'use strict'; + + +angular.module('core').controller('HomeController', ['$rootScope', '$scope', 'User', 'Auth', '$state', + function($rootScope, $scope, User, Auth, $state) { + $scope = $rootScope; + + $scope.user = Auth.ensureHasCurrentUser(User); + $scope.authentication = Auth; + + // if($scope.authentication.isAuthenticated()){ + // $state.go('listForms'); + // } + + } +]); +// 'use strict'; + +// /** +// * @ngdoc function +// * @name medform.controller:IndexCtrl +// * @description +// * # IndexCtrl +// * Controller of core +// */ +// angular.module('medform').controller('IndexCtrl', function ($scope, $rootScope, $location, User, Auth, $state) { +// $rootScope.user = Auth.ensureHasCurrentUser(User); +// // $rootScope.user = Auth.getUserState(User).user; +// $rootScope.authentication = Auth; + +// $scope.signout = function() { +// User.logout(function() { +// Auth.logout(); +// $rootScope.user = null; +// $state.go('home'); +// // $scope.$apply(); +// }); +// }; + + +// }); + +'use strict'; + +//Menu service used for managing menus +angular.module('core').service('Menus', [ + + function() { + // Define a set of default roles + this.defaultRoles = ['*']; + + // Define the menus object + this.menus = {}; + + // A private function for rendering decision + var shouldRender = function(user) { + if (user) { + if (!!~this.roles.indexOf('*')) { + return true; + } else { + for (var userRoleIndex in user.roles) { + for (var roleIndex in this.roles) { + console.log(this.roles[roleIndex]); + console.log( this.roles[roleIndex] === user.roles[userRoleIndex]); + if (this.roles[roleIndex] === user.roles[userRoleIndex]) { + return true; + } + } + } + } + } else { + return this.isPublic; + } + + return false; + }; + + // Validate menu existance + this.validateMenuExistance = function(menuId) { + if (menuId && menuId.length) { + if (this.menus[menuId]) { + return true; + } else { + throw new Error('Menu does not exists'); + } + } else { + throw new Error('MenuId was not provided'); + } + + return false; + }; + + // Get the menu object by menu id + this.getMenu = function(menuId) { + // Validate that the menu exists + this.validateMenuExistance(menuId); + + // Return the menu object + return this.menus[menuId]; + }; + + // Add new menu object by menu id + this.addMenu = function(menuId, isPublic, roles) { + // Create the new menu + this.menus[menuId] = { + isPublic: isPublic || false, + roles: roles || this.defaultRoles, + items: [], + shouldRender: shouldRender + }; + + // Return the menu object + return this.menus[menuId]; + }; + + // Remove existing menu object by menu id + this.removeMenu = function(menuId) { + // Validate that the menu exists + this.validateMenuExistance(menuId); + + // Return the menu object + delete this.menus[menuId]; + }; + + // Add menu item object + this.addMenuItem = function(menuId, menuItemTitle, menuItemURL, menuItemType, menuItemUIRoute, isPublic, roles, position) { + // Validate that the menu exists + this.validateMenuExistance(menuId); + + // Push new menu item + this.menus[menuId].items.push({ + title: menuItemTitle, + link: menuItemURL, + menuItemType: menuItemType || 'item', + menuItemClass: menuItemType, + uiRoute: menuItemUIRoute || ('/' + menuItemURL), + isPublic: ((isPublic === null || typeof isPublic === 'undefined') ? this.menus[menuId].isPublic : isPublic), + roles: ((roles === null || typeof roles === 'undefined') ? this.menus[menuId].roles : roles), + position: position || 0, + items: [], + shouldRender: shouldRender + }); + + // Return the menu object + return this.menus[menuId]; + }; + + // Add submenu item object + this.addSubMenuItem = function(menuId, rootMenuItemURL, menuItemTitle, menuItemURL, menuItemUIRoute, isPublic, roles, position) { + // Validate that the menu exists + this.validateMenuExistance(menuId); + + // Search for menu item + for (var itemIndex in this.menus[menuId].items) { + if (this.menus[menuId].items[itemIndex].link === rootMenuItemURL) { + // Push new submenu item + this.menus[menuId].items[itemIndex].items.push({ + title: menuItemTitle, + link: menuItemURL, + uiRoute: menuItemUIRoute || ('/' + menuItemURL), + isPublic: ((isPublic === null || typeof isPublic === 'undefined') ? this.menus[menuId].items[itemIndex].isPublic : isPublic), + roles: ((roles === null || typeof roles === 'undefined') ? this.menus[menuId].items[itemIndex].roles : roles), + position: position || 0, + shouldRender: shouldRender + }); + } + } + + // Return the menu object + return this.menus[menuId]; + }; + + // Remove existing menu object by menu id + this.removeMenuItem = function(menuId, menuItemURL) { + // Validate that the menu exists + this.validateMenuExistance(menuId); + + // Search for menu item to remove + for (var itemIndex in this.menus[menuId].items) { + if (this.menus[menuId].items[itemIndex].link === menuItemURL) { + this.menus[menuId].items.splice(itemIndex, 1); + } + } + + // Return the menu object + return this.menus[menuId]; + }; + + // Remove existing menu object by menu id + this.removeSubMenuItem = function(menuId, submenuItemURL) { + // Validate that the menu exists + this.validateMenuExistance(menuId); + + // Search for menu item to remove + for (var itemIndex in this.menus[menuId].items) { + for (var subitemIndex in this.menus[menuId].items[itemIndex].items) { + if (this.menus[menuId].items[itemIndex].items[subitemIndex].link === submenuItemURL) { + this.menus[menuId].items[itemIndex].items.splice(subitemIndex, 1); + } + } + } + + // Return the menu object + return this.menus[menuId]; + }; + + //Adding the topbar menu + this.addMenu('topbar', false, ['*']); + + //Adding the bottombar menu for the Form-Footer view + this.addMenu('bottombar', false, ['*']); + } +]); +'use strict'; + +// Configuring the Articles module +angular.module('forms').run(['Menus', + function(Menus) { + // Set top bar menu items + Menus.addMenuItem('topbar', 'My Forms', 'forms', '', '/forms', false); + } +]).filter('formValidity', + function(){ + + return function(formObj){ + //get keys + var formKeys = Object.keys(formObj); + + //we only care about things that don't start with $ + var fieldKeys = formKeys.filter(function(key){ + return key[0] !== '$'; + }); + + var fields = formObj.form_fields; + // fieldKeys.map(function(key){ + // return formObj[key]; + // }); + + var valid_count = fields.filter(function(field){ + if(typeof field === 'object'){ + return !!(field.fieldValue); + } + }).length; + return valid_count; + }; +}); +'use strict'; + +// Setting up route +angular.module('forms').config(['$stateProvider', + + function($stateProvider) { + // Forms state routing + $stateProvider. + state('listForms', { + url: '/forms', + templateUrl: 'modules/forms/views/list-forms.client.view.html', + }). + state('createForm', { + url: '/forms/create', + templateUrl: 'modules/forms/views/create-form.client.view.html', + }). + state('viewForm', { + url: '/forms/:formId/admin', + templateUrl: 'modules/forms/views/view-form.client.view.html', + }). + state('viewPublicForm', { + url: '/forms/:formId', + templateUrl: 'modules/forms/views/view-public-form.client.view.html', + data: { + hideNav: true, + hideFooter: false + }, + }). + state('editForm', { + url: '/forms/:formId/edit', + templateUrl: 'modules/forms/views/create-form.client.view.html', + }); + } +]); +'use strict'; + +angular.module('forms').controller('EditFormController', ['$scope', '$state', '$rootScope', 'Upload', '$stateParams', 'FormFields', 'Forms', 'CurrentForm', '$modal', '$location', '$http', + function ($scope, $state, $rootScope, Upload, $stateParams, FormFields, Forms, CurrentForm, $modal, $location, $http) { + $scope.form = {}; + $scope.isNewForm = false; + $scope.log = ''; + $scope.pdfLoading = false; + var _current_upload = null; + + // Get current form if it exists, or create new one + if($stateParams.formId){ + Forms.get({ formId: $stateParams.formId}, function(form){ + $scope.form = angular.fromJson(angular.toJson(form)); + console.log($scope.form); + }); + } else { + $scope.form.form_fields = []; + $scope.isNewForm = true; + } + + //PDF Functions + $scope.cancelUpload = function(){ + _current_upload.abort(); + $scope.pdfLoading = false; + $scope.removePDF(); + }; + + $scope.removePDF = function(){ + $scope.form.pdf = null; + $scope.form.isGenerated = false; + $scope.form.autofillPDFs = false; + + console.log('form.pdf: '+$scope.form.pdf+' REMOVED'); + }; + + $scope.uploadPDF = function(files) { + + if (files && files.length) { + // for (var i = 0; i < files.length; i++) { + var file = files[0]; + _current_upload = Upload.upload({ + url: '/upload/pdf', + fields: { + 'user': $scope.user, + 'form': $scope.form + }, + file: file + }).progress(function (evt) { + var progressPercentage = parseInt(100.0 * evt.loaded / evt.total); + $scope.log = 'progress: ' + progressPercentage + '% ' + + evt.config.file.name + '\n' + $scope.log; + $scope.pdfLoading = true; + }).success(function (data, status, headers, config) { + $scope.log = 'file ' + data.originalname + ' uploaded as '+ data.name +'. JSON: ' + JSON.stringify(data) + '\n' + $scope.log; + console.log($scope.form.pdf); + $scope.form.pdf = angular.fromJson(angular.toJson(data)); + $scope.pdfLoading = false; + + console.log($scope.log); + console.log('$scope.pdf: '+$scope.form.pdf.name); + if(!$scope.$$phase){ + $scope.$apply(); + } + }).error(function(err){ + $scope.pdfLoading = false; + console.log('Error occured during upload.\n'); + console.log(err); + }); + // } + } + }; + + $rootScope.goToWithId = function(route, id) { + $state.go(route, {'formId': id}, {reload: true}); + }; + + // Create new Form + $rootScope.createOrUpdate = function() { + + if($scope.isNewForm){ + // Create new Form object + var form = new Forms($scope.form); + + $http.post('/forms', {form: $scope.form}) + .success(function(data, status, headers){ + console.log('form created'); + + // Clear form fields + $scope.form = {}; + // Redirect after save + $scope.goToWithId('viewForm', $scope.form._id); + }).error(function(errorResponse){ + console.log(errorResponse); + $scope.error = errorResponse; + }); + } else{ + $scope.update(); + } + }; + + // Update existing Form + $rootScope.update = function() { + var form = new Forms($scope.form); + console.log('update form'); + console.log($scope.form); + + $http.put('/forms/'+$scope.form._id, {form: $scope.form}) + .success(function(data, status, headers){ + console.log('form updated successfully'); + $scope.goToWithId('viewForm', $scope.form._id); + }).error(function(err){ + console.log('Error occured during form UPDATE.\n'); + console.log(err); + }); + // form.$update({formId: $scope.form._id}, function(response) { + // console.log('form successfully updated'); + // $scope.goToWithId('viewForm', response._id); + // }, function(errorResponse) { + // console.log(errorResponse.data.message); + // $scope.error = errorResponse.data.message; + // }); + }; + } +]); + +'use strict'; + +// Forms controller +angular.module('forms').controller('SubmitFormController', ['$scope', '$stateParams', '$state', 'Forms', 'CurrentForm', + function($scope, $stateParams, $state, Forms, CurrentForm) { + + $scope.form = Forms.get({ + formId: $stateParams.formId + }); + CurrentForm.setForm($scope.form); + } +]); +'use strict'; + +// submissions controller +angular.module('forms').controller('ViewSubmissionController', ['$scope', '$stateParams', '$state', 'Submissions','$http', + function($scope, $stateParams, $state, Submissions, $http) { + $scope.submissionId = undefined; + + // Principal.identity().then(function(user){ + // $scope.authentication.user = user; + // }).then(function(){ + + + // Return all form's submissions + $scope.findAll = function() { + $scope.submissions = Submissions.query({ + formId: $stateParams.formId + }); + }; + + // Find a specific submission + $scope.findOne = function() { + $scope.submission = Submissions.get({ + submissionId: $scope.submissionId, + formId: $stateParams.formId + }); + }; + + + // Remove existing submission + $scope.remove = function(submission) { + if (!submission) { + submission = $scope.submission; + } + $http.delete('/forms/'+$stateParams.formId+'/submissions/'+submission._id). + success(function(data, status, headers){ + console.log('submission deleted successfully'); + alert('submission deleted..'); + }); + }; + + + // }); + } +]); +'use strict'; + +// Forms controller +angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope', '$stateParams', '$state', 'Forms', 'CurrentForm','$http', + function($rootScope, $scope, $stateParams, $state, Forms, CurrentForm, $http) { + + + $scope.myform = CurrentForm.getForm(); + $scope.submissions = undefined; + $scope.viewSubmissions = false; + $scope.showCreateModal = false; + $scope.table = { + masterChecker: true, + rows: [] + }; + + $scope.setForm = function (form) { + $scope.myForm = form; + }; + + $scope.openCreateModal = function(){ + if(!$scope.showCreateModal){ + $scope.showCreateModal = true; + } + }; + $scope.closeCreateModal = function(){ + if($scope.showCreateModal){ + $scope.showCreateModal = false; + } + }; + + //Create new form + $scope.createNew = function(){ + var form = {}; + form.title = $scope.myForm.name.$modelValue; + form.language = $scope.myForm.language.$modelValue; + console.log(form); + $scope.showCreateModal = true; + + console.log($scope.myForm); + if($scope.myForm.$valid && $scope.myForm.$dirty){ + $http.post('/forms', {form: form}) + .success(function(data, status, headers){ + console.log('form created'); + + // Clear form fields + $scope.myForm = {}; + // Redirect after save + $scope.goToWithId('viewForm', $scope.myform._id); + }).error(function(errorResponse){ + console.log(errorResponse); + // $scope.error = errorResponse.data.message; + }); + } + }; + + $scope.saveInProgress = false; + $scope.update = function() { + if(!$scope.saveInProgress){ + $scope.saveInProgress = true; + + console.log('start update()'); + + $http.put('/forms/'+$scope.myform._id, {form: $scope.myform}) + .then(function(response){ + console.log('form updated successfully'); + console.log('$scope.saveInProgress: '+$scope.saveInProgress); + // $rootScope.goToWithId('viewForm', $scope.myform._id); + }).catch(function(response){ + console.log('Error occured during form UPDATE.\n'); + console.log(response.data); + }).finally(function() { + $scope.saveInProgress = false; + }); + } + }; + + //Table Functions + $scope.toggleAllCheckers = function(){ + console.log('toggleAllCheckers'); + for(var i=0; i<$scope.table.rows.length; i++){ + $scope.table.rows[i].selected = $scope.table.masterChecker; + } + }; + $scope.toggleObjSelection = function($event, description) { + $event.stopPropagation(); + console.log('checkbox clicked'); + }; + + $scope.rowClicked = function(obj) { + console.log('row clicked'); + obj.selected = !obj.selected; + }; + + //show submissions of Form + $scope.showSubmissions = function(){ + $scope.viewSubmissions = true; + if(!$scope.table.rows.length){ + $http.get('/forms/'+$scope.myform._id+'/submissions') + .success(function(data, status, headers){ + console.log(data); + $scope.submissions = data; + $scope.table.rows = data; + console.log('form submissions successfully fetched'); + }) + .error(function(err){ + console.log('Could not fetch form submissions.\nError: '+err); + }); + } else if(!$scope.submissions.length){ + $http.get('/forms/'+$scope.myform._id+'/submissions') + .success(function(data, status, headers){ + $scope.submissions = data; + $scope.table.rows = data; + console.log($scope.table.rows); + console.log('form submissions successfully fetched'); + }) + .error(function(err){ + console.log('Could not fetch form submissions.\nError: '+err); + }); + } + console.log($scope.submissions); + }; + + //hide submissions of Form + $scope.hideSubmissions = function(){ + $scope.viewSubmissions = false; + }; + + // Return all user's Forms + $scope.findAll = function() { + $scope.myforms = Forms.query(); + }; + + // Find a specific Form + $scope.findOne = function() { + $scope.myform = Forms.get({ + formId: $stateParams.formId + }); + CurrentForm.setForm($scope.myform); + }; + + // Remove existing Form + $scope.remove = function(form_id) { + var form = {}; + if(!form_id){ + form = CurrentForm.getForm(); + if(!form) form = $scope.myform; + }else { + form._id = form_id; + } + + $http.delete('/forms/'+form._id) + .success(function(data, status, headers){ + console.log('form deleted successfully'); + + if(!form_id){ + $state.go('listForms'); + } + if($scope.myforms.length > 0){ + $scope.myforms = _.filter($scope.myforms, function(myform){ + return myform._id !== form._id; + }); + } + + }).error(function(error){ + console.log('ERROR: Form could not be deleted.'); + console.error(error); + }); + }; + + $scope.goToWithId = function(route, id) { + $state.go(route, {'formId': id}, {reload: true}); + }; + + // Create new Form + $rootScope.createOrUpdate = function() { + if($scope.isNewForm){ + // Create new Form object + var form = new Forms($scope.myform); + + $http.post('/forms', {form: $scope.myform}) + .success(function(data, status, headers){ + console.log('form created'); + + // Clear form fields + $scope.myform = {}; + // Redirect after save + $scope.goToWithId('viewForm', $scope.myform._id); + }).error(function(errorResponse){ + console.log(errorResponse.data.message); + $scope.error = errorResponse.data.message; + }); + } else{ + $rootScope.update(); + } + }; + + // $rootScope.saveInProgress = false; + + var saveFinished = function() { + $rootScope.saveInProgress = false; + console.log('update form'); + }; + + // Update existing Form + $rootScope.update = function() { + + $rootScope.saveInProgress = true; + console.log('update form'); + + $http.put('/forms/'+$scope.myform._id, {form: $scope.myform}) + .then(function(response){ + console.log('form updated successfully'); + }).catch(function(response){ + console.log('Error occured during form UPDATE.\n'); + console.log(response.data); + }).finally(function() { + $rootScope.saveInProgress = false; + console.log('update form'); + }); + }; + + $rootScope.resetForm = function(){ + $scope.myform = Forms.get({ + formId: $stateParams.formId + }); + }; + + } +]); +'use strict'; + +angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', function($rootScope, $timeout) { + + return { + require: ['^form'], + link: function($scope, $element, $attrs, $ctrls) { + + if(!$rootScope.watchCount === undefined){ + $rootScope.watchCount = 0; + } + var difference = function(array){ + var rest = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1)); + + var containsEquals = function(obj, target) { + if (obj == null) return false; + return _.any(obj, function(value) { + return _.isEqual(value, target); + }); + }; + + return _.filter(array, function(value){ return !containsEquals(rest, value); }); + }; + + var $formCtrl = $ctrls[0]; + var savePromise = null; + $scope.finishedRender = false; + var expression = $attrs.autoSaveForm || 'true'; + + $scope.$on('ngRepeatStarted', function(ngRepeatFinishedEvent) { + $scope.finishedRender = false; + $rootScope.watchCount = 0; + }); + $scope.$on('ngRepeatFinished', function(ngRepeatFinishedEvent) { + $scope.finishedRender = true; + }); + + $scope.$watch('myform.form_fields', function(newValue, oldValue) { + + if(difference(oldValue,newValue).length === 0 || oldValue === undefined){ + return; + } + + // console.log('\n\n-------\n$pristine: '+( $formCtrl.$pristine ) ); + // console.log('$dirty: '+( $formCtrl.$dirty ) ); + // console.log('form_fields changed: '+difference(oldValue.form_fields,newValue.form_fields).length ); + // console.log('$valid: '+$formCtrl.$valid); + // console.log('finishedRender: '+$scope.finishedRender); + // console.log('saveInProgress: '+$scope.saveInProgress); + + if($scope.finishedRender && ($formCtrl.$dirty || difference(oldValue,newValue).length !== 0) ) { + $rootScope.watchCount++; + if($rootScope.watchCount === 1) { + + if(savePromise) { + $timeout.cancel(savePromise); + } + + savePromise = $timeout(function() { + savePromise = null; + + // Still valid? + // if($formCtrl.$valid) { + if($scope.$eval(expression) !== false) { + console.log('Form data persisted -- setting pristine flag'); + $formCtrl.$setPristine(); + } + // } + + }); + } + } + + }, true); + } + }; + +}]); +'use strict'; + +angular.module('forms').directive('changeFocus', function() { + return { + scope:{ + focusDownId: '@', + focusUpId: '@', + }, + link: function(scope, elem, attrs) { + // console.log('aoeuaoeuaoeuaou'); + scope.focusUp = function(){ + if(!scope.$first) { + // console.log('aoeuaoeu'); + elem[0].previousElementSibling.find('input').focus(); + } + scope.apply(); + }; + scope.focusDown = function(){ + if(!scope.$last) { + elem[0].nextElementSibling.focus(); + } + scope.apply(); + }; + + //Bind 'focus-down' click event to given dom element + angular.element('#' + scope.focusDownId).bind('click', function() { + scope.focusDown(); + }); + + //Bind 'focus-up' click event to given dom element + angular.element('#' + scope.focusUpId).bind('click', function() { + scope.focusUp(); + }); + } + }; +}); +'use strict'; + +angular.module('forms').directive('configureFormDirective', ['$rootScope','$http', '$timeout', 'timeCounter', 'Auth', 'FormFields', + function ($rootScope, $http, $timeout, timeCounter, Auth, FormFields) { + return { + controller: function($scope){ + $scope.log = ''; + $scope.pdfLoading = false; + $scope.languages = $rootScope.languages; + var _current_upload = null; + $scope.createOrUpdate = $rootScope.createOrUpdate; + $scope.resetForm = $rootScope.resetForm; + + var _unbindedPdfFields = $scope.pdfFields; + + //DAVID: TODO: finish this so we can create a Form.pdfFieldMap + // $scope.getUnbindedPdfFields = function(fieldType){ + // _unbindedPdfFields = $scope.pdfFields + // } + + //PDF Functions + $scope.cancelUpload = function(){ + _current_upload.abort(); + $scope.pdfLoading = false; + $scope.removePDF(); + }; + + $scope.removePDF = function(){ + $scope.myform.pdf = null; + $scope.myform.isGenerated = false; + $scope.myform.autofillPDFs = false; + + console.log('form.pdf: '+$scope.myform.pdf+' REMOVED'); + }; + + $scope.uploadPDF = function(files) { + + if (files && files.length) { + // for (var i = 0; i < files.length; i++) { + var file = files[0]; + _current_upload = Upload.upload({ + url: '/upload/pdf', + fields: { + 'user': $scope.user, + 'form': $scope.myform + }, + file: file + }).progress(function (evt) { + var progressPercentage = parseInt(100.0 * evt.loaded / evt.total); + $scope.log = 'progress: ' + progressPercentage + '% ' + + evt.config.file.name + '\n' + $scope.log; + $scope.pdfLoading = true; + }).success(function (data, status, headers, config) { + $scope.log = 'file ' + data.originalname + ' uploaded as '+ data.name +'. JSON: ' + JSON.stringify(data) + '\n' + $scope.log; + console.log($scope.myform.pdf); + $scope.myform.pdf = angular.fromJson(angular.toJson(data)); + $scope.pdfLoading = false; + + console.log($scope.log); + console.log('$scope.pdf: '+$scope.myform.pdf.name); + if(!$scope.$$phase){ + $scope.$apply(); + } + }).error(function(err){ + $scope.pdfLoading = false; + console.log('Error occured during upload.\n'); + console.log(err); + }); + // } + } + }; + + }, + templateUrl: './modules/forms/views/directiveViews/form/configure-form.html', + restrict: 'E', + scope: { + myform:'=', + user:'=', + pdfFields:'@', + formFields:'@' + } + }; + } +]); +'use strict'; + +angular.module('forms').directive('editFormDirective', ['$rootScope', '$q', '$http', '$timeout', 'timeCounter', 'Auth', 'FormFields', + function ($rootScope, $q, $http, $timeout, timeCounter, Auth, FormFields) { + return { + templateUrl: './modules/forms/views/directiveViews/form/edit-form.html', + restrict: 'E', + scope: { + myform:'=', + user:'=' + }, + controller: function($scope){ + //Populate local scope with rootScope methods/variables + $scope.update = $rootScope.update; + + //Populate AddField with all available form field types + $scope.addField = {}; + $scope.addField.types = FormFields.fields; + + $scope.addField.types.forEach(function(type){ + type.lastAddedID = 1; + return type; + }); + + // accordion settings + $scope.accordion = {}; + $scope.accordion.oneAtATime = true; + + // Add a new field + $scope.addNewField = function(fieldType){ + + // incr field_id counter + $scope.addField.lastAddedID++; + var fieldTitle; + + for(var i = 0; i < $scope.addField.types.length; i++){ + // console.log($scope.addField.types[i].name === fieldType); + if($scope.addField.types[i].name === fieldType){ + $scope.addField.types[i].lastAddedID++; + console.log($scope.addField.types[i].lastAddedID); + fieldTitle = $scope.addField.types[i].value+$scope.addField.types[i].lastAddedID; + break; + } + } + var newField = { + 'title' : fieldTitle, + 'fieldType' : fieldType, + 'fieldValue' : '', + 'required' : true, + 'disabled' : false + }; + + // put newField into fields array + $scope.myform.form_fields.unshift(newField); + console.log($scope.myform.form_fields.length); + }; + + // deletes particular field on button click + $scope.deleteField = function (hashKey){ + console.log($scope.myform.form_fields); + for(var i = 0; i < $scope.myform.form_fields.length; i++){ + console.log($scope.myform.form_fields[i].$$hashKey === hashKey); + if($scope.myform.form_fields[i].$$hashKey === hashKey){ + $scope.myform.form_fields.splice(i, 1); + break; + } + } + }; + $scope.duplicateField = function (field, field_index){ + for(var i = 0; i < $scope.myform.form_fields.length; i++){ + if($scope.myform.form_fields[i].field_id === field.field_id){ + $scope.addNewField($scope.myform.form_fields[i].fieldType); + break; + } + } + }; + + // add new option to the field + $scope.addOption = function (field){ + if(!field.field_options) + field.field_options = []; + + var lastOptionID = 0; + + if(field.field_options[field.field_options.length-1]) + lastOptionID = field.field_options[field.field_options.length-1].option_id; + + // new option's id + var option_id = lastOptionID + 1; + + var newOption = { + 'option_id' : option_id, + 'option_title' : 'Option ' + option_id, + 'option_value' : option_id + }; + + // put new option into field_options array + field.field_options.push(newOption); + }; + + // delete particular option + $scope.deleteOption = function (field, option){ + for(var i = 0; i < field.field_options.length; i++){ + if(field.field_options[i].option_id === option.option_id){ + field.field_options.splice(i, 1); + break; + } + } + }; + + // decides whether field options block will be shown (true for dropdown and radio fields) + $scope.showAddOptions = function (field){ + if(field.fieldType == 'dropdown' || field.fieldType == 'checkbox' || field.fieldType == 'scale' || field.fieldType == 'rating' || field.fieldType == 'radio') + return true; + else + return false; + }; + + }, + + }; + } +]); +'use strict'; + +angular.module('forms').directive('fieldIconDirective', function($http, $compile) { + + return { + templateUrl: './modules/forms/views/directiveViews/form/fieldIcon.html', + restrict: 'E', + scope: { + typeName: '@' + }, + controller: function($scope){ + var iconTypeMap = { + "textfield": "fa fa-pencil-square-o", + "dropdown": "fa fa-th-list", + "date": "fa fa-calendar", + "checkbox": "fa fa-check-square-o", + "radio": "fa fa-dot-circle-o", + "email": "fa fa-envelope-o", + "textarea": "fa fa-pencil-square", + "legal": "fa fa-legal", + "file": "fa fa-cloud-upload", + "rating": "fa fa-star-half-o", + "link": "fa fa-link", + "scale": "fa fa-sliders", + "stripe": "fa fa-credit-card", + "statement": "fa fa-quote-left", + } + $scope.typeIcon = iconTypeMap[$scope.typeName]; + }, + + }; +}); +'use strict'; + +// coffeescript's for in loop +var __indexOf = [].indexOf || function(item) { + for (var i = 0, l = this.length; i < l; i++) { + if (i in this && this[i] === item) return i; + } + return -1; +}; + +angular.module('forms').directive('fieldDirective', function($http, $compile) { + + + var getTemplateUrl = function(field) { + + var type = field.fieldType; + var templateUrl = './modules/forms/views/directiveViews/field/'; + var supported_fields = [ + 'textfield', + 'email', + 'textarea', + 'checkbox', + 'date', + 'dropdown', + 'hidden', + 'password', + 'radio' + ]; + if (__indexOf.call(supported_fields, type) >= 0) { + return templateUrl += type + '.html'; + } + }; + + var linker = function(scope, element) { + scope.field.required = scope.required; + + // GET template content from path + var templateUrl = getTemplateUrl(scope.field); + $http.get(templateUrl).success(function(data) { + element.html(data); + $compile(element.contents())(scope); + }); + }; + + return { + template: '
{{field.title}}
', + restrict: 'E', + scope: { + field: '=', + required: '&' + }, + link: linker + }; +}); +'use strict'; +angular.module('forms').directive('formLocator', function() { + return { + link: function(scope) { + scope.$emit('formLocator'); + } + } +}); +'use strict'; + +angular.module('forms').directive('formDirective', ['$http', '$timeout', 'timeCounter', 'Auth', + function ($http, $timeout, timeCounter, Auth) { + return { + controller: function($scope){ + timeCounter.startClock(); + + $scope.submit = function(){ + var _timeElapsed = timeCounter.stopClock(); + $scope.form.timeElapsed = _timeElapsed; + + // console.log($scope.form.timeElapsed); + $scope.authentication = Auth; + console.log($scope.authentication.isAuthenticated()); + + $http.post('/forms/'+$scope.form._id,$scope.form). + success(function(data, status, headers){ + console.log('form submitted successfully'); + alert('Form submitted..'); + $scope.form.submitted = true; + }) + .error(function(error){ + console.log(error); + }); + }; + + $scope.cancel = function(){ + alert('Form canceled..'); + }; + + }, + templateUrl: './modules/forms/views/directiveViews/form/form.html', + restrict: 'E', + scope: { + form:'=' + } + }; + } +]); +'use strict'; + +angular.module('forms').directive('onFinishRender', function ($rootScope, $timeout) { + return { + restrict: 'A', + link: function (scope, element, attr) { + if (scope.$first === true) { + $timeout(function () { + $rootScope.$broadcast('ngRepeatStarted'); + }, 500); + } + if (scope.$last === true) { + $timeout(function () { + // console.log('ngRepeatFinished') + $rootScope.$broadcast('ngRepeatFinished'); + }, 500); + } + } + } +}); + +'use strict'; + +angular.module('forms').directive('tableDirective', ['$http', '$timeout', 'Auth', + function ($http, $timeout, Auth) { + return { + controller: function($scope){ + + $scope.toggleChecker = function(checked) { + var rows = $scope.gridOptions.$gridScope.renderedRows, + allChecked = true; + + for (var r = 0; r < rows.length; r++) { + if (rows[r].entity.checker !== true) { + allChecked = false; + break; + } + } + + $scope.gridOptions.$gridScope.checker = allChecked; + }; + + }, + templateUrl: './modules/forms/views/directiveViews/table/table.html', + restrict: 'E', + scope: { + rows:'=', + extras:'=', + } + }; + } +]); +'use strict'; + +//Forms service used for communicating with the forms REST endpoints +angular.module('forms').service('CurrentForm', ['Forms', + function(Forms){ + + //Private variables + var _form = {}; + + //Public Methods + this.getForm = function() { + return _form; + }; + this.setForm = function(form) { + _form = form; + }; + } +]); +'use strict'; + +angular.module('forms').service('FormFields', [ + function() { + this.fields = [ + { + name : 'textfield', + value : 'Short Text' + }, + { + name : 'email', + value : 'Email' + }, + { + name : 'radio', + value : 'Multiple Choice' + }, + { + name : 'dropdown', + value : 'Dropdown List' + }, + { + name : 'date', + value : 'Date' + }, + { + name : 'textarea', + value : 'Long Text' + }, + { + name : 'checkbox', + value : 'Checkbox' + }, + { + name : 'legal', + value : 'Legal' + }, + { + name : 'file', + value : 'File Upload' + }, + { + name : 'rating', + value : 'Rating' + }, + { + name : 'link', + value : 'Link' + }, + { + name : 'scale', + value : 'Opinion Scale' + }, + { + name : 'stripe', + value : 'Payment' + }, + { + name : 'statement', + value : 'Statement' + }, + ]; + } + +]); +'use strict'; + +//Forms service used for communicating with the forms REST endpoints +angular.module('forms').factory('Forms', ['$resource', + function($resource) { + return $resource('forms/:formId', { + formId: '@_id' + }, { + 'query' : { + method: 'GET', + isArray: true, + }, + 'update': { + method: 'PUT' + }, + 'save': { + method: 'POST' + } + }); + } +]); +'use strict'; + +//Submissions service used for communicating with the forms REST endpoints +angular.module('forms').factory('Submissions', ['$resource', + function($resource) { + return $resource('forms/:formID/submissions/:submissionId', { + submissionId: '@_id', + formId: '@_id' + }, { + 'query' : { + method: 'GET', + isArray: true, + }, + 'update': { + method: 'PUT' + }, + 'save': { + method: 'POST' + } + }); + } +]); +'use strict'; + +angular.module('forms').service('timeCounter', [ + function(){ + var _startTime, _endTime, that=this; + + this.timeSpent = 0; + + this.startClock = function(){ + _startTime = Date.now(); + // console.log('Clock Started'); + }; + + this.stopClock = function(){ + _endTime = Date.now(); + that.timeSpent = Math.abs(_endTime.valueOf() - _startTime.valueOf())/1000; + // console.log('Clock Ended'); + return that.timeSpent; + }; + + } +]); +'use strict'; + +// Config HTTP Error Handling +angular.module('users').config(['$httpProvider', + function($httpProvider) { + $httpProvider.interceptors.push(function($q, $location) { + return { + responseError: function(response) { + if( $location.path() !== '/users/me' && $location.path() !== '/'){ + + console.log('intercepted rejection of ', response.config.url, response.status); + if (response.status === 401) { + // save the current location so that login can redirect back + $location.nextAfterLogin = $location.path(); + $location.path('/signin'); + }else if(response.status === 403){ + $location.path('/access_denied'); + } + + } + return $q.reject(response); + } + }; + }); +}]); +'use strict'; + +// Setting up route +angular.module('users').config(['$stateProvider', + function($stateProvider) { + + var checkLoggedin = function($q, $timeout, $state, User, Auth) { + var deferred = $q.defer(); + + // console.log(Auth.ensureHasCurrentUser(User)); + + if (Auth.currentUser && Auth.currentUser.email) { + $timeout(deferred.resolve); + } + else { + Auth.currentUser = User.getCurrent(function() { + Auth.login(); + $timeout(deferred.resolve()); + }, + function() { + Auth.logout(); + $timeout(deferred.reject()); + $state.go('sigin', {reload: true}); + }); + } + + return deferred.promise; + }; + + // Users state routing + $stateProvider. + state('profile', { + // parent: 'restricted', + // data: { + // roles: ['user', 'admin'], + // }, + resolve: { + loggedin: checkLoggedin + }, + url: '/settings/profile', + templateUrl: 'modules/users/views/settings/edit-profile.client.view.html' + }). + state('password', { + // resolve: { + // checkLoggedin: Authorization.authorize + // }, + // parent: 'restricted', + // data: { + // roles: ['user', 'admin'], + // }, + resolve: { + loggedin: checkLoggedin + }, + url: '/settings/password', + templateUrl: 'modules/users/views/settings/change-password.client.view.html' + }). + state('accounts', { + // parent: 'restricted', + // data: { + // roles: ['user', 'admin'], + // }, + resolve: { + loggedin: checkLoggedin + }, + url: '/settings/accounts', + templateUrl: 'modules/users/views/settings/social-accounts.client.view.html' + }). + + state('signup', { + url: '/signup', + templateUrl: 'modules/users/views/authentication/signup.client.view.html' + }). + state('signup-success', { + url: '/signup-success', + templateUrl: 'modules/users/views/authentication/signup.client.view.html' + }). + state('signin', { + url: '/signin', + templateUrl: 'modules/users/views/authentication/signin.client.view.html' + }). + state('access_denied', { + url: '/access_denied', + templateUrl: 'modules/users/views/authentication/access-denied.client.view.html' + }). + + state('forgot', { + url: '/password/forgot', + templateUrl: 'modules/users/views/password/forgot-password.client.view.html' + }). + state('reset-invalid', { + url: '/password/reset/invalid', + templateUrl: 'modules/users/views/password/reset-password-invalid.client.view.html' + }). + state('reset-success', { + url: '/password/reset/success', + templateUrl: 'modules/users/views/password/reset-password-success.client.view.html' + }). + state('reset', { + url: '/password/reset/:token', + templateUrl: 'modules/users/views/password/reset-password.client.view.html' + }); + } +]); +'use strict'; + +angular.module('users').controller('AuthenticationController', ['$scope', '$location', '$state', '$rootScope', 'User', 'Auth', + function($scope, $location, $state, $rootScope, User, Auth) { + + $scope = $rootScope; + $scope.credentials = {}; + $scope.error = null; + + // If user is signed in then redirect back home + if ($scope.authentication.isAuthenticated()) $state.go('home'); + + $scope.signin = function() { + // console.log("signin"); + // console.log($scope.credentials); + Auth.currentUser = User.login($scope.credentials).then( + function(response) { + Auth.login(response); + $scope.user = $rootScope.user = Auth.ensureHasCurrentUser(User); + + if($state.previous.name !== 'home'){ + $state.go($state.previous.name); + }else{ + $state.go('home'); + } + + }, + function(error) { + $rootScope.user = Auth.ensureHasCurrentUser(User); + $scope.user = $rootScope.user; + + $scope.error = error; + console.log('loginError: '+error); + } + ); + }; + + $scope.signup = function() { + User.save($scope.registration, + function() { + $state.go('signup-success'); + }, + function(error) { + if(error) { + $scope.error = error; + }else { + console.log('No response received'); + } + } + ); + }; + + + // $scope.signup = function() { + // Principal.signup($scope.credentials).then( + // function(result){ + // $state.go('home'); + // }, + // function(rejection_reason){ + // $scope.error = rejection_reason; + // } + // ); + // // $http.post('/auth/signup', $scope.credentials).success(function(response) { + // // // If successful we assign the response to the global user model + // // $scope.authentication.user = response; + // // Principal.authenticate(response); + + // // // And redirect to the index page + // // $location.path('/'); + // // }).error(function(response) { + // // $scope.error = response.message; + // // }); + // }; + + // $scope.signin = function() { + // console.log('signin'); + + // Principal.signin($scope.credentials).then( + // function(result){ + // $state.go('home'); + // }, + // function(rejection_reason){ + // $scope.error = rejection_reason; + // } + // ); + // // var response_obj = Principal.signin($scope.credentials); + // // if( angular.isDefined(response_obj.error) ){ + // // $scope.error = response_obj.error; + // // $location.path('/signin'); + // // } else{ + // // $location.path('/'); + // // } + // // $http.post('/auth/signin', $scope.credentials).success(function(response) { + // // // If successful we assign the response to the global user model + // // $scope.authentication.user = response; + // // Principal.authenticate(response); + + // // // And redirect to the index page + // // $location.path('/'); + // // }).error(function(response) { + // // Principal.authenticate(null); + // // $scope.error = response.message; + // // }); + // }; + // } + } +]); +'use strict'; + +angular.module('users').controller('PasswordController', ['$scope', '$stateParams', '$state', 'User', + function($scope, $stateParams, $state, User) { + + //If user is signed in then redirect back home + if ($scope.authentication.isAuthenticated()) $state.go('home'); + + // Submit forgotten password account id + $scope.askForPasswordReset = function() { + User.askForPasswordReset($scope.credentials).then( + function(response){ + $scope.success = response.message; + $scope.credentials = null; + }, + function(error){ + $scope.error = error; + $scope.credentials = null; + } + ); + }; + + // Change user password + $scope.resetUserPassword = function() { + $scope.success = $scope.error = null; + User.resetPassword($scope.passwordDetails, $stateParams.token).then( + function(response){ + // If successful show success message and clear form + $scope.success = response.message; + $scope.passwordDetails = null; + + // And redirect to the index page + $state.go('reset-success'); + }, + function(error){ + $scope.error = error.message || error; + $scope.passwordDetails = null; + } + ); + }; + } +]); +'use strict'; + +angular.module('users').controller('SettingsController', ['$scope', '$rootScope', '$http', '$state', 'Users', + function($scope, $rootScope, $http, $state, Users) { + $scope.user = $rootScope.user; + console.log($scope.user); + // If user is not signed in then redirect back home + if (!$scope.user) $state.go('home'); + + // Check if there are additional accounts + $scope.hasConnectedAdditionalSocialAccounts = function(provider) { + for (var i in $scope.user.additionalProvidersData) { + return true; + } + + return false; + }; + + // Check if provider is already in use with current user + $scope.isConnectedSocialAccount = function(provider) { + return $scope.user.provider === provider || ($scope.user.additionalProvidersData && $scope.user.additionalProvidersData[provider]); + }; + + // Remove a user social account + $scope.removeUserSocialAccount = function(provider) { + $scope.success = $scope.error = null; + + $http.delete('/users/accounts', { + params: { + provider: provider + } + }).success(function(response) { + // If successful show success message and clear form + $scope.success = true; + $scope.user = response; + }).error(function(response) { + $scope.error = response.message; + }); + }; + + // Update a user profile + $scope.updateUserProfile = function(isValid) { + if (isValid) { + $scope.success = $scope.error = null; + var user = new Users($scope.user); + + user.$update(function(response) { + $scope.success = true; + $scope.user = response; + }, function(response) { + $scope.error = response.data.message; + }); + } else { + $scope.submitted = true; + } + }; + + // Change user password + $scope.changeUserPassword = function() { + $scope.success = $scope.error = null; + + $http.post('/users/password', $scope.passwordDetails).success(function(response) { + // If successful show success message and clear form + $scope.success = true; + $scope.passwordDetails = null; + }).error(function(response) { + $scope.error = response.message; + }); + }; + + // }); + } +]); +'use strict'; + +angular.module('users') + .factory('Auth', function($window) { + var userState = + { + isLoggedIn: false + }; + + var service = { + currentUser: null, + + // Note: we can't make the User a dependency of Auth + // because that would create a circular dependency + // Auth <- $http <- $resource <- LoopBackResource <- User <- Auth + ensureHasCurrentUser: function(User) { + if (service.currentUser && service.currentUser.displayName) { + // console.log('Using local current user.'); + // console.log(service.currentUser); + return service.currentUser; + } + else if ($window.user){ + // console.log('Using cached current user.'); + // console.log($window.user); + service.currentUser = $window.user; + return service.currentUser; + } + else{ + console.log('Fetching current user from the server.'); + User.getCurrent().then(function(user) { + // success + service.currentUser = user; + userState.isLoggedIn = true; + $window.user = service.currentUser; + return service.currentUser; + }, + function(response) { + userState.isLoggedIn = false; + service.currentUser = null; + $window.user = null; + console.log('User.getCurrent() err', response); + return null; + }); + } + }, + + isAuthenticated: function() { + return !!service.currentUser; + }, + + getUserState: function() { + return userState; + }, + + login: function(new_user) { + userState.isLoggedIn = true; + service.currentUser = new_user; + }, + + logout: function() { + $window.user = null; + userState.isLoggedIn = false; + service.currentUser = null; + }, + }; + return service; + }); + +// 'use strict'; + +// angular.module('users').factory('Authorization', ['$rootScope', '$http', '$q', '$state', 'Principal', +// function($rootScope, $http, $q, $state, Principal) { +// var service = { +// authorize: function(){ +// var deferred = $q.defer(); +// $http.get('/user/me').success(function(response) { + + +// //user is logged in +// if(response.data !== null){ +// deferred.resolve(); +// }else { +// $rootScope.message = 'You need to log in.'; +// deferred.reject(); +// $state.go('/login'); +// } + +// }); +// return deferred.promise(); +// } +// }; +// return service; +// // this.authorize = function() { +// // return Principal.identity().then(function(){ +// // var isAuthenticated = Principal.isAuthenticated(); +// // if( angular.isDefined($rootScope.toState.data) ){ +// // // if ($rootScope.toState.data.roles && $rootScope.toState.data.roles.length > 0 && !principal.isInAnyRole($rootScope.toState.data.roles)) { +// // if (!isAuthenticated){ //$location.path('/access_denied'); // user is signed in but not authorized for desired state +// // // console.log('isAuthenticated: '+isAuthenticated); + +// // // else { +// // // user is not authenticated. so the state they wanted before you +// // // send them to the signin state, so you can return them when you're done +// // $rootScope.returnToState = $rootScope.toState; +// // $rootScope.returnToStateParams = $rootScope.toStateParams; + +// // // now, send them to the signin state so they can log in +// // $location.path('/signin'); +// // } +// // // } +// // } +// // }); +// // }; +// } +// ]); +// 'use strict'; + +// angular.module('users').factory('AuthenticationService', function($http, $timeout, $q) { +// var error; +// var service = { +// // Information about the current user +// currentUser: null, + +// login: function(credentials) { +// var login = $http.post('/auth/signin', credentials); +// login.success(function(data) { +// service.currentUser = data.user; +// // $flash.clear(); +// }).error(function(error) { +// error = error.error ? error.error : error; +// console.error(error.message || error); +// }); +// return login; +// }, + +// logout: function() { +// var logout = $http.get('/auth/logout'); +// logout.success(function() { +// service.currentUser = null; +// console.log("You've successfully logged out"); +// }); +// return logout; +// }, + +// signup: function(credentials) { +// var signup = $http.post('/auth/signup', credentials) +// signup.success(function(response) { +// console.log("You've successfully created an account"); +// }).error(function(response) { +// error = error.error ? error.error : error; +// console.error(error.message || error); +// }); + +// return signup; +// }, + +// // Ask the backend to see if a user is already authenticated - +// // this may be from a previous session. +// identity: function() { +// if (service.isAuthenticated()) { +// return $q.when(service.currentUser); +// } else { +// return $http.get('/user/me').then(function(response) { +// service.currentUser = response.data.user; +// return service.currentUser; +// }); +// } +// }, + +// // Is the current user authenticated? +// isAuthenticated: function() { +// return !!service.currentUser; +// }, + +// isInRole: function(role) { +// return service.isAuthenticated() (service.currentUser.roles.indexOf(role) !== -1); +// }, + +// isInAnyRole: function(roles) { +// if ( !service.isAuthenticated() || !service.currentUser.roles) return false; +// var roles = service.currentUser.roles; + +// for (var i = 0; i < roles.length; i++) { +// if (this.isInRole(roles[i])) return true; +// } + +// return false; +// }, + +// }; +// return service; +// }); + +// // .factory('Principal', ['$window', '$http', '$q', '$timeout', '$state', +// // function($window, $http, $q, $timeout, $state) { +// // var _identity, +// // _authenticated = false; + +// // return { +// // isIdentityResolved: function() { +// // return angular.isDefined(_identity); +// // }, +// // isAuthenticated: function() { +// // return _authenticated; +// // }, +// // isInRole: function(role) { +// // if (!_authenticated || !_identity.roles) return false; + +// // return _identity.roles.indexOf(role) !== -1; +// // }, +// // isInAnyRole: function(roles) { +// // if (!_authenticated || !_identity.roles) return false; + +// // for (var i = 0; i < roles.length; i++) { +// // if (this.isInRole(roles[i])) return true; +// // } + +// // return false; +// // }, +// // authenticate: function(user) { +// // _identity = user; +// // _authenticated = (user !== null); + +// // // for this demo, we'll store the identity in localStorage. For you, it could be a cookie, sessionStorage, whatever +// // if (user) $window.user = user; +// // else $window.user = null; +// // }, +// // signin: function(credentials) { + +// // var deferred = $q.defer(); +// // var self = this; +// // $http.post('/auth/signin', credentials).success(function(response) { +// // // If successful we assign the response to the global user model +// // self.authenticate(response); +// // deferred.resolve(response); +// // }).error(function(response) { +// // _authenticated = false; +// // deferred.reject({ error: response.message }); +// // }); +// // return deferred.promise; +// // }, +// // signup: function(credentials) { + +// // var deferred = $q.defer(); + +// // $http.post('/auth/signup', credentials).success(function(response) { +// // // If successful we assign the response to the global user model +// // deferred.resolve(response); +// // }).error(function(response) { + +// // deferred.reject({ error: response.message }); +// // }); + +// // return deferred.promise; +// // }, +// // signout: function() { +// // var deferred = $q.defer(); +// // $http.get('/auth/signout').success(function(response) { +// // // If successful we assign the response to the global user model +// // deferred.resolve({}); +// // }).error(function(response) { +// // deferred.reject({ error: response.message }); +// // }); + +// // _authenticated = false; +// // _identity = undefined; + +// // return deferred.promise; +// // }, +// // identity: function() { +// // var self = this; + +// // var deferred = $q.defer(); + +// // // check and see if we have retrieved the user data from the server. if we have, reuse it by immediately resolving +// // if (angular.isDefined(_identity)) { + +// // deferred.resolve(_identity); +// // return deferred.promise; +// // }else if($window.user){ +// // // console.log($window.user); +// // // self.authenticate($window.user); +// // // var user = $window.user; +// // _identity = $window.user; +// // self.authenticate(_identity); +// // deferred.resolve(_identity); + +// // return deferred.promise; +// // }else { + +// // // otherwise, retrieve the user data from the server, update the user object, and then resolve. +// // $http.get('/users/me', { ignoreErrors: true }) +// // .success(function(response) { +// // self.authenticate(response); +// // $window.user = response; +// // deferred.resolve(_identity); +// // }) +// // .error(function() { +// // _identity = null; +// // _authenticated = false; +// // $window.user = null; +// // $state.path('signin'); +// // deferred.resolve(_identity); +// // }); + +// // return deferred.promise; +// // } +// // }, +// // getUser: function(){ +// // this.identity(false).then( function(user){ +// // return user; +// // }); +// // } +// // }; + +// // } +// // ]); + +'use strict'; + +angular.module('users').factory('User', ['$window', '$q', '$timeout', '$http', '$state', + function($window, $q, $timeout, $http, $state) { + + + var userService = { + getCurrent: function() { + var deferred = $q.defer(); + + $http.get('/users/me') + .success(function(response) { + deferred.resolve(response); + }) + .error(function() { + deferred.reject('User\'s session has expired'); + }); + + return deferred.promise; + }, + login: function(credentials) { + + var deferred = $q.defer(); + $http.post('/auth/signin', credentials).success(function(response) { + deferred.resolve(response); + }).error(function(error) { + + deferred.reject(error.message || error); + }); + return deferred.promise; + }, + logout: function() { + var deferred = $q.defer(); + $http.get('/auth/signout').success(function(response) { + deferred.resolve(null); + }).error(function(error) { + deferred.reject(error.message || error); + }); + + return deferred.promise; + }, + signup: function(credentials) { + + var deferred = $q.defer(); + + $http.post('/auth/signup', credentials).success(function(response) { + // If successful we assign the response to the global user model + deferred.resolve(response); + }).error(function(error) { + + deferred.reject(error.message || error); + }); + + return deferred.promise; + }, + + resetPassword: function(passwordDetails, token) { + var deferred = $q.defer(); + $http.get('/auth/password/'+token, passwordDetails).success(function(response) { + + deferred.resolve(); + }).error(function(error) { + deferred.reject(error.message || error); + }); + + return deferred.promise; + }, + + // Submit forgotten password account id + askForPasswordReset: function(credentials) { + var deferred = $q.defer(); + $http.post('/auth/forgot', credentials).success(function(response) { + // Show user success message and clear form + + deferred.resolve(response); + + }).error(function(error) { + // Show user error message + deferred.reject(error.message || error); + }); + + return deferred.promise; + }, + + }; + + return userService; + + } +]); + +'use strict'; + +// Users service used for communicating with the users REST endpoint +angular.module('users').factory('Users', ['$resource', + function($resource) { + return $resource('users', {}, { + update: { + method: 'PUT' + } + }); + } +]); \ No newline at end of file diff --git a/public/dist/application.min.css b/public/dist/application.min.css new file mode 100644 index 00000000..1029bb6f --- /dev/null +++ b/public/dist/application.min.css @@ -0,0 +1 @@ +.navbar-inverse{background-color:#fafafa;border:0}.navbar .navbar-brand{font-size:1.6em;font-weight:900;color:#ff8383}.navbar .navbar-brand:hover,.navbar .navbar-brand:visited{color:#FA787E}.navbar li.dropdown a.dropdown-toggle:hover>*{color:#000}.navbar li.dropdown a.dropdown-toggle>*{color:#d9d9d9}.navbar li.dropdown.open a.dropdown-toggle:hover>*{color:#fff}.navbar .navbar-brand span{text-decoration:underline}.nav.navbar-nav.navbar-right li{padding-right:20px}.content{margin-top:70px}.undecorated-link:hover{text-decoration:none}.ng-cloak,.x-ng-cloak,[data-ng-cloak],[ng-cloak],[ng\:cloak],[x-ng-cloak]{display:none!important}.ng-invalid.ng-dirty{border-color:#FA787E}.ng-valid.ng-dirty{border-color:#78FA89}.browsehappy.jumbotron.hide,body.ng-cloak{display:block}section.hero-section{width:100%}section.hero-section .jumbotron{background-color:transparent;color:#fff}.image-background{position:absolute;top:0;left:0;height:230%;width:100%;z-index:-98;background-image:url(http://yourplaceandmine.ie/wp-content/uploads/2014/09/Daingean-meeting-048_13-1080x675.jpg);background-repeat:no-repeat;background-position:0 50%;background-size:cover}.opacity-background{position:absolute;top:0;left:0;height:230%;width:100%;background-color:rgba(0,0,0,.5);z-index:-97}section.hero-section .jumbotron .signup-btn{background-color:#FA787E;border:none;font-size:2em;padding:.3em .9em;color:#fff;background-color:rgba(250,120,126,.65) #FA787E}.row-height{display:table;table-layout:fixed;height:100%;width:100%}.col-height{display:table-cell;float:none;height:100%}.col-top{vertical-align:top}.col-middle{vertical-align:middle}.col-bottom{vertical-align:bottom}@media (min-width:480px){.row-xs-height{display:table;table-layout:fixed;height:100%;width:100%}.col-xs-height{display:table-cell;float:none;height:100%}.col-xs-top{vertical-align:top}.col-xs-middle{vertical-align:middle}.col-xs-bottom{vertical-align:bottom}}@media (min-width:768px){.row-sm-height{display:table;table-layout:fixed;height:100%;width:100%}.col-sm-height{display:table-cell;float:none;height:100%}.col-sm-top{vertical-align:top}.col-sm-middle{vertical-align:middle}.col-sm-bottom{vertical-align:bottom}}@media (min-width:992px){.row-md-height{display:table;table-layout:fixed;height:100%;width:100%}.col-md-height{display:table-cell;float:none;height:100%}.col-md-top{vertical-align:top}.col-md-middle{vertical-align:middle}.col-md-bottom{vertical-align:bottom}}@media (min-width:1200px){.row-lg-height{display:table;table-layout:fixed;height:100%;width:100%}.col-lg-height{display:table-cell;float:none;height:100%}.col-lg-top{vertical-align:top}.col-lg-middle{vertical-align:middle}.col-lg-bottom{vertical-align:bottom}}form .row.field{padding:1em 0 3em}form .row.field>.field-title{margin-top:.5em;font-size:1.5em}form.submission-form .row.field.statement>.field-title{font-size:1.7em}form.submission-form .row.field.statement>.field-input{font-size:1.2em;color:#ddd}form.submission-form .row.field>.field-input input{width:500px}form.submission-form .row.field .field-input>input:focus{font-size:1em}form .row.field.textfield>.field-input>input{padding:.45em .9em;width:600px}div.config-form>.row{padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05);width:90%}div.config-form>.row>.container:nth-of-type(odd){border-right:1px #ddd solid}div.config-form .row>.field-input{padding-top:1.2em;padding-left:.1em}div.config-form .row>.field-input label{padding-left:1.3em;display:block}.admin-form>.page-header{padding-bottom:0;margin-bottom:40px}.admin-form>.page-header h1{margin-bottom:0}.admin-form>.page-header>.col-xs-3{padding-top:1.4em}.admin-form .form-controls .row{padding:5px}.admin-form .page-header{border:none}.admin-form .tab-content{padding-top:3em}.admin-form .panel-heading{background-color:#f1f1f1}.admin-form .panel-heading:hover{background-color:#fff;cursor:pointer}.admin-form .panel-heading a:hover{text-decoration:none}.current-fields .tool-panel>.panel-default:hover{border-color:#9d9d9d;cursor:pointer}.current-fields .tool-panel>.panel-default .panel-heading{background-color:#fff;color:#9d9d9d!important}.current-fields .tool-panel>.panel-default .panel-heading:hover{background-color:#eee;color:#000!important;cursor:pointer}.current-fields .tool-panel>.panel-default .panel-heading a{color:inherit}.current-fields .tool-panel>.panel-default .panel-heading a:hover{text-decoration:none}.admin-form .add-field{background-color:#ddd}.admin-form .add-field .col-xs-6{padding:.25em .4em}.admin-form .add-field .col-xs-6 .panel-heading{border-width:1px;border-style:solid;border-color:#bbb;border-radius:4px}.status-light{padding-left:.6em}.status-light.status-light-off{color:#BE0000}.status-light.status-light-on{color:#3C0}section>section.ng-scope{padding:0 60px 20px}.form-item.row{text-align:center;border-bottom:6px inset #ccc;background-color:#eee;width:180px;height:215px;margin-bottom:45px}.form-item.row.create-new{background-color:#838383;color:#fff}.form-item.row.create-new.new-form{background-color:#ff8383;z-index:11}.form-item.row.create-new.new-form:hover{background-color:#ff6464}.form-item.new-form a.btn{font-size:.95em}.overlay{position:absolute;top:0;left:0;height:193%;width:inherit;background-color:rgba(0,0,0,.5);z-index:10}.form-item.row.create-new:hover,.form-item.row:hover{border-bottom:8px inset #ccc;background-color:#d9d9d9}.form-item.row.create-new:hover{background-color:#515151}.form-item.row>.title-row{position:relative;top:15px;padding-top:3em;padding-bottom:3.65em}.form-item.row>.title-row h4{font-size:1.3em}.form-item.row.create-new>.title-row{padding:0}.form-item.row.create-new>.title-row h4{font-size:7em}.form-item.row>.details-row{margin-top:3.2em}.form-item.row>.details-row small{font-size:.6em}.form-item.row.create-new>.details-row small{font-size:.95em}@media (min-width:992px){.nav-users{position:fixed}}.remove-account-container{display:inline-block;position:relative}.btn-remove-account{top:10px;right:10px;position:absolute}section.auth{margin-top:5em}section.auth>h3{font-size:3em;font-weight:500;color:#777}section.auth.signup-view>h3{font-size:4.4em;padding-bottom:.5em}section.auth.signup-view.success>h3{padding-bottom:1.2em} \ No newline at end of file diff --git a/public/dist/application.min.js b/public/dist/application.min.js new file mode 100644 index 00000000..97db4690 --- /dev/null +++ b/public/dist/application.min.js @@ -0,0 +1,2 @@ +"use strict";var ApplicationConfiguration=function(){var applicationModuleName="medform",applicationModuleVendorDependencies=["ngResource","ngAnimate","ui.router","ui.bootstrap","ui.utils","ngRaven"],registerModule=function(moduleName,dependencies){angular.module(moduleName,dependencies||[]),angular.module(applicationModuleName).requires.push(moduleName)};return{applicationModuleName:applicationModuleName,applicationModuleVendorDependencies:applicationModuleVendorDependencies,registerModule:registerModule}}();angular.module(ApplicationConfiguration.applicationModuleName,ApplicationConfiguration.applicationModuleVendorDependencies),angular.module(ApplicationConfiguration.applicationModuleName).config(["$locationProvider",function($locationProvider){$locationProvider.hashPrefix("!")}]),angular.module(ApplicationConfiguration.applicationModuleName).run(["$rootScope","$state","$stateParams",function($rootScope,$state,$stateParams){$rootScope.$state=$state,$rootScope.$stateParams=$stateParams,$rootScope.$on("$stateChangeSuccess",function(event,toState,toParams,fromState){console.log(fromState),$state.previous=fromState,"home"===toState.name&&$rootScope.authentication.isAuthenticated()&&(event.preventDefault(),$state.go("listForms"))})}]),angular.element(document).ready(function(){"#_=_"===window.location.hash&&(window.location.hash="#!"),angular.bootstrap(document,[ApplicationConfiguration.applicationModuleName])}),ApplicationConfiguration.registerModule("core",["users"]),ApplicationConfiguration.registerModule("forms",["ngFileUpload","users"]),ApplicationConfiguration.registerModule("users"),angular.module("core").config(["$stateProvider","$urlRouterProvider",function($stateProvider,$urlRouterProvider,Authorization){$urlRouterProvider.otherwise("/"),$stateProvider.state("home",{url:"/",templateUrl:"modules/core/views/home.client.view.html"})}]),angular.module("core").controller("HeaderController",["$rootScope","$scope","Menus","$state","Auth","User",function($rootScope,$scope,Menus,$state,Auth,User){$scope.user=$rootScope.user=Auth.ensureHasCurrentUser(User),$scope.authentication=$rootScope.authentication=Auth,$rootScope.languages=$scope.languages=["english","french","spanish"],$scope.isCollapsed=!1,$scope.hideNav=!1,$scope.menu=Menus.getMenu("topbar"),$scope.signout=function(){var promise=User.logout();promise.then(function(){Auth.logout(),$rootScope.user=null,$state.go("home")},function(reason){console.log("Logout Failed: "+reason)})},$scope.toggleCollapsibleMenu=function(){$scope.isCollapsed=!$scope.isCollapsed},$scope.$on("$stateChangeSuccess",function(event,toState,toParams,fromState,fromParams){$scope.isCollapsed=!1,$scope.hideNav=!1,angular.isDefined(toState.data)&&angular.isDefined(toState.data.hideNav)&&($scope.hideNav=toState.data.hideNav)})}]),angular.module("core").controller("HomeController",["$rootScope","$scope","User","Auth","$state",function($rootScope,$scope,User,Auth,$state){$scope=$rootScope,$scope.user=Auth.ensureHasCurrentUser(User),$scope.authentication=Auth}]),angular.module("core").service("Menus",[function(){this.defaultRoles=["*"],this.menus={};var shouldRender=function(user){if(!user)return this.isPublic;if(~this.roles.indexOf("*"))return!0;for(var userRoleIndex in user.roles)for(var roleIndex in this.roles)if(console.log(this.roles[roleIndex]),console.log(this.roles[roleIndex]===user.roles[userRoleIndex]),this.roles[roleIndex]===user.roles[userRoleIndex])return!0;return!1};this.validateMenuExistance=function(menuId){if(menuId&&menuId.length){if(this.menus[menuId])return!0;throw new Error("Menu does not exists")}throw new Error("MenuId was not provided")},this.getMenu=function(menuId){return this.validateMenuExistance(menuId),this.menus[menuId]},this.addMenu=function(menuId,isPublic,roles){return this.menus[menuId]={isPublic:isPublic||!1,roles:roles||this.defaultRoles,items:[],shouldRender:shouldRender},this.menus[menuId]},this.removeMenu=function(menuId){this.validateMenuExistance(menuId),delete this.menus[menuId]},this.addMenuItem=function(menuId,menuItemTitle,menuItemURL,menuItemType,menuItemUIRoute,isPublic,roles,position){return this.validateMenuExistance(menuId),this.menus[menuId].items.push({title:menuItemTitle,link:menuItemURL,menuItemType:menuItemType||"item",menuItemClass:menuItemType,uiRoute:menuItemUIRoute||"/"+menuItemURL,isPublic:null===isPublic||"undefined"==typeof isPublic?this.menus[menuId].isPublic:isPublic,roles:null===roles||"undefined"==typeof roles?this.menus[menuId].roles:roles,position:position||0,items:[],shouldRender:shouldRender}),this.menus[menuId]},this.addSubMenuItem=function(menuId,rootMenuItemURL,menuItemTitle,menuItemURL,menuItemUIRoute,isPublic,roles,position){this.validateMenuExistance(menuId);for(var itemIndex in this.menus[menuId].items)this.menus[menuId].items[itemIndex].link===rootMenuItemURL&&this.menus[menuId].items[itemIndex].items.push({title:menuItemTitle,link:menuItemURL,uiRoute:menuItemUIRoute||"/"+menuItemURL,isPublic:null===isPublic||"undefined"==typeof isPublic?this.menus[menuId].items[itemIndex].isPublic:isPublic,roles:null===roles||"undefined"==typeof roles?this.menus[menuId].items[itemIndex].roles:roles,position:position||0,shouldRender:shouldRender});return this.menus[menuId]},this.removeMenuItem=function(menuId,menuItemURL){this.validateMenuExistance(menuId);for(var itemIndex in this.menus[menuId].items)this.menus[menuId].items[itemIndex].link===menuItemURL&&this.menus[menuId].items.splice(itemIndex,1);return this.menus[menuId]},this.removeSubMenuItem=function(menuId,submenuItemURL){this.validateMenuExistance(menuId);for(var itemIndex in this.menus[menuId].items)for(var subitemIndex in this.menus[menuId].items[itemIndex].items)this.menus[menuId].items[itemIndex].items[subitemIndex].link===submenuItemURL&&this.menus[menuId].items[itemIndex].items.splice(subitemIndex,1);return this.menus[menuId]},this.addMenu("topbar",!1,["*"]),this.addMenu("bottombar",!1,["*"])}]),angular.module("forms").run(["Menus",function(Menus){Menus.addMenuItem("topbar","My Forms","forms","","/forms",!1)}]).filter("formValidity",function(){return function(formObj){var formKeys=Object.keys(formObj),fields=(formKeys.filter(function(key){return"$"!==key[0]}),formObj.form_fields),valid_count=fields.filter(function(field){return"object"==typeof field?!!field.fieldValue:void 0}).length;return valid_count}}),angular.module("forms").config(["$stateProvider",function($stateProvider){$stateProvider.state("listForms",{url:"/forms",templateUrl:"modules/forms/views/list-forms.client.view.html"}).state("createForm",{url:"/forms/create",templateUrl:"modules/forms/views/create-form.client.view.html"}).state("viewForm",{url:"/forms/:formId/admin",templateUrl:"modules/forms/views/view-form.client.view.html"}).state("viewPublicForm",{url:"/forms/:formId",templateUrl:"modules/forms/views/view-public-form.client.view.html",data:{hideNav:!0,hideFooter:!1}}).state("editForm",{url:"/forms/:formId/edit",templateUrl:"modules/forms/views/create-form.client.view.html"})}]),angular.module("forms").controller("EditFormController",["$scope","$state","$rootScope","Upload","$stateParams","FormFields","Forms","CurrentForm","$modal","$location","$http",function($scope,$state,$rootScope,Upload,$stateParams,FormFields,Forms,CurrentForm,$modal,$location,$http){$scope.form={},$scope.isNewForm=!1,$scope.log="",$scope.pdfLoading=!1;var _current_upload=null;$stateParams.formId?Forms.get({formId:$stateParams.formId},function(form){$scope.form=angular.fromJson(angular.toJson(form)),console.log($scope.form)}):($scope.form.form_fields=[],$scope.isNewForm=!0),$scope.cancelUpload=function(){_current_upload.abort(),$scope.pdfLoading=!1,$scope.removePDF()},$scope.removePDF=function(){$scope.form.pdf=null,$scope.form.isGenerated=!1,$scope.form.autofillPDFs=!1,console.log("form.pdf: "+$scope.form.pdf+" REMOVED")},$scope.uploadPDF=function(files){if(files&&files.length){var file=files[0];_current_upload=Upload.upload({url:"/upload/pdf",fields:{user:$scope.user,form:$scope.form},file:file}).progress(function(evt){var progressPercentage=parseInt(100*evt.loaded/evt.total);$scope.log="progress: "+progressPercentage+"% "+evt.config.file.name+"\n"+$scope.log,$scope.pdfLoading=!0}).success(function(data,status,headers,config){$scope.log="file "+data.originalname+" uploaded as "+data.name+". JSON: "+JSON.stringify(data)+"\n"+$scope.log,console.log($scope.form.pdf),$scope.form.pdf=angular.fromJson(angular.toJson(data)),$scope.pdfLoading=!1,console.log($scope.log),console.log("$scope.pdf: "+$scope.form.pdf.name),$scope.$$phase||$scope.$apply()}).error(function(err){$scope.pdfLoading=!1,console.log("Error occured during upload.\n"),console.log(err)})}},$rootScope.goToWithId=function(route,id){$state.go(route,{formId:id},{reload:!0})},$rootScope.createOrUpdate=function(){if($scope.isNewForm){new Forms($scope.form);$http.post("/forms",{form:$scope.form}).success(function(data,status,headers){console.log("form created"),$scope.form={},$scope.goToWithId("viewForm",$scope.form._id)}).error(function(errorResponse){console.log(errorResponse),$scope.error=errorResponse})}else $scope.update()},$rootScope.update=function(){new Forms($scope.form);console.log("update form"),console.log($scope.form),$http.put("/forms/"+$scope.form._id,{form:$scope.form}).success(function(data,status,headers){console.log("form updated successfully"),$scope.goToWithId("viewForm",$scope.form._id)}).error(function(err){console.log("Error occured during form UPDATE.\n"),console.log(err)})}}]),angular.module("forms").controller("SubmitFormController",["$scope","$stateParams","$state","Forms","CurrentForm",function($scope,$stateParams,$state,Forms,CurrentForm){$scope.form=Forms.get({formId:$stateParams.formId}),CurrentForm.setForm($scope.form)}]),angular.module("forms").controller("ViewSubmissionController",["$scope","$stateParams","$state","Submissions","$http",function($scope,$stateParams,$state,Submissions,$http){$scope.submissionId=void 0,$scope.findAll=function(){$scope.submissions=Submissions.query({formId:$stateParams.formId})},$scope.findOne=function(){$scope.submission=Submissions.get({submissionId:$scope.submissionId,formId:$stateParams.formId})},$scope.remove=function(submission){submission||(submission=$scope.submission),$http["delete"]("/forms/"+$stateParams.formId+"/submissions/"+submission._id).success(function(data,status,headers){console.log("submission deleted successfully"),alert("submission deleted..")})}}]),angular.module("forms").controller("ViewFormController",["$rootScope","$scope","$stateParams","$state","Forms","CurrentForm","$http",function($rootScope,$scope,$stateParams,$state,Forms,CurrentForm,$http){$scope.myform=CurrentForm.getForm(),$scope.submissions=void 0,$scope.viewSubmissions=!1,$scope.showCreateModal=!1,$scope.table={masterChecker:!0,rows:[]},$scope.setForm=function(form){$scope.myForm=form},$scope.openCreateModal=function(){$scope.showCreateModal||($scope.showCreateModal=!0)},$scope.closeCreateModal=function(){$scope.showCreateModal&&($scope.showCreateModal=!1)},$scope.createNew=function(){var form={};form.title=$scope.myForm.name.$modelValue,form.language=$scope.myForm.language.$modelValue,console.log(form),$scope.showCreateModal=!0,console.log($scope.myForm),$scope.myForm.$valid&&$scope.myForm.$dirty&&$http.post("/forms",{form:form}).success(function(data,status,headers){console.log("form created"),$scope.myForm={},$scope.goToWithId("viewForm",$scope.myform._id)}).error(function(errorResponse){console.log(errorResponse)})},$scope.saveInProgress=!1,$scope.update=function(){$scope.saveInProgress||($scope.saveInProgress=!0,console.log("start update()"),$http.put("/forms/"+$scope.myform._id,{form:$scope.myform}).then(function(response){console.log("form updated successfully"),console.log("$scope.saveInProgress: "+$scope.saveInProgress)})["catch"](function(response){console.log("Error occured during form UPDATE.\n"),console.log(response.data)})["finally"](function(){$scope.saveInProgress=!1}))},$scope.toggleAllCheckers=function(){console.log("toggleAllCheckers");for(var i=0;i<$scope.table.rows.length;i++)$scope.table.rows[i].selected=$scope.table.masterChecker},$scope.toggleObjSelection=function($event,description){$event.stopPropagation(),console.log("checkbox clicked")},$scope.rowClicked=function(obj){console.log("row clicked"),obj.selected=!obj.selected},$scope.showSubmissions=function(){$scope.viewSubmissions=!0,$scope.table.rows.length?$scope.submissions.length||$http.get("/forms/"+$scope.myform._id+"/submissions").success(function(data,status,headers){$scope.submissions=data,$scope.table.rows=data,console.log($scope.table.rows),console.log("form submissions successfully fetched")}).error(function(err){console.log("Could not fetch form submissions.\nError: "+err)}):$http.get("/forms/"+$scope.myform._id+"/submissions").success(function(data,status,headers){console.log(data),$scope.submissions=data,$scope.table.rows=data,console.log("form submissions successfully fetched")}).error(function(err){console.log("Could not fetch form submissions.\nError: "+err)}),console.log($scope.submissions)},$scope.hideSubmissions=function(){$scope.viewSubmissions=!1},$scope.findAll=function(){$scope.myforms=Forms.query()},$scope.findOne=function(){$scope.myform=Forms.get({formId:$stateParams.formId}),CurrentForm.setForm($scope.myform)},$scope.remove=function(form_id){var form={};form_id?form._id=form_id:(form=CurrentForm.getForm(),form||(form=$scope.myform)),$http["delete"]("/forms/"+form._id).success(function(data,status,headers){console.log("form deleted successfully"),form_id||$state.go("listForms"),$scope.myforms.length>0&&($scope.myforms=_.filter($scope.myforms,function(myform){return myform._id!==form._id}))}).error(function(error){console.log("ERROR: Form could not be deleted."),console.error(error)})},$scope.goToWithId=function(route,id){$state.go(route,{formId:id},{reload:!0})},$rootScope.createOrUpdate=function(){if($scope.isNewForm){new Forms($scope.myform);$http.post("/forms",{form:$scope.myform}).success(function(data,status,headers){console.log("form created"),$scope.myform={},$scope.goToWithId("viewForm",$scope.myform._id)}).error(function(errorResponse){console.log(errorResponse.data.message),$scope.error=errorResponse.data.message})}else $rootScope.update()};$rootScope.update=function(){$rootScope.saveInProgress=!0,console.log("update form"),$http.put("/forms/"+$scope.myform._id,{form:$scope.myform}).then(function(response){console.log("form updated successfully")})["catch"](function(response){console.log("Error occured during form UPDATE.\n"),console.log(response.data)})["finally"](function(){$rootScope.saveInProgress=!1,console.log("update form")})},$rootScope.resetForm=function(){$scope.myform=Forms.get({formId:$stateParams.formId})}}]),angular.module("forms").directive("autoSaveForm",["$rootScope","$timeout",function($rootScope,$timeout){return{require:["^form"],link:function($scope,$element,$attrs,$ctrls){void 0===!$rootScope.watchCount&&($rootScope.watchCount=0);var difference=function(array){var rest=Array.prototype.concat.apply(Array.prototype,Array.prototype.slice.call(arguments,1)),containsEquals=function(obj,target){return null==obj?!1:_.any(obj,function(value){return _.isEqual(value,target)})};return _.filter(array,function(value){return!containsEquals(rest,value)})},$formCtrl=$ctrls[0],savePromise=null;$scope.finishedRender=!1;var expression=$attrs.autoSaveForm||"true";$scope.$on("ngRepeatStarted",function(ngRepeatFinishedEvent){$scope.finishedRender=!1,$rootScope.watchCount=0}),$scope.$on("ngRepeatFinished",function(ngRepeatFinishedEvent){$scope.finishedRender=!0}),$scope.$watch("myform.form_fields",function(newValue,oldValue){0!==difference(oldValue,newValue).length&&void 0!==oldValue&&$scope.finishedRender&&($formCtrl.$dirty||0!==difference(oldValue,newValue).length)&&($rootScope.watchCount++,1===$rootScope.watchCount&&(savePromise&&$timeout.cancel(savePromise),savePromise=$timeout(function(){savePromise=null,$scope.$eval(expression)!==!1&&(console.log("Form data persisted -- setting pristine flag"),$formCtrl.$setPristine())})))},!0)}}}]),angular.module("forms").directive("changeFocus",function(){return{scope:{focusDownId:"@",focusUpId:"@"},link:function(scope,elem,attrs){scope.focusUp=function(){scope.$first||elem[0].previousElementSibling.find("input").focus(),scope.apply()},scope.focusDown=function(){scope.$last||elem[0].nextElementSibling.focus(),scope.apply()},angular.element("#"+scope.focusDownId).bind("click",function(){scope.focusDown()}),angular.element("#"+scope.focusUpId).bind("click",function(){scope.focusUp()})}}}),angular.module("forms").directive("configureFormDirective",["$rootScope","$http","$timeout","timeCounter","Auth","FormFields",function($rootScope,$http,$timeout,timeCounter,Auth,FormFields){return{controller:function($scope){$scope.log="",$scope.pdfLoading=!1,$scope.languages=$rootScope.languages;var _current_upload=null;$scope.createOrUpdate=$rootScope.createOrUpdate,$scope.resetForm=$rootScope.resetForm;$scope.pdfFields;$scope.cancelUpload=function(){_current_upload.abort(),$scope.pdfLoading=!1,$scope.removePDF()},$scope.removePDF=function(){$scope.myform.pdf=null,$scope.myform.isGenerated=!1,$scope.myform.autofillPDFs=!1,console.log("form.pdf: "+$scope.myform.pdf+" REMOVED")},$scope.uploadPDF=function(files){if(files&&files.length){var file=files[0];_current_upload=Upload.upload({url:"/upload/pdf",fields:{user:$scope.user,form:$scope.myform},file:file}).progress(function(evt){var progressPercentage=parseInt(100*evt.loaded/evt.total);$scope.log="progress: "+progressPercentage+"% "+evt.config.file.name+"\n"+$scope.log,$scope.pdfLoading=!0}).success(function(data,status,headers,config){$scope.log="file "+data.originalname+" uploaded as "+data.name+". JSON: "+JSON.stringify(data)+"\n"+$scope.log,console.log($scope.myform.pdf),$scope.myform.pdf=angular.fromJson(angular.toJson(data)),$scope.pdfLoading=!1,console.log($scope.log),console.log("$scope.pdf: "+$scope.myform.pdf.name),$scope.$$phase||$scope.$apply()}).error(function(err){$scope.pdfLoading=!1,console.log("Error occured during upload.\n"),console.log(err)})}}},templateUrl:"./modules/forms/views/directiveViews/form/configure-form.html",restrict:"E",scope:{myform:"=",user:"=",pdfFields:"@",formFields:"@"}}}]),angular.module("forms").directive("editFormDirective",["$rootScope","$q","$http","$timeout","timeCounter","Auth","FormFields",function($rootScope,$q,$http,$timeout,timeCounter,Auth,FormFields){return{templateUrl:"./modules/forms/views/directiveViews/form/edit-form.html",restrict:"E",scope:{myform:"=",user:"="},controller:function($scope){$scope.update=$rootScope.update,$scope.addField={},$scope.addField.types=FormFields.fields,$scope.addField.types.forEach(function(type){return type.lastAddedID=1,type}),$scope.accordion={},$scope.accordion.oneAtATime=!0,$scope.addNewField=function(fieldType){$scope.addField.lastAddedID++;for(var fieldTitle,i=0;i<$scope.addField.types.length;i++)if($scope.addField.types[i].name===fieldType){$scope.addField.types[i].lastAddedID++,console.log($scope.addField.types[i].lastAddedID),fieldTitle=$scope.addField.types[i].value+$scope.addField.types[i].lastAddedID;break}var newField={title:fieldTitle,fieldType:fieldType,fieldValue:"",required:!0,disabled:!1};$scope.myform.form_fields.unshift(newField),console.log($scope.myform.form_fields.length)},$scope.deleteField=function(hashKey){console.log($scope.myform.form_fields);for(var i=0;i<$scope.myform.form_fields.length;i++)if(console.log($scope.myform.form_fields[i].$$hashKey===hashKey),$scope.myform.form_fields[i].$$hashKey===hashKey){$scope.myform.form_fields.splice(i,1);break}},$scope.duplicateField=function(field,field_index){for(var i=0;i<$scope.myform.form_fields.length;i++)if($scope.myform.form_fields[i].field_id===field.field_id){$scope.addNewField($scope.myform.form_fields[i].fieldType);break}},$scope.addOption=function(field){field.field_options||(field.field_options=[]);var lastOptionID=0;field.field_options[field.field_options.length-1]&&(lastOptionID=field.field_options[field.field_options.length-1].option_id);var option_id=lastOptionID+1,newOption={option_id:option_id,option_title:"Option "+option_id,option_value:option_id};field.field_options.push(newOption)},$scope.deleteOption=function(field,option){for(var i=0;ii;i++)if(i in this&&this[i]===item)return i;return-1};angular.module("forms").directive("fieldDirective",function($http,$compile){var getTemplateUrl=function(field){var type=field.fieldType,templateUrl="./modules/forms/views/directiveViews/field/",supported_fields=["textfield","email","textarea","checkbox","date","dropdown","hidden","password","radio"];return __indexOf.call(supported_fields,type)>=0?templateUrl+=type+".html":void 0},linker=function(scope,element){scope.field.required=scope.required;var templateUrl=getTemplateUrl(scope.field);$http.get(templateUrl).success(function(data){element.html(data),$compile(element.contents())(scope)})};return{template:"
{{field.title}}
",restrict:"E",scope:{field:"=",required:"&"},link:linker}}),angular.module("forms").directive("formLocator",function(){return{link:function(scope){scope.$emit("formLocator")}}}),angular.module("forms").directive("formDirective",["$http","$timeout","timeCounter","Auth",function($http,$timeout,timeCounter,Auth){return{controller:function($scope){timeCounter.startClock(),$scope.submit=function(){var _timeElapsed=timeCounter.stopClock();$scope.form.timeElapsed=_timeElapsed,$scope.authentication=Auth,console.log($scope.authentication.isAuthenticated()),$http.post("/forms/"+$scope.form._id,$scope.form).success(function(data,status,headers){console.log("form submitted successfully"),alert("Form submitted.."),$scope.form.submitted=!0}).error(function(error){console.log(error)})},$scope.cancel=function(){alert("Form canceled..")}},templateUrl:"./modules/forms/views/directiveViews/form/form.html",restrict:"E",scope:{form:"="}}}]),angular.module("forms").directive("onFinishRender",function($rootScope,$timeout){return{restrict:"A",link:function(scope,element,attr){scope.$first===!0&&$timeout(function(){$rootScope.$broadcast("ngRepeatStarted")},500),scope.$last===!0&&$timeout(function(){$rootScope.$broadcast("ngRepeatFinished")},500)}}}),angular.module("forms").directive("tableDirective",["$http","$timeout","Auth",function($http,$timeout,Auth){return{controller:function($scope){$scope.toggleChecker=function(checked){for(var rows=$scope.gridOptions.$gridScope.renderedRows,allChecked=!0,r=0;r