mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-29 18:52:22 +01:00
javascript fixes
This commit is contained in:
parent
f528b2021d
commit
6e56ac4286
@ -2,6 +2,11 @@
|
||||
"extends": "standard",
|
||||
"rules": {
|
||||
"semi": ["error", "always"]
|
||||
},
|
||||
"globals": {
|
||||
"Application": true,
|
||||
"angular": true,
|
||||
"Fablab": true
|
||||
}
|
||||
}
|
||||
|
||||
|
2
.rubocop.yml
Normal file
2
.rubocop.yml
Normal file
@ -0,0 +1,2 @@
|
||||
Metrics/LineLength:
|
||||
Max: 120
|
@ -5,6 +5,7 @@
|
||||
* creating namespaces and moduled for controllers, filters, services, and directives.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line no-use-before-define
|
||||
var Application = Application || {};
|
||||
|
||||
Application.Constants = angular.module('application.constants', []);
|
||||
@ -13,58 +14,49 @@ Application.Controllers = angular.module('application.controllers', []);
|
||||
Application.Filters = angular.module('application.filters', []);
|
||||
Application.Directives = angular.module('application.directives', []);
|
||||
|
||||
|
||||
angular.module('application', ['ngCookies', 'ngResource', 'ngSanitize', 'ngCookies', 'ui.router', 'ui.bootstrap',
|
||||
'ngUpload', 'duScroll', 'application.filters','application.services', 'application.directives',
|
||||
'frapontillo.bootstrap-switch', 'application.constants', 'application.controllers', 'application.router',
|
||||
'ui.select', 'ui.calendar', 'angularMoment', 'Devise', 'DeviseModal', 'angular-growl', 'xeditable',
|
||||
'checklist-model', 'unsavedChanges', 'angular-loading-bar', 'ngTouch', 'angular-google-analytics',
|
||||
'angularUtils.directives.dirDisqus', 'summernote', 'elasticsearch', 'angular-medium-editor', 'naif.base64',
|
||||
'minicolors', 'pascalprecht.translate', 'ngFitText', 'ngAside', 'ngCapsLock']).
|
||||
config(['$httpProvider', 'AuthProvider', "growlProvider", "unsavedWarningsConfigProvider", "AnalyticsProvider", "uibDatepickerPopupConfig", "$provide", "$translateProvider",
|
||||
function($httpProvider, AuthProvider, growlProvider, unsavedWarningsConfigProvider, AnalyticsProvider, uibDatepickerPopupConfig, $provide, $translateProvider) {
|
||||
|
||||
|
||||
'ngUpload', 'duScroll', 'application.filters', 'application.services', 'application.directives',
|
||||
'frapontillo.bootstrap-switch', 'application.constants', 'application.controllers', 'application.router',
|
||||
'ui.select', 'ui.calendar', 'angularMoment', 'Devise', 'DeviseModal', 'angular-growl', 'xeditable',
|
||||
'checklist-model', 'unsavedChanges', 'angular-loading-bar', 'ngTouch', 'angular-google-analytics',
|
||||
'angularUtils.directives.dirDisqus', 'summernote', 'elasticsearch', 'angular-medium-editor', 'naif.base64',
|
||||
'minicolors', 'pascalprecht.translate', 'ngFitText', 'ngAside', 'ngCapsLock'])
|
||||
.config(['$httpProvider', 'AuthProvider', 'growlProvider', 'unsavedWarningsConfigProvider', 'AnalyticsProvider', 'uibDatepickerPopupConfig', '$provide', '$translateProvider',
|
||||
function ($httpProvider, AuthProvider, growlProvider, unsavedWarningsConfigProvider, AnalyticsProvider, uibDatepickerPopupConfig, $provide, $translateProvider) {
|
||||
// Google analytics
|
||||
<% #if Rails.env.production? %>
|
||||
AnalyticsProvider.setAccount(Fablab.gaId);
|
||||
// track all routes (or not)
|
||||
AnalyticsProvider.trackPages(true);
|
||||
AnalyticsProvider.setDomainName(Fablab.defaultHost);
|
||||
AnalyticsProvider.useAnalytics(true);
|
||||
AnalyticsProvider.setPageEvent('$stateChangeSuccess');
|
||||
<% #else %>
|
||||
//AnalyticsProvider.setAccount('DISABLED');
|
||||
<% #end %>
|
||||
|
||||
// Custom messages for the date-picker widget
|
||||
uibDatepickerPopupConfig.closeText = Fablab.translations.app.shared.buttons.close;
|
||||
uibDatepickerPopupConfig.clearText = Fablab.translations.app.shared.buttons.clear;
|
||||
uibDatepickerPopupConfig.currentText = Fablab.translations.app.shared.buttons.today;
|
||||
// Custom messages for the date-picker widget
|
||||
uibDatepickerPopupConfig.closeText = Fablab.translations.app.shared.buttons.close;
|
||||
uibDatepickerPopupConfig.clearText = Fablab.translations.app.shared.buttons.clear;
|
||||
uibDatepickerPopupConfig.currentText = Fablab.translations.app.shared.buttons.today;
|
||||
|
||||
// Custom messages for angular-unsavedChanges
|
||||
unsavedWarningsConfigProvider.navigateMessage = Fablab.translations.app.shared.messages.you_will_lose_any_unsaved_modification_if_you_quit_this_page;
|
||||
unsavedWarningsConfigProvider.reloadMessage = Fablab.translations.app.shared.messages.you_will_lose_any_unsaved_modification_if_you_reload_this_page;
|
||||
// Custom messages for angular-unsavedChanges
|
||||
unsavedWarningsConfigProvider.navigateMessage = Fablab.translations.app.shared.messages.you_will_lose_any_unsaved_modification_if_you_quit_this_page;
|
||||
unsavedWarningsConfigProvider.reloadMessage = Fablab.translations.app.shared.messages.you_will_lose_any_unsaved_modification_if_you_reload_this_page;
|
||||
|
||||
// Set how long the popup messages (growl) will remain
|
||||
growlProvider.globalTimeToLive(5000);
|
||||
|
||||
// Configure the i18n module to load the partial translations from the given API URL
|
||||
$translateProvider.useLoader('$translatePartialLoader', {
|
||||
urlTemplate: '/api/translations/{lang}/{part}'
|
||||
});
|
||||
// Enable the cache to speed-up the loading times on already seen pages
|
||||
$translateProvider.useLoaderCache(true);
|
||||
// Secure i18n module against XSS attacks by escaping the output
|
||||
$translateProvider.useSanitizeValueStrategy('escapeParameters');
|
||||
// Enable the MessageFormat interpolation (used for pluralization)
|
||||
$translateProvider.addInterpolation('$translateMessageFormatInterpolation');
|
||||
// Set the langage of the instance (from ruby configuration)
|
||||
$translateProvider.preferredLanguage(Fablab.locale);
|
||||
|
||||
}]).run(["$rootScope", "$log", "AuthService", "Auth", "amMoment", "$state", "editableOptions", 'Analytics',
|
||||
function($rootScope, $log, AuthService, Auth, amMoment, $state, editableOptions, Analytics) {
|
||||
// Set how long the popup messages (growl) will remain
|
||||
growlProvider.globalTimeToLive(5000);
|
||||
|
||||
// Configure the i18n module to load the partial translations from the given API URL
|
||||
$translateProvider.useLoader('$translatePartialLoader', {
|
||||
urlTemplate: '/api/translations/{lang}/{part}'
|
||||
});
|
||||
// Enable the cache to speed-up the loading times on already seen pages
|
||||
$translateProvider.useLoaderCache(true);
|
||||
// Secure i18n module against XSS attacks by escaping the output
|
||||
$translateProvider.useSanitizeValueStrategy('escapeParameters');
|
||||
// Enable the MessageFormat interpolation (used for pluralization)
|
||||
$translateProvider.addInterpolation('$translateMessageFormatInterpolation');
|
||||
// Set the langage of the instance (from ruby configuration)
|
||||
$translateProvider.preferredLanguage(Fablab.locale);
|
||||
}]).run(['$rootScope', '$log', 'AuthService', 'Auth', 'amMoment', '$state', 'editableOptions', 'Analytics',
|
||||
function ($rootScope, $log, AuthService, Auth, amMoment, $state, editableOptions, Analytics) {
|
||||
// Angular-moment (date-time manipulations library)
|
||||
amMoment.changeLocale(Fablab.moment_locale);
|
||||
|
||||
@ -73,7 +65,7 @@ config(['$httpProvider', 'AuthProvider', "growlProvider", "unsavedWarningsConfig
|
||||
|
||||
// Alter the UI-Router's $state, registering into some information concerning the previous $state.
|
||||
// This is used to allow the user to navigate to the previous state
|
||||
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){
|
||||
$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
|
||||
$state.prevState = fromState;
|
||||
$state.prevParams = fromParams;
|
||||
});
|
||||
@ -85,11 +77,11 @@ config(['$httpProvider', 'AuthProvider', "growlProvider", "unsavedWarningsConfig
|
||||
|
||||
// Global function to allow the user to navigate to the previous screen (ie. $state).
|
||||
// If no previous $state were recorded, navigate to the home page
|
||||
$rootScope.backPrevLocation = function(event){
|
||||
$rootScope.backPrevLocation = function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
if($state.prevState.name == ""){
|
||||
$state.prevState = "app.public.home";
|
||||
if ($state.prevState.name === '') {
|
||||
$state.prevState = 'app.public.home';
|
||||
}
|
||||
$state.go($state.prevState, $state.prevParams);
|
||||
};
|
||||
@ -116,8 +108,8 @@ config(['$httpProvider', 'AuthProvider', "growlProvider", "unsavedWarningsConfig
|
||||
// Prevent the usage of the application for members with incomplete profiles: they will be redirected to
|
||||
// the 'profile completion' page. This is especially useful for user's accounts imported through SSO.
|
||||
$rootScope.$on('$stateChangeStart', function (event, toState) {
|
||||
Auth.currentUser().then(function(currentUser) {
|
||||
if (currentUser.need_completion && toState.name != 'app.logged.profileCompletion') {
|
||||
Auth.currentUser().then(function (currentUser) {
|
||||
if (currentUser.need_completion && toState.name !== 'app.logged.profileCompletion') {
|
||||
$state.go('app.logged.profileCompletion');
|
||||
}
|
||||
});
|
||||
@ -127,7 +119,6 @@ config(['$httpProvider', 'AuthProvider', "growlProvider", "unsavedWarningsConfig
|
||||
// see https://github.com/revolunet/angular-google-analytics#automatic-page-view-tracking
|
||||
Analytics.pageView();
|
||||
|
||||
|
||||
/**
|
||||
* This helper method builds and return an array contaning every integers between
|
||||
* the provided start and end.
|
||||
@ -135,16 +126,15 @@ config(['$httpProvider', 'AuthProvider', "growlProvider", "unsavedWarningsConfig
|
||||
* @param end {number}
|
||||
* @return {Array} [start .. end]
|
||||
*/
|
||||
$rootScope.intArray = function(start, end) {
|
||||
$rootScope.intArray = function (start, end) {
|
||||
var arr = [];
|
||||
for (var i = start; i < end; i++) { arr.push(i); }
|
||||
return arr;
|
||||
};
|
||||
|
||||
}]).constant('angularMomentConfig', {
|
||||
}]).constant('angularMomentConfig', {
|
||||
timezone: Fablab.timezone
|
||||
});
|
||||
|
||||
angular.isUndefinedOrNull = function(val) {
|
||||
return angular.isUndefined(val) || val === null
|
||||
angular.isUndefinedOrNull = function (val) {
|
||||
return angular.isUndefined(val) || val === null;
|
||||
};
|
@ -14,20 +14,19 @@
|
||||
|
||||
Application.Controllers.controller('ApplicationController', ['$rootScope', '$scope', '$window', '$locale', 'Session', 'AuthService', 'Auth', '$uibModal', '$state', 'growl', 'Notification', '$interval', 'Setting', '_t', 'Version',
|
||||
function ($rootScope, $scope, $window, $locale, Session, AuthService, Auth, $uibModal, $state, growl, Notification, $interval, Setting, _t, Version) {
|
||||
|
||||
/* PRIVATE STATIC CONSTANTS */
|
||||
|
||||
// User's notifications will get refreshed every 30s
|
||||
const NOTIFICATIONS_CHECK_PERIOD = 30000
|
||||
const NOTIFICATIONS_CHECK_PERIOD = 30000;
|
||||
|
||||
/* PUBLIC SCOPE */
|
||||
/* PUBLIC SCOPE */
|
||||
|
||||
// Fab-manager's version
|
||||
$scope.version =
|
||||
{ version: '' }
|
||||
{ version: '' };
|
||||
|
||||
// currency symbol for the current locale (cf. angular-i18n)
|
||||
$rootScope.currencySymbol = $locale.NUMBER_FORMATS.CURRENCY_SYM
|
||||
$rootScope.currencySymbol = $locale.NUMBER_FORMATS.CURRENCY_SYM;
|
||||
|
||||
/**
|
||||
* Set the current user to the provided value and initialize the session
|
||||
@ -35,17 +34,17 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco
|
||||
*/
|
||||
$scope.setCurrentUser = function (user) {
|
||||
if (!angular.isUndefinedOrNull(user)) {
|
||||
$rootScope.currentUser = user
|
||||
Session.create(user)
|
||||
getNotifications()
|
||||
$rootScope.currentUser = user;
|
||||
Session.create(user);
|
||||
getNotifications();
|
||||
// fab-manager's app-version
|
||||
if (user.role === 'admin') {
|
||||
return $scope.version = Version.get()
|
||||
return $scope.version = Version.get();
|
||||
} else {
|
||||
return $scope.version = { version: '' }
|
||||
return $scope.version = { version: '' };
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Login callback
|
||||
@ -53,36 +52,36 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco
|
||||
* @param callback {function}
|
||||
*/
|
||||
$scope.login = function (e, callback) {
|
||||
if (e) { e.preventDefault() }
|
||||
return openLoginModal(null, null, callback)
|
||||
}
|
||||
if (e) { e.preventDefault(); }
|
||||
return openLoginModal(null, null, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Logout callback
|
||||
* @param e {Object} see https://docs.angularjs.org/guide/expression#-event-
|
||||
*/
|
||||
$scope.logout = function (e) {
|
||||
e.preventDefault()
|
||||
e.preventDefault();
|
||||
return Auth.logout().then(function () {
|
||||
Session.destroy()
|
||||
$rootScope.currentUser = null
|
||||
$rootScope.toCheckNotifications = false
|
||||
Session.destroy();
|
||||
$rootScope.currentUser = null;
|
||||
$rootScope.toCheckNotifications = false;
|
||||
$scope.notifications = {
|
||||
total: 0,
|
||||
unread: 0
|
||||
}
|
||||
return $state.go('app.public.home')
|
||||
};
|
||||
return $state.go('app.public.home');
|
||||
}, function (error) {
|
||||
console.error(`An error occurred logging out: ${error}`);
|
||||
})
|
||||
}
|
||||
console.error(`An error occurred logging out: ${error}`);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Open the modal window allowing the user to create an account.
|
||||
* @param e {Object} see https://docs.angularjs.org/guide/expression#-event-
|
||||
*/
|
||||
$scope.signup = function (e) {
|
||||
if (e) { e.preventDefault() }
|
||||
if (e) { e.preventDefault(); }
|
||||
|
||||
return $uibModal.open({
|
||||
templateUrl: '<%= asset_path "shared/signupModal.html" %>',
|
||||
@ -95,33 +94,33 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco
|
||||
options: {
|
||||
startingDay: Fablab.weekStartingDay
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// callback to open the date picker (account creation modal)
|
||||
$scope.openDatePicker = function ($event) {
|
||||
$event.preventDefault()
|
||||
$event.stopPropagation()
|
||||
return $scope.datePicker.opened = true
|
||||
}
|
||||
$event.preventDefault();
|
||||
$event.stopPropagation();
|
||||
return $scope.datePicker.opened = true;
|
||||
};
|
||||
|
||||
// retrieve the groups (standard, student ...)
|
||||
Group.query(function(groups) {
|
||||
Group.query(function (groups) {
|
||||
$scope.groups = groups;
|
||||
})
|
||||
});
|
||||
|
||||
// retrieve the CGU
|
||||
CustomAsset.get({ name: 'cgu-file' }, function(cgu) {
|
||||
CustomAsset.get({ name: 'cgu-file' }, function (cgu) {
|
||||
$scope.cgu = cgu.custom_asset;
|
||||
})
|
||||
});
|
||||
|
||||
// default user's parameters
|
||||
$scope.user = {
|
||||
is_allow_contact: true,
|
||||
is_allow_newsletter: false
|
||||
}
|
||||
};
|
||||
|
||||
// Errors display
|
||||
$scope.alerts = []
|
||||
$scope.alerts = [];
|
||||
$scope.closeAlert = function (index) {
|
||||
$scope.alerts.splice(index, 1);
|
||||
};
|
||||
@ -134,15 +133,15 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco
|
||||
const orga = $scope.user.organization;
|
||||
delete $scope.user.organization;
|
||||
// register on server
|
||||
return Auth.register($scope.user).then(function(user) {
|
||||
return Auth.register($scope.user).then(function (user) {
|
||||
// creation successful
|
||||
$uibModalInstance.close(user)
|
||||
$uibModalInstance.close(user);
|
||||
}, function (error) {
|
||||
// creation failed...
|
||||
// restore organization param
|
||||
$scope.user.organization = orga
|
||||
$scope.user.organization = orga;
|
||||
// display errors
|
||||
angular.forEach(error.data.errors, function(v, k) {
|
||||
angular.forEach(error.data.errors, function (v, k) {
|
||||
angular.forEach(function (v, err) {
|
||||
$scope.alerts.push({
|
||||
msg: k + ': ' + err,
|
||||
@ -150,20 +149,20 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
};
|
||||
}]
|
||||
}).result['finally'](null).then(function(user) {
|
||||
}).result['finally'](null).then(function (user) {
|
||||
// when the account was created successfully, set the session to the newly created account
|
||||
$scope.setCurrentUser(user)
|
||||
})
|
||||
}
|
||||
$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 = function(token) {
|
||||
$scope.editPassword = function (token) {
|
||||
$uibModal.open({
|
||||
templateUrl: '<%= asset_path "shared/passwordEditModal.html" %>',
|
||||
size: 'md',
|
||||
@ -171,32 +170,32 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco
|
||||
$scope.user = { reset_password_token: token };
|
||||
$scope.alerts = [];
|
||||
$scope.closeAlert = function (index) {
|
||||
$scope.alerts.splice(index, 1)
|
||||
$scope.alerts.splice(index, 1);
|
||||
};
|
||||
|
||||
return $scope.changePassword = function () {
|
||||
$scope.alerts = []
|
||||
return $http.put('/users/password.json', { user: $scope.user }).success(function () { $uibModalInstance.close() }).error(function (data) {
|
||||
angular.forEach(data.errors, function(v, k) {
|
||||
angular.forEach(function(v, err) {
|
||||
$scope.alerts = [];
|
||||
return $http.put('/users/password.json', { user: $scope.user }).success(function () { $uibModalInstance.close(); }).error(function (data) {
|
||||
angular.forEach(data.errors, function (v, k) {
|
||||
angular.forEach(function (v, err) {
|
||||
$scope.alerts.push({
|
||||
msg: k + ': ' + err,
|
||||
type: 'danger'
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
}]
|
||||
}).result['finally'](null).then(function () {
|
||||
growl.success(_t('your_password_was_successfully_changed'))
|
||||
return Auth.login().then(function(user) {
|
||||
$scope.setCurrentUser(user)
|
||||
growl.success(_t('your_password_was_successfully_changed'));
|
||||
return Auth.login().then(function (user) {
|
||||
$scope.setCurrentUser(user);
|
||||
}, function (error) {
|
||||
console.error(`Authentication failed: ${error}`);
|
||||
}
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@ -204,25 +203,25 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco
|
||||
* @param event {Object} see https://docs.angularjs.org/guide/expression#-event-
|
||||
*/
|
||||
$scope.toggleNavSize = function (event) {
|
||||
let $classes, $targets
|
||||
let $classes, $targets;
|
||||
if (typeof event === 'undefined') {
|
||||
console.error('[ApplicationController::toggleNavSize] Missing event parameter')
|
||||
return
|
||||
console.error('[ApplicationController::toggleNavSize] Missing event parameter');
|
||||
return;
|
||||
}
|
||||
|
||||
let toggler = $(event.target)
|
||||
if (!toggler.data('toggle')) { toggler = toggler.closest('[data-toggle^="class"]') }
|
||||
let toggler = $(event.target);
|
||||
if (!toggler.data('toggle')) { toggler = toggler.closest('[data-toggle^="class"]'); }
|
||||
|
||||
const $class = toggler.data()['toggle']
|
||||
const $target = toggler.data('target') || toggler.attr('data-link')
|
||||
const $class = toggler.data()['toggle'];
|
||||
const $target = toggler.data('target') || toggler.attr('data-link');
|
||||
|
||||
if ($class) {
|
||||
const $tmp = $class.split(':')[1]
|
||||
if ($tmp) { $classes = $tmp.split(',') }
|
||||
const $tmp = $class.split(':')[1];
|
||||
if ($tmp) { $classes = $tmp.split(','); }
|
||||
}
|
||||
|
||||
if ($target) {
|
||||
$targets = $target.split(',')
|
||||
$targets = $target.split(',');
|
||||
}
|
||||
|
||||
if ($classes && $classes.length) {
|
||||
@ -230,93 +229,92 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco
|
||||
if ($classes[index].indexOf('*') !== -1) {
|
||||
const patt = new RegExp('\\s',
|
||||
+$classes[index].replace(/\*/g, '[A-Za-z0-9-_]+').split(' ').join('\\s|\\s'),
|
||||
+'\\s', 'g')
|
||||
+'\\s', 'g');
|
||||
$(toggler).each(function (i, it) {
|
||||
let cn = ` ${it.className} `
|
||||
let cn = ` ${it.className} `;
|
||||
while (patt.test(cn)) {
|
||||
cn = cn.replace(patt, ' ')
|
||||
cn = cn.replace(patt, ' ');
|
||||
}
|
||||
return it.className = $.trim(cn)
|
||||
})
|
||||
return it.className = $.trim(cn);
|
||||
});
|
||||
}
|
||||
|
||||
return (($targets[index] !== '#') && $($targets[index]).toggleClass($classes[index])) || toggler.toggleClass($classes[index])
|
||||
})
|
||||
return (($targets[index] !== '#') && $($targets[index]).toggleClass($classes[index])) || toggler.toggleClass($classes[index]);
|
||||
});
|
||||
}
|
||||
|
||||
toggler.toggleClass('active')
|
||||
}
|
||||
toggler.toggleClass('active');
|
||||
};
|
||||
|
||||
/* PRIVATE SCOPE */
|
||||
/* PRIVATE SCOPE */
|
||||
/**
|
||||
* Kind of constructor: these actions will be realized first when the controller is loaded
|
||||
*/
|
||||
const initialize = function () {
|
||||
// try to retrieve any currently logged user
|
||||
Auth.login().then(function (user) {
|
||||
$scope.setCurrentUser(user)
|
||||
$scope.setCurrentUser(user);
|
||||
// force users to complete their profile if they are not
|
||||
if (user.need_completion) {
|
||||
return $state.transitionTo('app.logged.profileCompletion')
|
||||
return $state.transitionTo('app.logged.profileCompletion');
|
||||
}
|
||||
}, function(error) {
|
||||
}, function (error) {
|
||||
console.error(`Authentication failed: ${error}`);
|
||||
$rootScope.toCheckNotifications = false
|
||||
})
|
||||
$rootScope.toCheckNotifications = false;
|
||||
});
|
||||
|
||||
// bind to the $stateChangeStart event (AngularJS/UI-Router)
|
||||
$rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
|
||||
if (!toState.data) { return }
|
||||
if (!toState.data) { return; }
|
||||
|
||||
const { authorizedRoles } = toState.data
|
||||
const { authorizedRoles } = toState.data;
|
||||
if (!AuthService.isAuthorized(authorizedRoles)) {
|
||||
event.preventDefault()
|
||||
event.preventDefault();
|
||||
if (AuthService.isAuthenticated()) {
|
||||
// user is not allowed
|
||||
console.error('[ApplicationController::initialize] user is not allowed')
|
||||
console.error('[ApplicationController::initialize] user is not allowed');
|
||||
} else {
|
||||
// user is not logged in
|
||||
openLoginModal(toState, toParams)
|
||||
openLoginModal(toState, toParams);
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// we stop polling notifications when the page is not in foreground
|
||||
onPageVisible(function(state) { $rootScope.toCheckNotifications = (state === 'visible') })
|
||||
onPageVisible(function (state) { $rootScope.toCheckNotifications = (state === 'visible'); });
|
||||
|
||||
Setting.get({ name: 'fablab_name' }, function(data) { $scope.fablabName = data.setting.value })
|
||||
Setting.get({ name: 'name_genre' }, function(data) { $scope.nameGenre = data.setting.value })
|
||||
Setting.get({ name: 'fablab_name' }, function (data) { $scope.fablabName = data.setting.value; });
|
||||
Setting.get({ name: 'name_genre' }, function (data) { $scope.nameGenre = data.setting.value; });
|
||||
|
||||
// shorthands
|
||||
$scope.isAuthenticated = Auth.isAuthenticated
|
||||
$scope.isAuthorized = AuthService.isAuthorized
|
||||
return $rootScope.login = $scope.login
|
||||
}
|
||||
$scope.isAuthenticated = Auth.isAuthenticated;
|
||||
$scope.isAuthorized = AuthService.isAuthorized;
|
||||
return $rootScope.login = $scope.login;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retreive once the notifications from the server and display a message popup for each new one.
|
||||
* Then, periodically check for new notifications.
|
||||
*/
|
||||
var getNotifications = function () {
|
||||
$rootScope.toCheckNotifications = true
|
||||
$rootScope.toCheckNotifications = true;
|
||||
if (!$rootScope.checkNotificationsIsInit && !!$rootScope.currentUser) {
|
||||
setTimeout(function() {
|
||||
setTimeout(function () {
|
||||
// we request the most recent notifications
|
||||
Notification.last_unread(function (notifications) {
|
||||
$rootScope.lastCheck = new Date()
|
||||
$scope.notifications = notifications.totals
|
||||
$rootScope.lastCheck = new Date();
|
||||
$scope.notifications = notifications.totals;
|
||||
|
||||
const toDisplay = [];
|
||||
angular.forEach(notifications.notifications, function(n) { toDisplay.push(n) });
|
||||
angular.forEach(notifications.notifications, function (n) { toDisplay.push(n); });
|
||||
|
||||
if (toDisplay.length < notifications.totals.unread) {
|
||||
toDisplay.push({ message: { description: _t('and_NUMBER_other_notifications', { NUMBER: notifications.totals.unread - toDisplay.length }, 'messageformat') } });
|
||||
}
|
||||
|
||||
angular.forEach(toDisplay, function(notification) { growl.info(notification.message.description); })
|
||||
})
|
||||
|
||||
}, 2000)
|
||||
angular.forEach(toDisplay, function (notification) { growl.info(notification.message.description); });
|
||||
});
|
||||
}, 2000);
|
||||
|
||||
const checkNotifications = function () {
|
||||
if ($rootScope.toCheckNotifications) {
|
||||
@ -324,15 +322,15 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco
|
||||
$rootScope.lastCheck = new Date();
|
||||
$scope.notifications = data.totals;
|
||||
|
||||
angular.forEach(data.notifications, function(notification) { growl.info(notification.message.description) });
|
||||
})
|
||||
angular.forEach(data.notifications, function (notification) { growl.info(notification.message.description); });
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$interval(checkNotifications, NOTIFICATIONS_CHECK_PERIOD);
|
||||
$rootScope.checkNotificationsIsInit = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Open the modal window allowing the user to log in.
|
||||
@ -340,19 +338,19 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco
|
||||
var openLoginModal = function (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)%>'
|
||||
$window.location.href = '<%=user_omniauth_authorize_path(AuthProvider.active.strategy_name.to_sym)%>';
|
||||
<% else %>
|
||||
return $uibModal.open({
|
||||
templateUrl: '<%= asset_path "shared/deviseModal.html" %>',
|
||||
size: 'sm',
|
||||
controller: ['$scope', '$uibModalInstance', '_t', function ($scope, $uibModalInstance, _t) {
|
||||
const user = ($scope.user = {})
|
||||
$scope.login = function() {
|
||||
const user = ($scope.user = {});
|
||||
$scope.login = function () {
|
||||
Auth.login(user).then(function (user) {
|
||||
// Authentication succeeded ...
|
||||
$uibModalInstance.close(user)
|
||||
$uibModalInstance.close(user);
|
||||
if (callback && (typeof callback === 'function')) {
|
||||
return callback(user)
|
||||
return callback(user);
|
||||
}
|
||||
}
|
||||
, function (error) {
|
||||
@ -361,57 +359,57 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco
|
||||
return $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 = function() { $uibModalInstance.dismiss('cancel') }
|
||||
$scope.dismiss = function () { $uibModalInstance.dismiss('cancel'); };
|
||||
|
||||
$scope.openSignup = function (e) {
|
||||
e.preventDefault()
|
||||
return $uibModalInstance.dismiss('signup')
|
||||
}
|
||||
e.preventDefault();
|
||||
return $uibModalInstance.dismiss('signup');
|
||||
};
|
||||
|
||||
return $scope.openResetPassword = function (e) {
|
||||
e.preventDefault()
|
||||
return $uibModalInstance.dismiss('resetPassword')
|
||||
}
|
||||
e.preventDefault();
|
||||
return $uibModalInstance.dismiss('resetPassword');
|
||||
};
|
||||
}]
|
||||
}).result['finally'](null).then(function (user) {
|
||||
// what to do when the modal is closed
|
||||
// what to do when the modal is closed
|
||||
|
||||
// authentication succeeded, set the session, gather the notifications and redirect
|
||||
$scope.setCurrentUser(user);
|
||||
// authentication succeeded, set the session, gather the notifications and redirect
|
||||
$scope.setCurrentUser(user);
|
||||
|
||||
if ((toState !== null) && (toParams !== null)) {
|
||||
return $state.go(toState, toParams)
|
||||
}
|
||||
}, function (reason) {
|
||||
// authentication did not ended successfully
|
||||
if (reason === 'signup') {
|
||||
// open signup modal
|
||||
$scope.signup();
|
||||
} else if (reason === 'resetPassword') {
|
||||
// open the 'reset password' modal
|
||||
return $uibModal.open({
|
||||
templateUrl: '<%= asset_path "shared/passwordNewModal.html" %>',
|
||||
size: 'sm',
|
||||
controller: ['$scope', '$uibModalInstance', '$http', function ($scope, $uibModalInstance, $http) {
|
||||
$scope.user = { email: '' }
|
||||
return $scope.sendReset = function () {
|
||||
$scope.alerts = []
|
||||
return $http.post('/users/password.json', { user: $scope.user }).success(function() { $uibModalInstance.close() }).error(function() {
|
||||
$scope.alerts.push({
|
||||
msg: _t('your_email_address_is_unknown'),
|
||||
type: 'danger'
|
||||
});
|
||||
})
|
||||
}
|
||||
}]
|
||||
}).result['finally'](null).then(function() { growl.info(_t('you_will_receive_in_a_moment_an_email_with_instructions_to_reset_your_password')) })
|
||||
}
|
||||
})
|
||||
}
|
||||
if ((toState !== null) && (toParams !== null)) {
|
||||
return $state.go(toState, toParams);
|
||||
}
|
||||
}, function (reason) {
|
||||
// authentication did not ended successfully
|
||||
if (reason === 'signup') {
|
||||
// open signup modal
|
||||
$scope.signup();
|
||||
} else if (reason === 'resetPassword') {
|
||||
// open the 'reset password' modal
|
||||
return $uibModal.open({
|
||||
templateUrl: '<%= asset_path "shared/passwordNewModal.html" %>',
|
||||
size: 'sm',
|
||||
controller: ['$scope', '$uibModalInstance', '$http', function ($scope, $uibModalInstance, $http) {
|
||||
$scope.user = { email: '' };
|
||||
return $scope.sendReset = function () {
|
||||
$scope.alerts = [];
|
||||
return $http.post('/users/password.json', { user: $scope.user }).success(function () { $uibModalInstance.close(); }).error(function () {
|
||||
$scope.alerts.push({
|
||||
msg: _t('your_email_address_is_unknown'),
|
||||
type: 'danger'
|
||||
});
|
||||
});
|
||||
};
|
||||
}]
|
||||
}).result['finally'](null).then(function () { 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 %>
|
||||
@ -422,11 +420,11 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco
|
||||
* Inspired by http://stackoverflow.com/questions/1060008/is-there-a-way-to-detect-if-a-browser-window-is-not-currently-active#answer-1060034
|
||||
*/
|
||||
var onPageVisible = function (callback) {
|
||||
let hidden = 'hidden'
|
||||
let hidden = 'hidden';
|
||||
|
||||
const onchange = function (evt) {
|
||||
const v = 'visible'
|
||||
const h = 'hidden'
|
||||
const v = 'visible';
|
||||
const h = 'hidden';
|
||||
const evtMap = {
|
||||
focus: v,
|
||||
focusin: v,
|
||||
@ -434,38 +432,38 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco
|
||||
blur: h,
|
||||
focusout: h,
|
||||
pagehide: h
|
||||
}
|
||||
evt = evt || window.event
|
||||
};
|
||||
evt = evt || window.event;
|
||||
if (evt.type in evtMap) {
|
||||
if (typeof callback === 'function') { callback(evtMap[evt.type]) }
|
||||
if (typeof callback === 'function') { callback(evtMap[evt.type]); }
|
||||
} else {
|
||||
if (typeof callback === 'function') { callback(this[hidden] ? 'hidden' : 'visible') }
|
||||
if (typeof callback === 'function') { callback(this[hidden] ? 'hidden' : 'visible'); }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Standards:
|
||||
if (hidden in document) {
|
||||
document.addEventListener('visibilitychange', onchange)
|
||||
document.addEventListener('visibilitychange', onchange);
|
||||
} else if ((hidden = 'mozHidden') in document) {
|
||||
document.addEventListener('mozvisibilitychange', onchange)
|
||||
document.addEventListener('mozvisibilitychange', onchange);
|
||||
} else if ((hidden = 'webkitHidden') in document) {
|
||||
document.addEventListener('webkitvisibilitychange', onchange)
|
||||
document.addEventListener('webkitvisibilitychange', onchange);
|
||||
} else if ((hidden = 'msHidden') in document) {
|
||||
document.addEventListener('msvisibilitychange', onchange)
|
||||
document.addEventListener('msvisibilitychange', onchange);
|
||||
// IE 9 and lower
|
||||
} else if ('onfocusin' in document) {
|
||||
document.onfocusin = (document.onfocusout = onchange)
|
||||
document.onfocusin = (document.onfocusout = onchange);
|
||||
// All others
|
||||
} else {
|
||||
window.onpageshow = (window.onpagehide = (window.onfocus = (window.onblur = onchange)))
|
||||
window.onpageshow = (window.onpagehide = (window.onfocus = (window.onblur = onchange)));
|
||||
}
|
||||
// set the initial state (but only if browser supports the Page Visibility API)
|
||||
if (document[hidden] !== undefined) {
|
||||
return onchange({ type: document[hidden] ? 'blur' : 'focus' })
|
||||
return onchange({ type: document[hidden] ? 'blur' : 'focus' });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// !!! MUST BE CALLED AT THE END of the controller
|
||||
return initialize()
|
||||
return initialize();
|
||||
}
|
||||
])
|
||||
]);
|
||||
|
@ -18,88 +18,88 @@ Application.Controllers.controller('EventsController', ['$scope', '$state', 'Eve
|
||||
/* PUBLIC SCOPE */
|
||||
|
||||
// The events displayed on the page
|
||||
$scope.events = []
|
||||
$scope.events = [];
|
||||
|
||||
// The currently displayed page number
|
||||
$scope.page = 1
|
||||
$scope.page = 1;
|
||||
|
||||
// List of categories for the events
|
||||
$scope.categories = categoriesPromise
|
||||
$scope.categories = categoriesPromise;
|
||||
|
||||
// List of events themes
|
||||
$scope.themes = themesPromise
|
||||
$scope.themes = themesPromise;
|
||||
|
||||
// List of age ranges
|
||||
$scope.ageRanges = ageRangesPromise
|
||||
$scope.ageRanges = ageRangesPromise;
|
||||
|
||||
// Hide or show the 'load more' button
|
||||
$scope.noMoreResults = false
|
||||
$scope.noMoreResults = false;
|
||||
|
||||
// Active filters for the events list
|
||||
$scope.filters = {
|
||||
category_id: null,
|
||||
theme_id: null,
|
||||
age_range_id: null
|
||||
}
|
||||
};
|
||||
|
||||
$scope.monthNames = [<%= t('date.month_names')[1..-1].map { |m| "\"#{m}\"" }.join(', ') %>]
|
||||
$scope.monthNames = [<%= t('date.month_names')[1..-1].map { |m| "\"#{m}\"" }.join(', ') %>];
|
||||
|
||||
/**
|
||||
* Adds a resultset of events to the bottom of the page, grouped by month
|
||||
*/
|
||||
$scope.loadMoreEvents = function () {
|
||||
$scope.page += 1
|
||||
$scope.page += 1;
|
||||
return Event.query(Object.assign({ page: $scope.page }, $scope.filters), function (data) {
|
||||
$scope.events = $scope.events.concat(data)
|
||||
groupEvents($scope.events)
|
||||
$scope.events = $scope.events.concat(data);
|
||||
groupEvents($scope.events);
|
||||
|
||||
if (!data[0] || (data[0].nb_total_events <= $scope.events.length)) {
|
||||
return $scope.noMoreResults = true
|
||||
return $scope.noMoreResults = true;
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback to redirect the user to the specified event page
|
||||
* @param event {{id:number}}
|
||||
*/
|
||||
$scope.showEvent = function(event) { $state.go('app.public.events_show', { id: event.id }); };
|
||||
$scope.showEvent = function (event) { $state.go('app.public.events_show', { id: event.id }); };
|
||||
|
||||
/**
|
||||
* Callback to refresh the events list according to the filters set
|
||||
*/
|
||||
$scope.filterEvents = function () {
|
||||
// reinitialize results datasets
|
||||
$scope.page = 1
|
||||
$scope.eventsGroupByMonth = {}
|
||||
$scope.events = []
|
||||
$scope.monthOrder = []
|
||||
$scope.noMoreResults = false
|
||||
$scope.page = 1;
|
||||
$scope.eventsGroupByMonth = {};
|
||||
$scope.events = [];
|
||||
$scope.monthOrder = [];
|
||||
$scope.noMoreResults = false;
|
||||
|
||||
// run a search query
|
||||
return Event.query(Object.assign({ page: $scope.page }, $scope.filters), function (data) {
|
||||
$scope.events = data
|
||||
groupEvents(data)
|
||||
$scope.events = data;
|
||||
groupEvents(data);
|
||||
|
||||
if (!data[0] || (data[0].nb_total_events <= $scope.events.length)) {
|
||||
return $scope.noMoreResults = true
|
||||
return $scope.noMoreResults = true;
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Test if the provided event occurs on a single day or on many days
|
||||
* @param event {{start_date:Date, end_date:Date}} Event object as retreived from the API
|
||||
* @return {boolean} false if the event occurs on many days
|
||||
*/
|
||||
$scope.onSingleDay = function(event) { moment(event.start_date).isSame(event.end_date, 'day'); };
|
||||
$scope.onSingleDay = function (event) { moment(event.start_date).isSame(event.end_date, 'day'); };
|
||||
|
||||
/* PRIVATE SCOPE */
|
||||
/* PRIVATE SCOPE */
|
||||
|
||||
/**
|
||||
* Kind of constructor: these actions will be realized first when the controller is loaded
|
||||
*/
|
||||
const initialize = function() {
|
||||
const initialize = function () {
|
||||
$scope.filterEvents();
|
||||
};
|
||||
|
||||
@ -111,31 +111,31 @@ Application.Controllers.controller('EventsController', ['$scope', '$state', 'Eve
|
||||
*/
|
||||
const groupEvents = function (events) {
|
||||
if (events.length > 0) {
|
||||
const eventsGroupedByMonth = _.groupBy(events, function(obj) {
|
||||
return _.map(['month_id', 'year'], function(key) {
|
||||
const eventsGroupedByMonth = _.groupBy(events, function (obj) {
|
||||
return _.map(['month_id', 'year'], function (key) {
|
||||
return obj[key];
|
||||
});
|
||||
})
|
||||
$scope.eventsGroupByMonth = Object.assign($scope.eventsGroupByMonth, eventsGroupedByMonth)
|
||||
return $scope.monthOrder = Object.keys($scope.eventsGroupByMonth)
|
||||
});
|
||||
$scope.eventsGroupByMonth = Object.assign($scope.eventsGroupByMonth, eventsGroupedByMonth);
|
||||
return $scope.monthOrder = Object.keys($scope.eventsGroupByMonth);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// # !!! MUST BE CALLED AT THE END of the controller
|
||||
initialize()
|
||||
initialize();
|
||||
}
|
||||
])
|
||||
]);
|
||||
|
||||
Application.Controllers.controller('ShowEventController', ['$scope', '$state', '$stateParams', 'Event', '$uibModal', 'Member', 'Reservation', 'Price', 'CustomAsset', 'eventPromise', 'growl', '_t', 'Wallet', 'helpers', 'dialogs', 'priceCategoriesPromise', 'settingsPromise',
|
||||
function ($scope, $state, $stateParams, Event, $uibModal, Member, Reservation, Price, CustomAsset, eventPromise, growl, _t, Wallet, helpers, dialogs, priceCategoriesPromise, settingsPromise) {
|
||||
/* PUBLIC SCOPE */
|
||||
|
||||
// reservations for the currently shown event
|
||||
$scope.reservations = []
|
||||
$scope.reservations = [];
|
||||
|
||||
// user to deal with
|
||||
$scope.ctrl =
|
||||
{ member: {} }
|
||||
{ member: {} };
|
||||
|
||||
// parameters for a new reservation
|
||||
$scope.reserve = {
|
||||
@ -148,26 +148,26 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
||||
amountTotal: 0,
|
||||
totalNoCoupon: 0,
|
||||
totalSeats: 0
|
||||
}
|
||||
};
|
||||
|
||||
// Discount coupon to apply to the basket, if any
|
||||
$scope.coupon =
|
||||
{ applied: null }
|
||||
{ applied: null };
|
||||
|
||||
// Get the details for the current event (event's id is recovered from the current URL)
|
||||
$scope.event = eventPromise
|
||||
$scope.event = eventPromise;
|
||||
|
||||
// List of price categories for the events
|
||||
$scope.priceCategories = priceCategoriesPromise
|
||||
$scope.priceCategories = priceCategoriesPromise;
|
||||
|
||||
// Global config: is the user authorized to change his bookings slots?
|
||||
$scope.enableBookingMove = (settingsPromise.booking_move_enable === 'true')
|
||||
$scope.enableBookingMove = (settingsPromise.booking_move_enable === 'true');
|
||||
|
||||
// Global config: delay in hours before a booking while changing the booking slot is forbidden
|
||||
$scope.moveBookingDelay = parseInt(settingsPromise.booking_move_delay)
|
||||
$scope.moveBookingDelay = parseInt(settingsPromise.booking_move_delay);
|
||||
|
||||
// Message displayed to the end user about rules that applies to events reservations
|
||||
$scope.eventExplicationsAlert = settingsPromise.event_explications_alert
|
||||
$scope.eventExplicationsAlert = settingsPromise.event_explications_alert;
|
||||
|
||||
/**
|
||||
* Callback to delete the provided event (admins only)
|
||||
@ -180,91 +180,92 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
||||
return {
|
||||
title: _t('confirmation_required'),
|
||||
msg: _t('do_you_really_want_to_delete_this_event')
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}, function() {
|
||||
}, function () {
|
||||
// the admin has confirmed, delete
|
||||
event.$delete(function() {
|
||||
$state.go('app.public.events_list')
|
||||
return growl.info(_t('event_successfully_deleted'))
|
||||
}, function(error) {
|
||||
event.$delete(function () {
|
||||
$state.go('app.public.events_list');
|
||||
return growl.info(_t('event_successfully_deleted'));
|
||||
}, function (error) {
|
||||
console.error(error);
|
||||
growl.error(_t('unable_to_delete_the_event_because_some_users_alredy_booked_it'));
|
||||
})}
|
||||
)
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback to call when the number of tickets to book changes in the current booking
|
||||
*/
|
||||
$scope.changeNbPlaces = function () {
|
||||
// compute the total remaning places
|
||||
let remain = $scope.event.nb_free_places - $scope.reserve.nbReservePlaces
|
||||
let remain = $scope.event.nb_free_places - $scope.reserve.nbReservePlaces;
|
||||
for (let ticket in $scope.reserve.tickets) {
|
||||
remain -= $scope.reserve.tickets[ticket]
|
||||
remain -= $scope.reserve.tickets[ticket];
|
||||
}
|
||||
// we store the total number of seats booked, this is used to know if the 'pay' button must be shown
|
||||
$scope.reserve.totalSeats = $scope.event.nb_free_places - remain
|
||||
$scope.reserve.totalSeats = $scope.event.nb_free_places - remain;
|
||||
|
||||
// update the available seats for full price tickets
|
||||
const fullPriceRemains = $scope.reserve.nbReservePlaces + remain
|
||||
$scope.reserve.nbPlaces.normal = __range__(0, fullPriceRemains, true)
|
||||
const fullPriceRemains = $scope.reserve.nbReservePlaces + remain;
|
||||
$scope.reserve.nbPlaces.normal = __range__(0, fullPriceRemains, true);
|
||||
|
||||
// update the available seats for other prices tickets
|
||||
for (let key in $scope.reserve.nbPlaces) {
|
||||
if (key !== 'normal') {
|
||||
const priceRemain = $scope.reserve.tickets[key] + remain
|
||||
$scope.reserve.nbPlaces[key] = __range__(0, priceRemain, true)
|
||||
const priceRemain = $scope.reserve.tickets[key] + remain;
|
||||
$scope.reserve.nbPlaces[key] = __range__(0, priceRemain, true);
|
||||
}
|
||||
}
|
||||
|
||||
// recompute the total price
|
||||
return $scope.computeEventAmount()
|
||||
}
|
||||
return $scope.computeEventAmount();
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback to reset the current reservation parameters
|
||||
* @param e {Object} see https://docs.angularjs.org/guide/expression#-event-
|
||||
*/
|
||||
$scope.cancelReserve = function (e) {
|
||||
e.preventDefault()
|
||||
return resetEventReserve()
|
||||
}
|
||||
e.preventDefault();
|
||||
return resetEventReserve();
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback to allow the user to set the details for his reservation
|
||||
*/
|
||||
$scope.reserveEvent = function () {
|
||||
if ($scope.event.nb_total_places > 0) {
|
||||
$scope.reserveSuccess = false
|
||||
$scope.reserveSuccess = false;
|
||||
if (!$scope.isAuthenticated()) {
|
||||
return $scope.login(null, function (user) {
|
||||
$scope.reserve.toReserve = !$scope.reserve.toReserve
|
||||
$scope.reserve.toReserve = !$scope.reserve.toReserve;
|
||||
if (user.role !== 'admin') {
|
||||
return $scope.ctrl.member = user
|
||||
return $scope.ctrl.member = user;
|
||||
}
|
||||
})
|
||||
});
|
||||
} else {
|
||||
return $scope.reserve.toReserve = !$scope.reserve.toReserve
|
||||
return $scope.reserve.toReserve = !$scope.reserve.toReserve;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback to deal with the reservations of the user selected in the dropdown list instead of the current user's
|
||||
* reservations. (admins only)
|
||||
*/
|
||||
$scope.updateMember = function () {
|
||||
resetEventReserve()
|
||||
$scope.reserveSuccess = false
|
||||
resetEventReserve();
|
||||
$scope.reserveSuccess = false;
|
||||
if ($scope.ctrl.member) {
|
||||
return Member.get({ id: $scope.ctrl.member.id }, function (member) {
|
||||
$scope.ctrl.member = member
|
||||
return getReservations($scope.event.id, 'Event', $scope.ctrl.member.id)
|
||||
})
|
||||
$scope.ctrl.member = member;
|
||||
return getReservations($scope.event.id, 'Event', $scope.ctrl.member.id);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback to trigger the payment process of the current reservation
|
||||
@ -272,23 +273,23 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
||||
$scope.payEvent = function () {
|
||||
// first, we check that a user was selected
|
||||
if (Object.keys($scope.ctrl.member).length > 0) {
|
||||
const reservation = mkReservation($scope.ctrl.member, $scope.reserve, $scope.event)
|
||||
const reservation = mkReservation($scope.ctrl.member, $scope.reserve, $scope.event);
|
||||
|
||||
return Wallet.getWalletByUser({ user_id: $scope.ctrl.member.id }, function (wallet) {
|
||||
const amountToPay = helpers.getAmountToPay($scope.reserve.amountTotal, wallet.amount)
|
||||
const amountToPay = helpers.getAmountToPay($scope.reserve.amountTotal, wallet.amount);
|
||||
if (($scope.currentUser.role !== 'admin') && (amountToPay > 0)) {
|
||||
return payByStripe(reservation)
|
||||
return payByStripe(reservation);
|
||||
} else {
|
||||
if (($scope.currentUser.role === 'admin') || (amountToPay === 0)) {
|
||||
return payOnSite(reservation)
|
||||
return payOnSite(reservation);
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
} else {
|
||||
// otherwise we alert, this error musn't occur when the current user is not admin
|
||||
return growl.error(_t('please_select_a_member_first'))
|
||||
return growl.error(_t('please_select_a_member_first'));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback to validate the booking of a free event
|
||||
@ -301,40 +302,40 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
||||
slots_attributes: [],
|
||||
nb_reserve_places: $scope.reserve.nbReservePlaces,
|
||||
tickets_attributes: []
|
||||
}
|
||||
};
|
||||
// a single slot is used for events
|
||||
reservation.slots_attributes.push({
|
||||
start_at: $scope.event.start_date,
|
||||
end_at: $scope.event.end_date,
|
||||
availability_id: $scope.event.availability.id
|
||||
})
|
||||
});
|
||||
// iterate over reservations per prices
|
||||
for (let price_id in $scope.reserve.tickets) {
|
||||
const seats = $scope.reserve.tickets[price_id]
|
||||
const seats = $scope.reserve.tickets[price_id];
|
||||
reservation.tickets_attributes.push({
|
||||
event_price_category_id: price_id,
|
||||
booked: seats
|
||||
})
|
||||
});
|
||||
}
|
||||
// set the attempting marker
|
||||
$scope.attempting = true
|
||||
$scope.attempting = true;
|
||||
// save the reservation to the API
|
||||
return Reservation.save({ reservation }, function (reservation) {
|
||||
// reservation successfull
|
||||
afterPayment(reservation)
|
||||
return $scope.attempting = false
|
||||
afterPayment(reservation);
|
||||
return $scope.attempting = false;
|
||||
}
|
||||
, function (response) {
|
||||
// reservation failed
|
||||
$scope.alerts = []
|
||||
$scope.alerts = [];
|
||||
$scope.alerts.push({
|
||||
msg: response.data.card[0],
|
||||
type: 'danger'
|
||||
})
|
||||
});
|
||||
// unset the attempting marker
|
||||
return $scope.attempting = false
|
||||
})
|
||||
}
|
||||
return $scope.attempting = false;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback to alter an already booked reservation date. A modal window will be opened to allow the user to choose
|
||||
@ -343,89 +344,89 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
||||
* @param e {Object} see https://docs.angularjs.org/guide/expression#-event-
|
||||
*/
|
||||
$scope.modifyReservation = function (reservation, e) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
const index = $scope.reservations.indexOf(reservation)
|
||||
const index = $scope.reservations.indexOf(reservation);
|
||||
return $uibModal.open({
|
||||
templateUrl: '<%= asset_path "events/modify_event_reservation_modal.html" %>',
|
||||
resolve: {
|
||||
event () { return $scope.event },
|
||||
reservation () { return reservation }
|
||||
event () { return $scope.event; },
|
||||
reservation () { return reservation; }
|
||||
},
|
||||
controller: ['$scope', '$uibModalInstance', 'event', 'reservation', 'Reservation', function ($scope, $uibModalInstance, event, reservation, Reservation) {
|
||||
// we copy the controller's resolved parameters into the scope
|
||||
$scope.event = event
|
||||
$scope.reservation = angular.copy(reservation)
|
||||
$scope.event = event;
|
||||
$scope.reservation = angular.copy(reservation);
|
||||
|
||||
// set the reservable_id to the first available event
|
||||
for (e of Array.from(event.recurrence_events)) {
|
||||
if (e.nb_free_places > reservation.total_booked_seats) {
|
||||
$scope.reservation.reservable_id = e.id
|
||||
break
|
||||
$scope.reservation.reservable_id = e.id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Callback to validate the new reservation's date
|
||||
$scope.ok = function () {
|
||||
let eventToPlace = null
|
||||
let eventToPlace = null;
|
||||
angular.forEach(event.recurrence_events, function (e) {
|
||||
if (e.id === parseInt($scope.reservation.reservable_id, 10)) {
|
||||
return eventToPlace = e
|
||||
return eventToPlace = e;
|
||||
}
|
||||
})
|
||||
$scope.reservation.slots[0].start_at = eventToPlace.start_date
|
||||
$scope.reservation.slots[0].end_at = eventToPlace.end_date
|
||||
$scope.reservation.slots[0].availability_id = eventToPlace.availability_id
|
||||
$scope.reservation.slots_attributes = $scope.reservation.slots
|
||||
$scope.attempting = true
|
||||
});
|
||||
$scope.reservation.slots[0].start_at = eventToPlace.start_date;
|
||||
$scope.reservation.slots[0].end_at = eventToPlace.end_date;
|
||||
$scope.reservation.slots[0].availability_id = eventToPlace.availability_id;
|
||||
$scope.reservation.slots_attributes = $scope.reservation.slots;
|
||||
$scope.attempting = true;
|
||||
Reservation.update({ id: reservation.id }, { reservation: $scope.reservation }, function (reservation) {
|
||||
$uibModalInstance.close(reservation)
|
||||
$scope.attempting = true
|
||||
$uibModalInstance.close(reservation);
|
||||
$scope.attempting = true;
|
||||
}
|
||||
, function (response) {
|
||||
$scope.alerts = []
|
||||
angular.forEach(response, function(v, k) {
|
||||
angular.forEach(v, function(err) {
|
||||
$scope.alerts.push({ msg: k + ': ' + err, type: 'danger' }) ;
|
||||
})
|
||||
})
|
||||
$scope.alerts = [];
|
||||
angular.forEach(response, function (v, k) {
|
||||
angular.forEach(v, function (err) {
|
||||
$scope.alerts.push({ msg: k + ': ' + err, type: 'danger' });
|
||||
});
|
||||
});
|
||||
$scope.attempting = false;
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Callback to cancel the modification
|
||||
$scope.cancel = function() { $uibModalInstance.dismiss('cancel') }
|
||||
$scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
|
||||
}
|
||||
] })
|
||||
.result['finally'](null).then(function (reservation) {
|
||||
// remove the reservation from the user's reservations list for this event (occurrence)
|
||||
$scope.reservations.splice(index, 1)
|
||||
$scope.reservations.splice(index, 1);
|
||||
// add the number of places transfered (to the new date) to the total of free places for this event
|
||||
$scope.event.nb_free_places = $scope.event.nb_free_places + reservation.total_booked_seats
|
||||
$scope.event.nb_free_places = $scope.event.nb_free_places + reservation.total_booked_seats;
|
||||
// remove the number of places transfered from the total of free places of the receiving occurrance
|
||||
angular.forEach($scope.event.recurrence_events, function (e) {
|
||||
if (e.id === parseInt(reservation.reservable.id, 10)) {
|
||||
return e.nb_free_places = e.nb_free_places - reservation.total_booked_seats
|
||||
return e.nb_free_places = e.nb_free_places - reservation.total_booked_seats;
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the provided reservation is able to be moved (date change)
|
||||
* @param reservation {{total_booked_seats:number}}
|
||||
*/
|
||||
$scope.reservationCanModify = function (reservation) {
|
||||
const slotStart = moment(reservation.slots[0].start_at)
|
||||
const now = moment()
|
||||
const slotStart = moment(reservation.slots[0].start_at);
|
||||
const now = moment();
|
||||
|
||||
let isAble = false
|
||||
let isAble = false;
|
||||
angular.forEach($scope.event.recurrence_events, function (e) {
|
||||
if (e.nb_free_places >= reservation.total_booked_seats) { return isAble = true }
|
||||
})
|
||||
return (isAble && $scope.enableBookingMove && (slotStart.diff(now, 'hours') >= $scope.moveBookingDelay))
|
||||
}
|
||||
if (e.nb_free_places >= reservation.total_booked_seats) { return isAble = true; }
|
||||
});
|
||||
return (isAble && $scope.enableBookingMove && (slotStart.diff(now, 'hours') >= $scope.moveBookingDelay));
|
||||
};
|
||||
|
||||
/**
|
||||
* Compute the total amount for the current reservation according to the previously set parameters
|
||||
@ -434,25 +435,25 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
||||
$scope.computeEventAmount = function () {
|
||||
// first we check that a user was selected
|
||||
if (Object.keys($scope.ctrl.member).length > 0) {
|
||||
const r = mkReservation($scope.ctrl.member, $scope.reserve, $scope.event)
|
||||
const r = mkReservation($scope.ctrl.member, $scope.reserve, $scope.event);
|
||||
return Price.compute(mkRequestParams(r, $scope.coupon.applied), function (res) {
|
||||
$scope.reserve.amountTotal = res.price
|
||||
return $scope.reserve.totalNoCoupon = res.price_without_coupon
|
||||
})
|
||||
$scope.reserve.amountTotal = res.price;
|
||||
return $scope.reserve.totalNoCoupon = res.price_without_coupon;
|
||||
});
|
||||
} else {
|
||||
return $scope.reserve.amountTotal = null
|
||||
return $scope.reserve.amountTotal = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the URL allowing to share the current project on the Facebook social network
|
||||
*/
|
||||
$scope.shareOnFacebook = function () { return `https://www.facebook.com/share.php?u=${$state.href('app.public.events_show', { id: $scope.event.id }, { absolute: true }).replace('#', '%23')}`; }
|
||||
$scope.shareOnFacebook = function () { return `https://www.facebook.com/share.php?u=${$state.href('app.public.events_show', { id: $scope.event.id }, { absolute: true }).replace('#', '%23')}`; };
|
||||
|
||||
/**
|
||||
* Return the URL allowing to share the current project on the Twitter social network
|
||||
*/
|
||||
$scope.shareOnTwitter = function () { return `https://twitter.com/intent/tweet?url=${encodeURIComponent($state.href('app.public.events_show', { id: $scope.event.id }, { absolute: true }))}&text=${encodeURIComponent($scope.event.title)}`; }
|
||||
$scope.shareOnTwitter = function () { return `https://twitter.com/intent/tweet?url=${encodeURIComponent($state.href('app.public.events_show', { id: $scope.event.id }, { absolute: true }))}&text=${encodeURIComponent($scope.event.title)}`; };
|
||||
|
||||
/**
|
||||
* Return the textual description of the conditions applyable to the given price's category
|
||||
@ -461,12 +462,12 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
||||
$scope.getPriceCategoryConditions = function (category_id) {
|
||||
for (let cat of Array.from($scope.priceCategories)) {
|
||||
if (cat.id === category_id) {
|
||||
return cat.conditions
|
||||
return cat.conditions;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* PRIVATE SCOPE */
|
||||
/* PRIVATE SCOPE */
|
||||
|
||||
/**
|
||||
* Kind of constructor: these actions will be realized first when the controller is loaded
|
||||
@ -475,25 +476,25 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
||||
// set the controlled user as the current user if the current user is not an admin
|
||||
if ($scope.currentUser) {
|
||||
if ($scope.currentUser.role !== 'admin') {
|
||||
$scope.ctrl.member = $scope.currentUser
|
||||
$scope.ctrl.member = $scope.currentUser;
|
||||
}
|
||||
}
|
||||
|
||||
// initialize the "reserve" object with the event's data
|
||||
resetEventReserve()
|
||||
resetEventReserve();
|
||||
|
||||
// if non-admin, get the current user's reservations into $scope.reservations
|
||||
if ($scope.currentUser) {
|
||||
getReservations($scope.event.id, 'Event', $scope.currentUser.id)
|
||||
getReservations($scope.event.id, 'Event', $scope.currentUser.id);
|
||||
}
|
||||
|
||||
// watch when a coupon is applied to re-compute the total price
|
||||
return $scope.$watch('coupon.applied', function (newValue, oldValue) {
|
||||
if ((newValue !== null) || (oldValue !== null)) {
|
||||
return $scope.computeEventAmount()
|
||||
return $scope.computeEventAmount();
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve the reservations for the couple event / user
|
||||
@ -506,7 +507,7 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
||||
reservable_id,
|
||||
reservable_type,
|
||||
user_id
|
||||
}).$promise.then(function (reservations) { $scope.reservations = reservations })
|
||||
}).$promise.then(function (reservations) { $scope.reservations = reservations; });
|
||||
};
|
||||
|
||||
/**
|
||||
@ -524,27 +525,27 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
||||
slots_attributes: [],
|
||||
nb_reserve_places: reserve.nbReservePlaces,
|
||||
tickets_attributes: []
|
||||
}
|
||||
};
|
||||
|
||||
reservation.slots_attributes.push({
|
||||
start_at: event.start_date,
|
||||
end_at: event.end_date,
|
||||
availability_id: event.availability.id,
|
||||
offered: event.offered || false
|
||||
})
|
||||
});
|
||||
|
||||
for (let evt_px_cat of Array.from(event.prices)) {
|
||||
const booked = reserve.tickets[evt_px_cat.id]
|
||||
const booked = reserve.tickets[evt_px_cat.id];
|
||||
if (booked > 0) {
|
||||
reservation.tickets_attributes.push({
|
||||
event_price_category_id: evt_px_cat.id,
|
||||
booked
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return reservation
|
||||
}
|
||||
return reservation;
|
||||
};
|
||||
|
||||
/**
|
||||
* Format the parameters expected by /api/prices/compute or /api/reservations and return the resulting object
|
||||
@ -556,10 +557,10 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
||||
const params = {
|
||||
reservation,
|
||||
coupon_code: ((coupon ? coupon.code : undefined))
|
||||
}
|
||||
};
|
||||
|
||||
return params
|
||||
}
|
||||
return params;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the current reservation to the default values. This implies to reservation form to be hidden.
|
||||
@ -575,16 +576,16 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
||||
toReserve: false,
|
||||
amountTotal: 0,
|
||||
totalSeats: 0
|
||||
}
|
||||
};
|
||||
|
||||
for (let evt_px_cat of Array.from($scope.event.prices)) {
|
||||
$scope.reserve.nbPlaces[evt_px_cat.id] = __range__(0, $scope.event.nb_free_places, true)
|
||||
$scope.reserve.tickets[evt_px_cat.id] = 0
|
||||
$scope.reserve.nbPlaces[evt_px_cat.id] = __range__(0, $scope.event.nb_free_places, true);
|
||||
$scope.reserve.tickets[evt_px_cat.id] = 0;
|
||||
}
|
||||
|
||||
return $scope.event.offered = false
|
||||
return $scope.event.offered = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Open a modal window which trigger the stripe payment process
|
||||
@ -596,66 +597,66 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
||||
size: 'md',
|
||||
resolve: {
|
||||
reservation () {
|
||||
return reservation
|
||||
return reservation;
|
||||
},
|
||||
price () {
|
||||
return Price.compute(mkRequestParams(reservation, $scope.coupon.applied)).$promise
|
||||
return Price.compute(mkRequestParams(reservation, $scope.coupon.applied)).$promise;
|
||||
},
|
||||
wallet () {
|
||||
return Wallet.getWalletByUser({ user_id: reservation.user_id }).$promise
|
||||
return Wallet.getWalletByUser({ user_id: reservation.user_id }).$promise;
|
||||
},
|
||||
cgv () {
|
||||
return CustomAsset.get({ name: 'cgv-file' }).$promise
|
||||
return CustomAsset.get({ name: 'cgv-file' }).$promise;
|
||||
},
|
||||
objectToPay () {
|
||||
return {
|
||||
eventToReserve: $scope.event,
|
||||
reserve: $scope.reserve,
|
||||
member: $scope.ctrl.member
|
||||
}
|
||||
};
|
||||
},
|
||||
coupon () {
|
||||
return $scope.coupon.applied
|
||||
return $scope.coupon.applied;
|
||||
}
|
||||
},
|
||||
controller: ['$scope', '$uibModalInstance', '$state', 'reservation', 'price', 'cgv', 'Auth', 'Reservation', 'growl', 'wallet', 'helpers', '$filter', 'coupon',
|
||||
function ($scope, $uibModalInstance, $state, reservation, price, cgv, Auth, Reservation, growl, wallet, helpers, $filter, coupon) {
|
||||
// User's wallet amount
|
||||
$scope.walletAmount = wallet.amount
|
||||
$scope.walletAmount = wallet.amount;
|
||||
|
||||
// Price
|
||||
$scope.amount = helpers.getAmountToPay(price.price, wallet.amount)
|
||||
$scope.amount = helpers.getAmountToPay(price.price, wallet.amount);
|
||||
|
||||
// CGV
|
||||
$scope.cgv = cgv.custom_asset
|
||||
$scope.cgv = cgv.custom_asset;
|
||||
|
||||
// Reservation
|
||||
$scope.reservation = reservation
|
||||
$scope.reservation = reservation;
|
||||
|
||||
// Used in wallet info template to interpolate some translations
|
||||
$scope.numberFilter = $filter('number')
|
||||
$scope.numberFilter = $filter('number');
|
||||
|
||||
// Callback for the stripe payment authorization
|
||||
return $scope.payment = function (status, response) {
|
||||
if (response.error) {
|
||||
return growl.error(response.error.message)
|
||||
return growl.error(response.error.message);
|
||||
} else {
|
||||
$scope.attempting = true
|
||||
$scope.reservation.card_token = response.id
|
||||
Reservation.save(mkRequestParams($scope.reservation, coupon), function(reservation) { $uibModalInstance.close(reservation); }
|
||||
$scope.attempting = true;
|
||||
$scope.reservation.card_token = response.id;
|
||||
Reservation.save(mkRequestParams($scope.reservation, coupon), function (reservation) { $uibModalInstance.close(reservation); }
|
||||
, function (response) {
|
||||
$scope.alerts = []
|
||||
$scope.alerts = [];
|
||||
$scope.alerts.push({
|
||||
msg: response.data.card[0],
|
||||
type: 'danger'
|
||||
})
|
||||
return $scope.attempting = false
|
||||
})
|
||||
});
|
||||
return $scope.attempting = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
]
|
||||
}).result['finally'](null).then(function(reservation) { afterPayment(reservation); })
|
||||
}).result['finally'](null).then(function (reservation) { afterPayment(reservation); });
|
||||
};
|
||||
|
||||
/**
|
||||
@ -668,100 +669,100 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
||||
size: 'sm',
|
||||
resolve: {
|
||||
reservation () {
|
||||
return reservation
|
||||
return reservation;
|
||||
},
|
||||
price () {
|
||||
return Price.compute(mkRequestParams(reservation, $scope.coupon.applied)).$promise
|
||||
return Price.compute(mkRequestParams(reservation, $scope.coupon.applied)).$promise;
|
||||
},
|
||||
wallet () {
|
||||
return Wallet.getWalletByUser({ user_id: reservation.user_id }).$promise
|
||||
return Wallet.getWalletByUser({ user_id: reservation.user_id }).$promise;
|
||||
},
|
||||
coupon () {
|
||||
return $scope.coupon.applied
|
||||
return $scope.coupon.applied;
|
||||
}
|
||||
},
|
||||
controller: ['$scope', '$uibModalInstance', '$state', 'reservation', 'price', 'Auth', 'Reservation', 'wallet', 'helpers', '$filter', 'coupon',
|
||||
function ($scope, $uibModalInstance, $state, reservation, price, Auth, Reservation, wallet, helpers, $filter, coupon) {
|
||||
// User's wallet amount
|
||||
$scope.walletAmount = wallet.amount
|
||||
$scope.walletAmount = wallet.amount;
|
||||
|
||||
// Price
|
||||
$scope.price = price.price
|
||||
$scope.price = price.price;
|
||||
|
||||
// price to pay
|
||||
$scope.amount = helpers.getAmountToPay(price.price, wallet.amount)
|
||||
$scope.amount = helpers.getAmountToPay(price.price, wallet.amount);
|
||||
|
||||
// Reservation
|
||||
$scope.reservation = reservation
|
||||
$scope.reservation = reservation;
|
||||
|
||||
// Used in wallet info template to interpolate some translations
|
||||
$scope.numberFilter = $filter('number')
|
||||
$scope.numberFilter = $filter('number');
|
||||
|
||||
// Button label
|
||||
if ($scope.amount > 0) {
|
||||
$scope.validButtonName = _t('confirm_payment_of_html', { ROLE: $scope.currentUser.role, AMOUNT: $filter('currency')($scope.amount) }, 'messageformat')
|
||||
$scope.validButtonName = _t('confirm_payment_of_html', { ROLE: $scope.currentUser.role, AMOUNT: $filter('currency')($scope.amount) }, 'messageformat');
|
||||
} else {
|
||||
if ((price.price > 0) && ($scope.walletAmount === 0)) {
|
||||
$scope.validButtonName = _t('confirm_payment_of_html', { ROLE: $scope.currentUser.role, AMOUNT: $filter('currency')(price.price) }, 'messageformat')
|
||||
$scope.validButtonName = _t('confirm_payment_of_html', { ROLE: $scope.currentUser.role, AMOUNT: $filter('currency')(price.price) }, 'messageformat');
|
||||
} else {
|
||||
$scope.validButtonName = _t('confirm')
|
||||
$scope.validButtonName = _t('confirm');
|
||||
}
|
||||
}
|
||||
|
||||
// Callback to validate the payment
|
||||
$scope.ok = function () {
|
||||
$scope.attempting = true
|
||||
$scope.attempting = true;
|
||||
return Reservation.save(mkRequestParams($scope.reservation, coupon), function (reservation) {
|
||||
$uibModalInstance.close(reservation)
|
||||
return $scope.attempting = true
|
||||
$uibModalInstance.close(reservation);
|
||||
return $scope.attempting = true;
|
||||
}
|
||||
, function (response) {
|
||||
$scope.alerts = []
|
||||
angular.forEach(response, function(v, k) {
|
||||
angular.forEach(v, function(err) {
|
||||
$scope.alerts = [];
|
||||
angular.forEach(response, function (v, k) {
|
||||
angular.forEach(v, function (err) {
|
||||
$scope.alerts.push({
|
||||
msg: k + ': ' + err,
|
||||
type: 'danger'
|
||||
})
|
||||
})
|
||||
})
|
||||
return $scope.attempting = false
|
||||
})
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
return $scope.attempting = false;
|
||||
});
|
||||
};
|
||||
|
||||
// Callback to cancel the payment
|
||||
return $scope.cancel = function() { $uibModalInstance.dismiss('cancel'); }
|
||||
return $scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
|
||||
}
|
||||
] })
|
||||
.result['finally'](null).then(function(reservation) { afterPayment(reservation) })
|
||||
}
|
||||
.result['finally'](null).then(function (reservation) { afterPayment(reservation); });
|
||||
};
|
||||
|
||||
/**
|
||||
* What to do after the payment was successful
|
||||
* @param resveration {Object} booked reservation
|
||||
*/
|
||||
var afterPayment = function (reservation) {
|
||||
$scope.event.nb_free_places = $scope.event.nb_free_places - reservation.total_booked_seats
|
||||
resetEventReserve()
|
||||
$scope.reserveSuccess = true
|
||||
$scope.coupon.applied = null
|
||||
$scope.reservations.push(reservation)
|
||||
$scope.event.nb_free_places = $scope.event.nb_free_places - reservation.total_booked_seats;
|
||||
resetEventReserve();
|
||||
$scope.reserveSuccess = true;
|
||||
$scope.coupon.applied = null;
|
||||
$scope.reservations.push(reservation);
|
||||
if ($scope.currentUser.role === 'admin') {
|
||||
return $scope.ctrl.member = null
|
||||
return $scope.ctrl.member = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// !!! MUST BE CALLED AT THE END of the controller
|
||||
return initialize()
|
||||
return initialize();
|
||||
}
|
||||
])
|
||||
]);
|
||||
|
||||
function __range__ (left, right, inclusive) {
|
||||
let range = []
|
||||
let ascending = left < right
|
||||
let end = !inclusive ? right : ascending ? right + 1 : right - 1
|
||||
let range = [];
|
||||
let ascending = left < right;
|
||||
let end = !inclusive ? right : ascending ? right + 1 : right - 1;
|
||||
for (let i = left; ascending ? i < end : i > end; ascending ? i++ : i--) {
|
||||
range.push(i)
|
||||
range.push(i);
|
||||
}
|
||||
return range
|
||||
return range;
|
||||
}
|
||||
|
@ -17,11 +17,6 @@
|
||||
* inherits $scope.$parent.notifications (global notifications state) from ApplicationController
|
||||
*/
|
||||
Application.Controllers.controller('NotificationsController', ['$scope', 'Notification', function ($scope, Notification) {
|
||||
/* PRIVATE STATIC CONSTANTS */
|
||||
|
||||
// Number of notifications added to the page when the user clicks on 'load next notifications'
|
||||
const NOTIFICATIONS_PER_PAGE = 15;
|
||||
|
||||
/* PUBLIC SCOPE */
|
||||
|
||||
// Array containg the archived notifications (already read)
|
||||
|
@ -32,7 +32,7 @@ angular.module('application.router', ['ui.router'])
|
||||
resolve: {
|
||||
logoFile: ['CustomAsset', function (CustomAsset) { return CustomAsset.get({ name: 'logo-file' }).$promise; }],
|
||||
logoBlackFile: ['CustomAsset', function (CustomAsset) { return CustomAsset.get({ name: 'logo-black-file' }).$promise; }],
|
||||
commonTranslations: [ 'Translations', function (Translations) { return Translations.query(['app.public.common', 'app.shared.buttons', 'app.shared.elements']).$promise; }]
|
||||
commonTranslations: ['Translations', function (Translations) { return Translations.query(['app.public.common', 'app.shared.buttons', 'app.shared.elements']).$promise; }]
|
||||
},
|
||||
onEnter: ['$rootScope', 'logoFile', 'logoBlackFile', function ($rootScope, logoFile, logoBlackFile) {
|
||||
// Application logo
|
||||
@ -78,7 +78,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.public.about').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.public.about').$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.public.home', {
|
||||
@ -95,7 +95,7 @@ angular.module('application.router', ['ui.router'])
|
||||
upcomingEventsPromise: ['Event', function (Event) { return Event.upcoming({ limit: 3 }).$promise; }],
|
||||
homeBlogpostPromise: ['Setting', function (Setting) { return Setting.get({ name: 'home_blogpost' }).$promise; }],
|
||||
twitterNamePromise: ['Setting', function (Setting) { return Setting.get({ name: 'twitter_name' }).$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.public.home').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.public.home').$promise; }]
|
||||
}
|
||||
})
|
||||
|
||||
@ -114,7 +114,7 @@ angular.module('application.router', ['ui.router'])
|
||||
groupsPromise: ['Group', function (Group) { return Group.query().$promise; }],
|
||||
cguFile: ['CustomAsset', function (CustomAsset) { return CustomAsset.get({ name: 'cgu-file' }).$promise; }],
|
||||
memberPromise: ['Member', 'currentUser', function (Member, currentUser) { return Member.get({ id: currentUser.id }).$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.logged.profileCompletion', 'app.shared.user']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.logged.profileCompletion', 'app.shared.user']).$promise; }]
|
||||
}
|
||||
})
|
||||
|
||||
@ -135,7 +135,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.logged.dashboard.profile', 'app.shared.public_profile']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.logged.dashboard.profile', 'app.shared.public_profile']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.logged.dashboard.settings', {
|
||||
@ -149,7 +149,7 @@ angular.module('application.router', ['ui.router'])
|
||||
resolve: {
|
||||
groups: ['Group', function (Group) { return Group.query().$promise; }],
|
||||
activeProviderPromise: ['AuthProvider', function (AuthProvider) { return AuthProvider.active().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.logged.dashboard.settings', 'app.shared.user']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.logged.dashboard.settings', 'app.shared.user']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.logged.dashboard.projects', {
|
||||
@ -161,7 +161,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.logged.dashboard.projects').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.logged.dashboard.projects').$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.logged.dashboard.trainings', {
|
||||
@ -173,7 +173,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.logged.dashboard.trainings').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.logged.dashboard.trainings').$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.logged.dashboard.events', {
|
||||
@ -185,7 +185,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.logged.dashboard.events').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.logged.dashboard.events').$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.logged.dashboard.invoices', {
|
||||
@ -197,7 +197,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.logged.dashboard.invoices').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.logged.dashboard.invoices').$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.logged.dashboard.wallet', {
|
||||
@ -211,7 +211,7 @@ angular.module('application.router', ['ui.router'])
|
||||
resolve: {
|
||||
walletPromise: ['Wallet', 'currentUser', function (Wallet, currentUser) { return Wallet.getWalletByUser({ user_id: currentUser.id }).$promise; }],
|
||||
transactionsPromise: ['Wallet', 'walletPromise', function (Wallet, walletPromise) { return Wallet.transactions({ id: walletPromise.id }).$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.shared.wallet']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.shared.wallet']).$promise; }]
|
||||
}
|
||||
})
|
||||
|
||||
@ -226,7 +226,7 @@ angular.module('application.router', ['ui.router'])
|
||||
},
|
||||
resolve: {
|
||||
memberPromise: ['$stateParams', 'Member', function ($stateParams, Member) { return Member.get({ id: $stateParams.id }).$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.logged.members_show', 'app.shared.public_profile']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.logged.members_show', 'app.shared.public_profile']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.logged.members', {
|
||||
@ -239,7 +239,7 @@ angular.module('application.router', ['ui.router'])
|
||||
},
|
||||
resolve: {
|
||||
membersPromise: ['Member', function (Member) { return Member.query({ requested_attributes: '[profile]', page: 1, size: 10 }).$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.logged.members').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.logged.members').$promise; }]
|
||||
}
|
||||
})
|
||||
|
||||
@ -256,7 +256,7 @@ angular.module('application.router', ['ui.router'])
|
||||
themesPromise: ['Theme', function (Theme) { return Theme.query().$promise; }],
|
||||
componentsPromise: ['Component', function (Component) { return Component.query().$promise; }],
|
||||
machinesPromise: ['Machine', function (Machine) { return Machine.query().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.public.projects_list').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.public.projects_list').$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.logged.projects_new', {
|
||||
@ -269,7 +269,7 @@ angular.module('application.router', ['ui.router'])
|
||||
},
|
||||
resolve: {
|
||||
allowedExtensions: ['Project', function (Project) { return Project.allowedExtensions().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.logged.projects_new', 'app.shared.project']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.logged.projects_new', 'app.shared.project']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.public.projects_show', {
|
||||
@ -282,7 +282,7 @@ angular.module('application.router', ['ui.router'])
|
||||
},
|
||||
resolve: {
|
||||
projectPromise: ['$stateParams', 'Project', function ($stateParams, Project) { return Project.get({ id: $stateParams.id }).$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.public.projects_show').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.public.projects_show').$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.logged.projects_edit', {
|
||||
@ -296,7 +296,7 @@ angular.module('application.router', ['ui.router'])
|
||||
resolve: {
|
||||
projectPromise: ['$stateParams', 'Project', function ($stateParams, Project) { return Project.get({ id: $stateParams.id }).$promise; }],
|
||||
allowedExtensions: ['Project', function (Project) { return Project.allowedExtensions().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.logged.projects_edit', 'app.shared.project']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.logged.projects_edit', 'app.shared.project']).$promise; }]
|
||||
}
|
||||
})
|
||||
|
||||
@ -311,7 +311,7 @@ angular.module('application.router', ['ui.router'])
|
||||
},
|
||||
resolve: {
|
||||
machinesPromise: ['Machine', function (Machine) { return Machine.query().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.public.machines_list', 'app.shared.training_reservation_modal', 'app.shared.request_training_modal']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.public.machines_list', 'app.shared.training_reservation_modal', 'app.shared.request_training_modal']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.admin.machines_new', {
|
||||
@ -323,7 +323,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.admin.machines_new', 'app.shared.machine']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.admin.machines_new', 'app.shared.machine']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.public.machines_show', {
|
||||
@ -336,7 +336,7 @@ angular.module('application.router', ['ui.router'])
|
||||
},
|
||||
resolve: {
|
||||
machinePromise: ['Machine', '$stateParams', function (Machine, $stateParams) { return Machine.get({ id: $stateParams.id }).$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.public.machines_show', 'app.shared.training_reservation_modal', 'app.shared.request_training_modal']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.public.machines_show', 'app.shared.training_reservation_modal', 'app.shared.request_training_modal']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.logged.machines_reserve', {
|
||||
@ -363,7 +363,7 @@ angular.module('application.router', ['ui.router'])
|
||||
'subscription_explications_alert']`
|
||||
}).$promise;
|
||||
}],
|
||||
translations: [ 'Translations', function (Translations) {
|
||||
translations: ['Translations', function (Translations) {
|
||||
return Translations.query(['app.logged.machines_reserve', 'app.shared.plan_subscribe', 'app.shared.member_select',
|
||||
'app.shared.stripe', 'app.shared.valid_reservation_modal', 'app.shared.confirm_modify_slot_modal',
|
||||
'app.shared.wallet', 'app.shared.coupon_input', 'app.shared.cart']).$promise;
|
||||
@ -380,7 +380,7 @@ angular.module('application.router', ['ui.router'])
|
||||
},
|
||||
resolve: {
|
||||
machinePromise: ['Machine', '$stateParams', function (Machine, $stateParams) { return Machine.get({ id: $stateParams.id }).$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.admin.machines_edit', 'app.shared.machine']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.admin.machines_edit', 'app.shared.machine']).$promise; }]
|
||||
}
|
||||
})
|
||||
|
||||
@ -396,7 +396,7 @@ angular.module('application.router', ['ui.router'])
|
||||
},
|
||||
resolve: {
|
||||
spacesPromise: ['Space', function (Space) { return Space.query().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.public.spaces_list']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.public.spaces_list']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.admin.space_new', {
|
||||
@ -409,7 +409,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.admin.space_new', 'app.shared.space']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.admin.space_new', 'app.shared.space']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.public.space_show', {
|
||||
@ -423,7 +423,7 @@ angular.module('application.router', ['ui.router'])
|
||||
},
|
||||
resolve: {
|
||||
spacePromise: ['Space', '$stateParams', function (Space, $stateParams) { return Space.get({ id: $stateParams.id }).$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.public.space_show']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.public.space_show']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.admin.space_edit', {
|
||||
@ -437,7 +437,7 @@ angular.module('application.router', ['ui.router'])
|
||||
},
|
||||
resolve: {
|
||||
spacePromise: ['Space', '$stateParams', function (Space, $stateParams) { return Space.get({ id: $stateParams.id }).$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.admin.space_edit', 'app.shared.space']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.admin.space_edit', 'app.shared.space']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.logged.space_reserve', {
|
||||
@ -465,7 +465,7 @@ angular.module('application.router', ['ui.router'])
|
||||
'subscription_explications_alert', \
|
||||
'space_explications_alert']` }).$promise;
|
||||
}],
|
||||
translations: [ 'Translations', function (Translations) {
|
||||
translations: ['Translations', function (Translations) {
|
||||
return Translations.query(['app.logged.space_reserve', 'app.shared.plan_subscribe', 'app.shared.member_select',
|
||||
'app.shared.stripe', 'app.shared.valid_reservation_modal', 'app.shared.confirm_modify_slot_modal',
|
||||
'app.shared.wallet', 'app.shared.coupon_input', 'app.shared.cart']).$promise;
|
||||
@ -484,7 +484,7 @@ angular.module('application.router', ['ui.router'])
|
||||
},
|
||||
resolve: {
|
||||
trainingsPromise: ['Training', function (Training) { return Training.query({ public_page: true }).$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.public.trainings_list']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.public.trainings_list']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.public.training_show', {
|
||||
@ -497,7 +497,7 @@ angular.module('application.router', ['ui.router'])
|
||||
},
|
||||
resolve: {
|
||||
trainingPromise: ['Training', '$stateParams', function (Training, $stateParams) { return Training.get({ id: $stateParams.id }).$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.public.training_show']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.public.training_show']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.logged.trainings_reserve', {
|
||||
@ -528,7 +528,7 @@ angular.module('application.router', ['ui.router'])
|
||||
'training_explications_alert', \
|
||||
'training_information_message']` }).$promise;
|
||||
}],
|
||||
translations: [ 'Translations', function (Translations) {
|
||||
translations: ['Translations', function (Translations) {
|
||||
return Translations.query(['app.logged.trainings_reserve', 'app.shared.plan_subscribe', 'app.shared.member_select',
|
||||
'app.shared.stripe', 'app.shared.valid_reservation_modal', 'app.shared.confirm_modify_slot_modal',
|
||||
'app.shared.wallet', 'app.shared.coupon_input', 'app.shared.cart']).$promise;
|
||||
@ -545,7 +545,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.logged.notifications').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.logged.notifications').$promise; }]
|
||||
}
|
||||
})
|
||||
|
||||
@ -563,7 +563,7 @@ angular.module('application.router', ['ui.router'])
|
||||
subscriptionExplicationsPromise: ['Setting', function (Setting) { return Setting.get({ name: 'subscription_explications_alert' }).$promise; }],
|
||||
plansPromise: ['Plan', function (Plan) { return Plan.query().$promise; }],
|
||||
groupsPromise: ['Group', function (Group) { return Group.query().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) {
|
||||
translations: ['Translations', function (Translations) {
|
||||
return Translations.query(['app.public.plans', 'app.shared.member_select', 'app.shared.stripe', 'app.shared.wallet',
|
||||
'app.shared.coupon_input']).$promise;
|
||||
}]
|
||||
@ -583,7 +583,7 @@ angular.module('application.router', ['ui.router'])
|
||||
categoriesPromise: ['Category', function (Category) { return Category.query().$promise; }],
|
||||
themesPromise: ['EventTheme', function (EventTheme) { return EventTheme.query().$promise; }],
|
||||
ageRangesPromise: ['AgeRange', function (AgeRange) { return AgeRange.query().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.public.events_list').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.public.events_list').$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.public.events_show', {
|
||||
@ -598,7 +598,7 @@ angular.module('application.router', ['ui.router'])
|
||||
eventPromise: ['Event', '$stateParams', function (Event, $stateParams) { return Event.get({ id: $stateParams.id }).$promise; }],
|
||||
priceCategoriesPromise: ['PriceCategory', function (PriceCategory) { return PriceCategory.query().$promise; }],
|
||||
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['booking_move_enable', 'booking_move_delay', 'event_explications_alert']" }).$promise; }],
|
||||
translations: [ 'Translations', function (Translations) {
|
||||
translations: ['Translations', function (Translations) {
|
||||
return Translations.query(['app.public.events_show', 'app.shared.member_select', 'app.shared.stripe',
|
||||
'app.shared.valid_reservation_modal', 'app.shared.wallet', 'app.shared.coupon_input']).$promise;
|
||||
}]
|
||||
@ -620,7 +620,7 @@ angular.module('application.router', ['ui.router'])
|
||||
trainingsPromise: ['Training', function (Training) { return Training.query().$promise; }],
|
||||
machinesPromise: ['Machine', function (Machine) { return Machine.query().$promise; }],
|
||||
spacesPromise: ['Space', function (Space) { return Space.query().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.public.calendar']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.public.calendar']).$promise; }]
|
||||
}
|
||||
})
|
||||
|
||||
@ -638,7 +638,7 @@ angular.module('application.router', ['ui.router'])
|
||||
bookingWindowStart: ['Setting', function (Setting) { return Setting.get({ name: 'booking_window_start' }).$promise; }],
|
||||
bookingWindowEnd: ['Setting', function (Setting) { return Setting.get({ name: 'booking_window_end' }).$promise; }],
|
||||
machinesPromise: ['Machine', function (Machine) { return Machine.query().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.admin.calendar').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.admin.calendar').$promise; }]
|
||||
}
|
||||
})
|
||||
|
||||
@ -655,7 +655,7 @@ angular.module('application.router', ['ui.router'])
|
||||
componentsPromise: ['Component', function (Component) { return Component.query().$promise; }],
|
||||
licencesPromise: ['Licence', function (Licence) { return Licence.query().$promise; }],
|
||||
themesPromise: ['Theme', function (Theme) { return Theme.query().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.admin.project_elements').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.admin.project_elements').$promise; }]
|
||||
}
|
||||
})
|
||||
|
||||
@ -671,7 +671,7 @@ angular.module('application.router', ['ui.router'])
|
||||
resolve: {
|
||||
trainingsPromise: ['Training', function (Training) { return Training.query().$promise; }],
|
||||
machinesPromise: ['Machine', function (Machine) { return Machine.query().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.admin.trainings', 'app.shared.trainings']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.admin.trainings', 'app.shared.trainings']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.admin.trainings_new', {
|
||||
@ -684,7 +684,7 @@ angular.module('application.router', ['ui.router'])
|
||||
},
|
||||
resolve: {
|
||||
machinesPromise: ['Machine', function (Machine) { return Machine.query().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.admin.trainings_new', 'app.shared.trainings']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.admin.trainings_new', 'app.shared.trainings']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.admin.trainings_edit', {
|
||||
@ -698,7 +698,7 @@ angular.module('application.router', ['ui.router'])
|
||||
resolve: {
|
||||
trainingPromise: ['Training', '$stateParams', function (Training, $stateParams) { return Training.get({ id: $stateParams.id }).$promise; }],
|
||||
machinesPromise: ['Machine', function (Machine) { return Machine.query().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.shared.trainings').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.shared.trainings').$promise; }]
|
||||
}
|
||||
})
|
||||
// events
|
||||
@ -716,7 +716,7 @@ angular.module('application.router', ['ui.router'])
|
||||
themesPromise: ['EventTheme', function (EventTheme) { return EventTheme.query().$promise; }],
|
||||
ageRangesPromise: ['AgeRange', function (AgeRange) { return AgeRange.query().$promise; }],
|
||||
priceCategoriesPromise: ['PriceCategory', function (PriceCategory) { return PriceCategory.query().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.admin.events').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.admin.events').$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.admin.events_new', {
|
||||
@ -732,7 +732,7 @@ angular.module('application.router', ['ui.router'])
|
||||
themesPromise: ['EventTheme', function (EventTheme) { return EventTheme.query().$promise; }],
|
||||
ageRangesPromise: ['AgeRange', function (AgeRange) { return AgeRange.query().$promise; }],
|
||||
priceCategoriesPromise: ['PriceCategory', function (PriceCategory) { return PriceCategory.query().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.admin.events_new', 'app.shared.event']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.admin.events_new', 'app.shared.event']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.admin.events_edit', {
|
||||
@ -749,7 +749,7 @@ angular.module('application.router', ['ui.router'])
|
||||
themesPromise: ['EventTheme', function (EventTheme) { return EventTheme.query().$promise; }],
|
||||
ageRangesPromise: ['AgeRange', function (AgeRange) { return AgeRange.query().$promise; }],
|
||||
priceCategoriesPromise: ['PriceCategory', function (PriceCategory) { return PriceCategory.query().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.admin.events_edit', 'app.shared.event']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.admin.events_edit', 'app.shared.event']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.admin.event_reservations', {
|
||||
@ -763,7 +763,7 @@ angular.module('application.router', ['ui.router'])
|
||||
resolve: {
|
||||
eventPromise: ['Event', '$stateParams', function (Event, $stateParams) { return Event.get({ id: $stateParams.id }).$promise; }],
|
||||
reservationsPromise: ['Reservation', '$stateParams', function (Reservation, $stateParams) { return Reservation.query({ reservable_id: $stateParams.id, reservable_type: 'Event' }).$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.admin.event_reservations').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.admin.event_reservations').$promise; }]
|
||||
}
|
||||
})
|
||||
|
||||
@ -781,7 +781,7 @@ angular.module('application.router', ['ui.router'])
|
||||
groups: ['Group', function (Group) { return Group.query().$promise; }],
|
||||
machinesPricesPromise: ['Price', function (Price) { return Price.query({ priceable_type: 'Machine', plan_id: 'null' }).$promise; }],
|
||||
trainingsPricingsPromise: ['TrainingsPricing', function (TrainingsPricing) { return TrainingsPricing.query().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.admin.pricing', 'app.shared.member_select', 'app.shared.coupon']).$promise; }],
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.admin.pricing', 'app.shared.member_select', 'app.shared.coupon']).$promise; }],
|
||||
trainingsPromise: ['Training', function (Training) { return Training.query().$promise; }],
|
||||
machineCreditsPromise: ['Credit', function (Credit) { return Credit.query({ creditable_type: 'Machine' }).$promise; }],
|
||||
machinesPromise: ['Machine', function (Machine) { return Machine.query().$promise; }],
|
||||
@ -811,7 +811,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.admin.plans.new', 'app.shared.plan']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.admin.plans.new', 'app.shared.plan']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.admin.plans.edit', {
|
||||
@ -827,7 +827,7 @@ angular.module('application.router', ['ui.router'])
|
||||
machines: ['Machine', function (Machine) { return Machine.query().$promise; }],
|
||||
plans: ['Plan', function (Plan) { return Plan.query().$promise; }],
|
||||
planPromise: ['Plan', '$stateParams', function (Plan, $stateParams) { return Plan.get({ id: $stateParams.id }).$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.admin.plans.edit', 'app.shared.plan']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.admin.plans.edit', 'app.shared.plan']).$promise; }]
|
||||
}
|
||||
})
|
||||
|
||||
@ -841,7 +841,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.admin.coupons_new', 'app.shared.coupon']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.admin.coupons_new', 'app.shared.coupon']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.admin.coupons_edit', {
|
||||
@ -854,7 +854,7 @@ angular.module('application.router', ['ui.router'])
|
||||
},
|
||||
resolve: {
|
||||
couponPromise: ['Coupon', '$stateParams', function (Coupon, $stateParams) { return Coupon.get({ id: $stateParams.id }).$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.admin.coupons_edit', 'app.shared.coupon']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.admin.coupons_edit', 'app.shared.coupon']).$promise; }]
|
||||
}
|
||||
})
|
||||
|
||||
@ -885,7 +885,7 @@ angular.module('application.router', ['ui.router'])
|
||||
query: { number: '', customer: '', date: null, order_by: '-reference', page: 1, size: 20 }
|
||||
}).$promise;
|
||||
}],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.admin.invoices').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.admin.invoices').$promise; }]
|
||||
}
|
||||
})
|
||||
|
||||
@ -916,7 +916,7 @@ angular.module('application.router', ['ui.router'])
|
||||
groupsPromise: ['Group', function (Group) { return Group.query().$promise; }],
|
||||
tagsPromise: ['Tag', function (Tag) { return Tag.query().$promise; }],
|
||||
authProvidersPromise: ['AuthProvider', function (AuthProvider) { return AuthProvider.query().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.admin.members').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.admin.members').$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.admin.members_new', {
|
||||
@ -928,7 +928,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.admin.members_new', 'app.shared.user', 'app.shared.user_admin']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.admin.members_new', 'app.shared.user', 'app.shared.user_admin']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.admin.members_edit', {
|
||||
@ -945,7 +945,7 @@ angular.module('application.router', ['ui.router'])
|
||||
walletPromise: ['Wallet', '$stateParams', function (Wallet, $stateParams) { return Wallet.getWalletByUser({ user_id: $stateParams.id }).$promise; }],
|
||||
transactionsPromise: ['Wallet', 'walletPromise', function (Wallet, walletPromise) { return Wallet.transactions({ id: walletPromise.id }).$promise; }],
|
||||
tagsPromise: ['Tag', function (Tag) { return Tag.query().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.admin.members_edit', 'app.shared.user', 'app.shared.user_admin', 'app.shared.wallet']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.admin.members_edit', 'app.shared.user', 'app.shared.user_admin', 'app.shared.wallet']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.admin.admins_new', {
|
||||
@ -957,7 +957,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.admin.admins_new').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.admin.admins_new').$promise; }]
|
||||
}
|
||||
})
|
||||
|
||||
@ -973,7 +973,7 @@ angular.module('application.router', ['ui.router'])
|
||||
resolve: {
|
||||
mappingFieldsPromise: ['AuthProvider', function (AuthProvider) { return AuthProvider.mapping_fields().$promise; }],
|
||||
authProvidersPromise: ['AuthProvider', function (AuthProvider) { return AuthProvider.query().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.admin.authentication_new', 'app.shared.authentication', 'app.shared.oauth2']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.admin.authentication_new', 'app.shared.authentication', 'app.shared.oauth2']).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.admin.authentication_edit', {
|
||||
@ -987,7 +987,7 @@ angular.module('application.router', ['ui.router'])
|
||||
resolve: {
|
||||
providerPromise: ['AuthProvider', '$stateParams', function (AuthProvider, $stateParams) { return AuthProvider.get({ id: $stateParams.id }).$promise; }],
|
||||
mappingFieldsPromise: ['AuthProvider', function (AuthProvider) { return AuthProvider.mapping_fields().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query(['app.admin.authentication_edit', 'app.shared.authentication', 'app.shared.oauth2']).$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query(['app.admin.authentication_edit', 'app.shared.authentication', 'app.shared.oauth2']).$promise; }]
|
||||
}
|
||||
})
|
||||
|
||||
@ -1003,7 +1003,7 @@ angular.module('application.router', ['ui.router'])
|
||||
resolve: {
|
||||
membersPromise: ['Member', function (Member) { return Member.mapping().$promise; }],
|
||||
statisticsPromise: ['Statistics', function (Statistics) { return Statistics.query().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.admin.statistics').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.admin.statistics').$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.admin.stats_graphs', {
|
||||
@ -1015,7 +1015,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.admin.stats_graphs').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.admin.stats_graphs').$promise; }]
|
||||
}
|
||||
})
|
||||
|
||||
@ -1063,7 +1063,7 @@ angular.module('application.router', ['ui.router'])
|
||||
cgvFile: ['CustomAsset', function (CustomAsset) { return CustomAsset.get({ name: 'cgv-file' }).$promise; }],
|
||||
faviconFile: ['CustomAsset', function (CustomAsset) { return CustomAsset.get({ name: 'favicon-file' }).$promise; }],
|
||||
profileImageFile: ['CustomAsset', function (CustomAsset) { return CustomAsset.get({ name: 'profile-image-file' }).$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.admin.settings').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.admin.settings').$promise; }]
|
||||
}
|
||||
})
|
||||
|
||||
@ -1078,7 +1078,7 @@ angular.module('application.router', ['ui.router'])
|
||||
},
|
||||
resolve: {
|
||||
clientsPromise: ['OpenAPIClient', function (OpenAPIClient) { return OpenAPIClient.query().$promise; }],
|
||||
translations: [ 'Translations', function (Translations) { return Translations.query('app.admin.open_api_clients').$promise; }]
|
||||
translations: ['Translations', function (Translations) { return Translations.query('app.admin.open_api_clients').$promise; }]
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -111,6 +111,7 @@ Application.Services.service('Diacritics', [
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-control-regex
|
||||
return str.replace(/[^\u0000-\u007E]/g, function (a) {
|
||||
return diacriticsMap[a] || a;
|
||||
});
|
||||
|
@ -2,9 +2,12 @@ class API::NotificationsController < API::ApiController
|
||||
include NotifyWith::NotificationsApi
|
||||
before_action :authenticate_user!
|
||||
|
||||
# Number of notifications added to the page when the user clicks on 'load next notifications'
|
||||
NOTIFICATIONS_PER_PAGE = 15
|
||||
|
||||
def index
|
||||
loop do
|
||||
@notifications = current_user.notifications.page(params[:page]).per(15).order('created_at DESC')
|
||||
@notifications = current_user.notifications.page(params[:page]).per(NOTIFICATIONS_PER_PAGE).order('created_at DESC')
|
||||
# we delete obsolete notifications on first access
|
||||
break unless delete_obsoletes(@notifications)
|
||||
end
|
||||
@ -38,6 +41,7 @@ class API::NotificationsController < API::ApiController
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def delete_obsoletes(notifications)
|
||||
cleaned = false
|
||||
notifications.each do |n|
|
||||
|
Loading…
x
Reference in New Issue
Block a user