2015-05-05 03:10:25 +02:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The application file bootstraps the angular app by initializing the main module and
|
|
|
|
* creating namespaces and moduled for controllers, filters, services, and directives.
|
|
|
|
*/
|
|
|
|
|
2022-04-01 17:48:32 +02:00
|
|
|
// eslint-disable-next-line no-var -- Application is a global variable.
|
2020-09-16 16:54:56 +02:00
|
|
|
var Application = Application || {};
|
2015-05-05 03:10:25 +02:00
|
|
|
|
2020-10-21 15:07:01 +02:00
|
|
|
Application.Components = angular.module('application.components', []);
|
2015-05-05 03:10:25 +02:00
|
|
|
Application.Services = angular.module('application.services', []);
|
|
|
|
Application.Controllers = angular.module('application.controllers', []);
|
|
|
|
Application.Filters = angular.module('application.filters', []);
|
|
|
|
Application.Directives = angular.module('application.directives', []);
|
|
|
|
|
2018-11-27 13:57:41 +01:00
|
|
|
angular.module('application', ['ngCookies', 'ngResource', 'ngSanitize', 'ui.router', 'ui.bootstrap',
|
2018-11-21 11:32:50 +01:00
|
|
|
'ngUpload', 'duScroll', 'application.filters', 'application.services', 'application.directives',
|
2020-10-21 15:07:01 +02:00
|
|
|
'frapontillo.bootstrap-switch', 'application.controllers', 'application.router', 'application.components',
|
2020-06-15 11:57:13 +02:00
|
|
|
'ui.select', 'ui.calendar', 'angularMoment', 'Devise', 'angular-growl', 'xeditable',
|
2022-03-21 17:59:38 +01:00
|
|
|
'checklist-model', 'unsavedChanges', 'angular-loading-bar', 'ngTouch',
|
2018-11-21 11:32:50 +01:00
|
|
|
'angularUtils.directives.dirDisqus', 'summernote', 'elasticsearch', 'angular-medium-editor', 'naif.base64',
|
2020-01-28 15:55:22 +01:00
|
|
|
'minicolors', 'pascalprecht.translate', 'ngFitText', 'ngAside', 'ngCapsLock', 'vcRecaptcha', 'ui.codemirror',
|
|
|
|
'bm.uiTour'])
|
2022-03-21 13:43:23 +01:00
|
|
|
.config(['$httpProvider', 'AuthProvider', 'growlProvider', 'unsavedWarningsConfigProvider', 'uibDatepickerPopupConfig', '$provide', '$translateProvider', 'TourConfigProvider', '$sceDelegateProvider',
|
|
|
|
function ($httpProvider, AuthProvider, growlProvider, unsavedWarningsConfigProvider, uibDatepickerPopupConfig, $provide, $translateProvider, TourConfigProvider, $sceDelegateProvider) {
|
2019-06-12 16:31:45 +02:00
|
|
|
// Google analytics
|
2019-06-13 11:28:55 +02:00
|
|
|
// first we check the user acceptance
|
|
|
|
const cookiesConsent = document.cookie.replace(/(?:(?:^|.*;\s*)fab-manager-cookies-consent\s*=\s*([^;]*).*$)|^.*$/, '$1');
|
|
|
|
if (cookiesConsent === 'accept') {
|
2022-03-21 17:59:38 +01:00
|
|
|
GTM.enableAnalytics(Fablab.trackingId);
|
2019-06-13 11:28:55 +02:00
|
|
|
} else {
|
|
|
|
// if the cookies were not explicitly accepted, delete them
|
|
|
|
document.cookie = '_ga=; expires=Thu, 01 Jan 1970 00:00:00 GMT';
|
|
|
|
document.cookie = '_gid=; expires=Thu, 01 Jan 1970 00:00:00 GMT';
|
|
|
|
}
|
2016-03-23 18:39:41 +01:00
|
|
|
|
2018-11-21 11:32:50 +01:00
|
|
|
// 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;
|
|
|
|
|
|
|
|
// 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');
|
2019-12-16 10:16:11 +01:00
|
|
|
// Use the MessageFormat interpolation by default (used for pluralization)
|
|
|
|
$translateProvider.useMessageFormatInterpolation();
|
2020-04-07 14:52:13 +02:00
|
|
|
// Set the language of the instance (from ruby configuration)
|
2018-11-21 11:32:50 +01:00
|
|
|
$translateProvider.preferredLanguage(Fablab.locale);
|
2020-01-28 15:55:22 +01:00
|
|
|
// End the tour when the user clicks the forward or back buttons of the browser
|
|
|
|
TourConfigProvider.enableNavigationInterceptors();
|
2022-03-15 17:10:33 +01:00
|
|
|
|
|
|
|
$sceDelegateProvider.resourceUrlWhitelist(['self']);
|
2022-03-21 13:43:23 +01:00
|
|
|
}]).run(['$rootScope', '$transitions', '$log', 'Auth', 'amMoment', '$state', 'editableOptions',
|
|
|
|
function ($rootScope, $transitions, $log, Auth, amMoment, $state, editableOptions) {
|
2016-03-23 18:39:41 +01:00
|
|
|
// Angular-moment (date-time manipulations library)
|
|
|
|
amMoment.changeLocale(Fablab.moment_locale);
|
|
|
|
|
|
|
|
// Angular-xeditable (click-to-edit elements, used in admin backoffice)
|
2015-05-05 03:10:25 +02:00
|
|
|
editableOptions.theme = 'bs3';
|
|
|
|
|
2016-10-07 11:11:58 +02:00
|
|
|
// Alter the UI-Router's $state, registering into some information concerning the previous $state.
|
2016-03-23 18:39:41 +01:00
|
|
|
// This is used to allow the user to navigate to the previous state
|
2022-03-15 17:10:33 +01:00
|
|
|
$transitions.onSuccess({ }, function (trans) {
|
|
|
|
$state.prevState = trans.$from().name;
|
2022-05-23 14:20:08 +02:00
|
|
|
$state.prevParams = Object.fromEntries(
|
|
|
|
Object.keys(trans.$from().params).map(k => {
|
|
|
|
return [k, trans.$from().params[k].value()];
|
|
|
|
})
|
|
|
|
);
|
2022-03-22 14:00:59 +01:00
|
|
|
|
|
|
|
const path = trans.router.stateService.href(trans.$to(), {}, { absolute: true });
|
|
|
|
GTM.trackPage(path, trans.$to().name);
|
2015-05-05 03:10:25 +02:00
|
|
|
});
|
|
|
|
|
2016-03-23 18:39:41 +01:00
|
|
|
// 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
|
2018-11-21 11:32:50 +01:00
|
|
|
$rootScope.backPrevLocation = function (event) {
|
2015-05-05 03:10:25 +02:00
|
|
|
event.preventDefault();
|
|
|
|
event.stopPropagation();
|
2022-03-15 17:10:33 +01:00
|
|
|
if ($state.prevState === '') {
|
2018-11-21 11:32:50 +01:00
|
|
|
$state.prevState = 'app.public.home';
|
2015-05-05 03:10:25 +02:00
|
|
|
}
|
|
|
|
$state.go($state.prevState, $state.prevParams);
|
|
|
|
};
|
|
|
|
|
2016-03-23 18:39:41 +01:00
|
|
|
// Configuration of the summernote editor (used in project edition)
|
2015-05-13 18:30:35 +02:00
|
|
|
$rootScope.summernoteOpts = {
|
2016-03-23 18:39:41 +01:00
|
|
|
lang: Fablab.summernote_locale,
|
2015-05-18 21:48:10 +02:00
|
|
|
height: 200,
|
2015-05-13 18:30:35 +02:00
|
|
|
toolbar: [
|
|
|
|
['style', ['style']],
|
|
|
|
['font', ['bold', 'italic', 'underline', 'clear']],
|
|
|
|
['color', ['color']],
|
|
|
|
['para', ['ul', 'ol', 'paragraph']],
|
|
|
|
['table', ['table']],
|
|
|
|
['insert', ['link', 'picture', 'hr']],
|
|
|
|
['view', ['fullscreen', 'codeview']],
|
|
|
|
['group', ['video']],
|
|
|
|
['help', ['help']]
|
|
|
|
],
|
|
|
|
styleTags: ['p', 'blockquote', 'pre', 'h4', 'h5', 'h6'],
|
|
|
|
maximumImageFileSize: 4096
|
|
|
|
};
|
|
|
|
|
2016-03-23 18:39:41 +01:00
|
|
|
// 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.
|
2022-03-15 17:10:33 +01:00
|
|
|
$transitions.onStart({}, function (trans) {
|
2018-11-21 11:32:50 +01:00
|
|
|
Auth.currentUser().then(function (currentUser) {
|
2022-03-15 17:10:33 +01:00
|
|
|
if (currentUser.need_completion && trans.$to().name !== 'app.logged.profileCompletion') {
|
2016-03-23 18:39:41 +01:00
|
|
|
$state.go('app.logged.profileCompletion');
|
|
|
|
}
|
2018-11-27 16:26:21 +01:00
|
|
|
}).catch(() => {
|
|
|
|
// no one is logged, just ignore
|
2016-03-23 18:39:41 +01:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-06-02 12:49:00 +02:00
|
|
|
/**
|
2019-06-12 16:31:45 +02:00
|
|
|
* This helper method builds and return an array containing every integers between
|
2016-06-02 12:49:00 +02:00
|
|
|
* the provided start and end.
|
|
|
|
* @param start {number}
|
|
|
|
* @param end {number}
|
|
|
|
* @return {Array} [start .. end]
|
|
|
|
*/
|
2018-11-21 11:32:50 +01:00
|
|
|
$rootScope.intArray = function (start, end) {
|
2019-06-12 16:31:45 +02:00
|
|
|
const arr = [];
|
|
|
|
for (let i = start; i < end; i++) { arr.push(i); }
|
2016-06-02 12:49:00 +02:00
|
|
|
return arr;
|
|
|
|
};
|
2018-11-21 11:32:50 +01:00
|
|
|
}]).constant('angularMomentConfig', {
|
2016-03-23 18:39:41 +01:00
|
|
|
timezone: Fablab.timezone
|
2020-09-28 17:33:18 +02:00
|
|
|
}).constant('moment', require('moment-timezone'));
|
2016-07-13 10:19:43 +02:00
|
|
|
|
2018-11-21 11:32:50 +01:00
|
|
|
angular.isUndefinedOrNull = function (val) {
|
|
|
|
return angular.isUndefined(val) || val === null;
|
2016-07-13 10:19:43 +02:00
|
|
|
};
|
2020-09-16 15:38:07 +02:00
|
|
|
|
|
|
|
module.exports = { Application };
|