'use strict' Application.Controllers.controller 'ApplicationController', ["$rootScope", "$scope", "$window", "Session", "AuthService", "Auth", "$uibModal", "$state", 'growl', 'Notification', '$interval', "Setting", '_t' , ($rootScope, $scope, $window, Session, AuthService, Auth, $uibModal, $state, growl, Notification, $interval, Setting, _t) -> ### PRIVATE STATIC CONSTANTS ### # User's notifications will get refreshed every 30s NOTIFICATIONS_CHECK_PERIOD = 30000 ### PUBLIC SCOPE ### ## # Set the current user to the provided value and initialize the session # @param user {Object} Rails/Devise user ## $scope.setCurrentUser = (user) -> $rootScope.currentUser = user Session.create(user); getNotifications() ## # Login callback # @param e {Object} see https://docs.angularjs.org/guide/expression#-event- # @param callback {function} ## $scope.login = (e, callback) -> e.preventDefault() if e openLoginModal null, null, callback ## # Logout callback # @param e {Object} see https://docs.angularjs.org/guide/expression#-event- ## $scope.logout = (e) -> e.preventDefault() Auth.logout().then (oldUser) -> # console.log(oldUser.name + " you're signed out now."); Session.destroy() $rootScope.currentUser = null $rootScope.toCheckNotifications = false $scope.notifications = [] $state.go('app.public.home') , (error) -> # An error occurred logging out. ## # Open the modal window allowing the user to create an account. # @param e {Object} see https://docs.angularjs.org/guide/expression#-event- ## $scope.signup = (e) -> e.preventDefault() if e $uibModal.open templateUrl: '<%= asset_path "shared/signupModal.html" %>' size: 'md' controller: ['$scope', '$uibModalInstance', 'Group', 'CustomAsset', ($scope, $uibModalInstance, Group, CustomAsset) -> # default parameters for the date picker in the account creation modal $scope.datePicker = format: Fablab.uibDateFormat opened: false options: startingDay: Fablab.weekStartingDay # callback to open the date picker (account creation modal) $scope.openDatePicker = ($event) -> $event.preventDefault() $event.stopPropagation() $scope.datePicker.opened = true # retrieve the groups (standard, student ...) Group.query (groups) -> $scope.groups = groups # retrieve the CGU CustomAsset.get {name: 'cgu-file'}, (cgu) -> $scope.cgu = cgu.custom_asset # default user's parameters $scope.user = is_allow_contact: true # Errors display $scope.alerts = [] $scope.closeAlert = (index) -> $scope.alerts.splice(index, 1) # callback for form validation $scope.ok = -> # try to create the account $scope.alerts = [] Auth.register($scope.user).then (user) -> # creation successful $uibModalInstance.close(user) , (error) -> # creation failed... angular.forEach error.data.errors, (v, k) -> angular.forEach v, (err) -> $scope.alerts.push msg: k+': '+err type: 'danger' ] .result['finally'](null).then (user) -> # when the account was created succesfully, set the session to the newly created account $scope.setCurrentUser(user) ## # Open the modal window allowing the user to change his password. # @param token {string} security token for password changing. The user should have recieved it by mail ## $scope.editPassword = (token) -> $uibModal.open templateUrl: '<%= asset_path "shared/passwordEditModal.html" %>' size: 'md' controller: ['$scope', '$uibModalInstance', '$http', '_t', ($scope, $uibModalInstance, $http, _t) -> $scope.user = reset_password_token: token $scope.alerts = [] $scope.closeAlert = (index) -> $scope.alerts.splice(index, 1) $scope.changePassword = -> $scope.alerts = [] $http.put('/users/password.json', {user: $scope.user}).success (data) -> $uibModalInstance.close() .error (data) -> angular.forEach data.errors, (v, k) -> angular.forEach v, (err) -> $scope.alerts.push msg: k+': '+err type: 'danger' ] .result['finally'](null).then (user) -> growl.success(_t('your_password_was_successfully_changed')) Auth.login().then (user) -> $scope.setCurrentUser(user) , (error) -> # Authentication failed... ## # Compact/Expend the width of the left navigation bar # @param e {Object} see https://docs.angularjs.org/guide/expression#-event- ## $scope.toggleNavSize = (event) -> if typeof event == 'undefined' console.error '[ApplicationController::toggleNavSize] Missing event parameter' return toggler = $(event.target) toggler = toggler.closest('[data-toggle^="class"]') unless toggler.data('toggle') $class = toggler.data()['toggle'] $target = toggler.data('target') or toggler.attr('data-link') if $class $tmp = $class.split(':')[1] $classes = $tmp.split(',') if $tmp if $target $targets = $target.split(',') if $classes and $classes.length $.each $targets, ( index, value ) -> if $classes[index].indexOf( '*' ) != -1 patt = new RegExp( '\\s' + $classes[index].replace( /\*/g, '[A-Za-z0-9-_]+' ).split( ' ' ).join( '\\s|\\s' ) + '\\s', 'g' ) $(toggler).each ( i, it ) -> cn = ' ' + it.className + ' ' while patt.test( cn ) cn = cn.replace( patt, ' ' ) it.className = $.trim( cn ) ($targets[index] !='#') and $($targets[index]).toggleClass($classes[index]) or toggler.toggleClass($classes[index]) toggler.toggleClass('active') return ### PRIVATE SCOPE ### ## # Kind of constructor: these actions will be realized first when the controller is loaded ## initialize = -> # try to retrieve any currently logged user Auth.login().then (user) -> $scope.setCurrentUser(user) if user.need_completion $state.transitionTo('app.logged.profileCompletion') , (error) -> # Authentication failed... $rootScope.toCheckNotifications = false # bind to the $stateChangeStart event (AngularJS/UI-Router) $rootScope.$on '$stateChangeStart', (event, toState, toParams, fromState, fromParams) -> return unless toState.data authorizedRoles = toState.data.authorizedRoles unless AuthService.isAuthorized(authorizedRoles) event.preventDefault() if AuthService.isAuthenticated() # user is not allowed console.error('[ApplicationController::initialize] user is not allowed') else # user is not logged in openLoginModal(toState, toParams) Setting.get { name: 'fablab_name' }, (data)-> $scope.fablabName = data.setting.value Setting.get { name: 'name_genre' }, (data)-> $scope.nameGenre = data.setting.value # shorthands $scope.isAuthenticated = Auth.isAuthenticated; $scope.isAuthorized = AuthService.isAuthorized; ## # Retreive once the notifications from the server and display a message popup for each new one. # Then, periodically check for new notifications. ## getNotifications = -> $rootScope.toCheckNotifications = true unless $rootScope.checkNotificationsIsInit or !$rootScope.currentUser $scope.notifications = Notification.query {is_read: false} $scope.$watch 'notifications', (newValue, oldValue) -> diff = [] angular.forEach newValue, (value) -> find = false for i in [0..oldValue.length] by 1 if oldValue[i] and (value.id is oldValue[i].id) find = true break unless find diff.push(value) angular.forEach diff, (notification, key) -> growl.info(notification.message.description) , true checkNotifications = -> if $rootScope.toCheckNotifications Notification.query({is_read: false}).$promise.then (data) -> $scope.notifications = data; $interval(checkNotifications, NOTIFICATIONS_CHECK_PERIOD) $rootScope.checkNotificationsIsInit = true ## # Open the modal window allowing the user to log in. ## openLoginModal = (toState, toParams, callback) -> <% active_provider = AuthProvider.active %> <% if active_provider.providable_type != DatabaseProvider.name %> $window.location.href = '<%=user_omniauth_authorize_path(AuthProvider.active.strategy_name.to_sym)%>' <% else %> $uibModal.open templateUrl: '<%= asset_path "shared/deviseModal.html" %>' size: 'sm' controller: ['$scope', '$uibModalInstance', '_t', ($scope, $uibModalInstance, _t) -> user = $scope.user = {} $scope.login = () -> Auth.login(user).then (user) -> # Authentification succeeded ... $uibModalInstance.close(user) if callback and typeof callback is "function" callback(user) , (error) -> # Authentication failed... $scope.alerts = [] $scope.alerts.push msg: _t('wrong_email_or_password') type: 'danger' # handle modal behaviors. The provided reason will be used to define the following actions $scope.dismiss = -> $uibModalInstance.dismiss('cancel') $scope.openSignup = (e) -> e.preventDefault() $uibModalInstance.dismiss('signup') $scope.openResetPassword = (e) -> e.preventDefault() $uibModalInstance.dismiss('resetPassword') ] # what to do when the modal is closed .result['finally'](null).then (user) -> # authentification succeeded, set the session, gather the notifications and redirect $scope.setCurrentUser(user) if toState isnt null and toParams isnt null $state.go(toState, toParams) , (reason) -> # authentification did not ended successfully if reason is 'signup' # open signup modal $scope.signup() else if reason is 'resetPassword' # open the 'reset password' modal $uibModal.open templateUrl: '<%= asset_path "shared/passwordNewModal.html" %>' size: 'sm' controller: ['$scope', '$uibModalInstance', '$http', ($scope, $uibModalInstance, $http) -> $scope.user = {email: ''} $scope.sendReset = () -> $scope.alerts = [] $http.post('/users/password.json', {user: $scope.user}).success -> $uibModalInstance.close() .error -> $scope.alerts.push msg: _t('your_email_address_is_unknown') type: 'danger' ] .result['finally'](null).then -> growl.info(_t('you_will_receive_in_a_moment_an_email_with_instructions_to_reset_your_password')) # otherwise the user just closed the modal <% end %> ## !!! MUST BE CALLED AT THE END of the controller initialize() ]