1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-29 18:52:22 +01:00

added semicolons

This commit is contained in:
Sylvain 2018-11-21 11:08:53 +01:00
parent 8cd533b5a6
commit f528b2021d
96 changed files with 3617 additions and 3614 deletions

View File

@ -1,4 +1,7 @@
{
"extends": "standard"
"extends": "standard",
"rules": {
"semi": ["error", "always"]
}
}

View File

@ -9,21 +9,21 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Controllers.controller('AboutController', ['$scope', 'Setting', 'CustomAsset', function ($scope, Setting, CustomAsset) {
/* PUBLIC SCOPE */
Setting.get({ name: 'about_title' }, data => $scope.aboutTitle = data.setting)
Setting.get({ name: 'about_title' }, data => $scope.aboutTitle = data.setting);
Setting.get({ name: 'about_body' }, data => $scope.aboutBody = data.setting)
Setting.get({ name: 'about_body' }, data => $scope.aboutBody = data.setting);
Setting.get({ name: 'about_contacts' }, data => $scope.aboutContacts = data.setting)
Setting.get({ name: 'about_contacts' }, data => $scope.aboutContacts = data.setting);
// retrieve the CGU
CustomAsset.get({ name: 'cgu-file' }, cgu => $scope.cgu = cgu.custom_asset)
CustomAsset.get({ name: 'cgu-file' }, cgu => $scope.cgu = cgu.custom_asset);
// retrieve the CGV
return CustomAsset.get({ name: 'cgv-file' }, cgv => $scope.cgv = cgv.custom_asset)
return CustomAsset.get({ name: 'cgv-file' }, cgv => $scope.cgv = cgv.custom_asset);
}
])
]);

View File

@ -11,7 +11,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
/* COMMON CODE */
@ -19,7 +19,7 @@
const METHODS = {
'DatabaseProvider': 'local_database',
'OAuth2Provider': 'o_auth2'
}
};
/**
* Iterate through the provided array and return the index of the requested element
@ -28,8 +28,8 @@ const METHODS = {
* @returns {number} index of the requested element, in the provided array
*/
const findIdxById = function (elements, id) {
return (elements.map(function (elem) { return elem.id })).indexOf(id)
}
return (elements.map(function (elem) { return elem.id; })).indexOf(id);
};
/**
* For OAuth2 authentications, mapping the user's ID is mandatory. This function will check that this mapping
@ -40,11 +40,11 @@ const findIdxById = function (elements, id) {
const check_oauth2_id_is_mapped = function (mappings) {
for (let mapping of Array.from(mappings)) {
if ((mapping.local_model === 'user') && (mapping.local_field === 'uid') && !mapping._destroy) {
return true
return true;
}
}
return false
}
return false;
};
/**
* Provides a set of common callback methods and data to the $scope parameter. These methods are used
@ -63,15 +63,15 @@ const check_oauth2_id_is_mapped = function (mappings) {
class AuthenticationController {
constructor ($scope, $state, $uibModal, mappingFieldsPromise) {
// list of supported authentication methods
$scope.authMethods = METHODS
$scope.authMethods = METHODS;
// list of fields that can be mapped through the SSO
$scope.mappingFields = mappingFieldsPromise
$scope.mappingFields = mappingFieldsPromise;
/**
* Changes the admin's view to the members list page
*/
$scope.cancel = function () { $state.go('app.admin.members') }
$scope.cancel = function () { $state.go('app.admin.members'); };
/**
* Open a modal allowing to specify the data mapping for the given field
@ -81,11 +81,11 @@ class AuthenticationController {
templateUrl: '<%= asset_path "admin/authentications/_data_mapping.html" %>',
size: 'md',
resolve: {
field () { return mapping },
field () { return mapping; },
datatype () {
for (let field of Array.from($scope.mappingFields[mapping.local_model])) {
if (field[0] === mapping.local_field) {
return field[1]
return field[1];
}
}
}
@ -93,12 +93,12 @@ class AuthenticationController {
controller: ['$scope', '$uibModalInstance', 'field', 'datatype', function ($scope, $uibModalInstance, field, datatype) {
// parent field
$scope.field = field
$scope.field = field;
// expected data type
$scope.datatype = datatype
$scope.datatype = datatype;
// data transformation rules
$scope.transformation =
{ rules: field.transformation || { type: datatype } }
{ rules: field.transformation || { type: datatype } };
// available transformation formats
$scope.formats = {
date: [
@ -123,25 +123,25 @@ class AuthenticationController {
value: 'timestamp-ms'
}
]
}
};
// Create a new mapping between anything and an expected integer
$scope.addIntegerMapping = function () {
if (!angular.isArray($scope.transformation.rules.mapping)) {
$scope.transformation.rules.mapping = []
$scope.transformation.rules.mapping = [];
}
return $scope.transformation.rules.mapping.push({ from: '', to: 0 })
}
return $scope.transformation.rules.mapping.push({ from: '', to: 0 });
};
// close and save the modifications
$scope.ok = function () { $uibModalInstance.close($scope.transformation.rules) }
$scope.ok = function () { $uibModalInstance.close($scope.transformation.rules); };
// do not save the modifications
return $scope.cancel = function () { $uibModalInstance.dismiss() }
return $scope.cancel = function () { $uibModalInstance.dismiss(); };
}
] })
.result['finally'](null).then(function (transfo_rules) { mapping.transformation = transfo_rules })
}
.result['finally'](null).then(function (transfo_rules) { mapping.transformation = transfo_rules; });
};
}
}
@ -153,7 +153,7 @@ Application.Controllers.controller('AuthentificationController', ['$scope', '$st
/* PUBLIC SCOPE */
// full list of authentication providers
$scope.providers = authProvidersPromise
$scope.providers = authProvidersPromise;
/**
* Translate the classname into an explicit textual message
@ -161,13 +161,13 @@ Application.Controllers.controller('AuthentificationController', ['$scope', '$st
* @returns {string}
*/
$scope.getType = function (type) {
const text = METHODS[type]
const text = METHODS[type];
if (typeof text !== 'undefined') {
return _t(text)
return _t(text);
} else {
return _t('unknown') + type
return _t('unknown') + type;
}
}
};
/**
* Translate the status string into an explicit textual message
@ -176,12 +176,12 @@ Application.Controllers.controller('AuthentificationController', ['$scope', '$st
*/
$scope.getState = function (status) {
switch (status) {
case 'active': return _t('active')
case 'pending': return _t('pending')
case 'previous': return _t('previous_provider')
default: return _t('unknown') + status
case 'active': return _t('active');
case 'pending': return _t('pending');
case 'previous': return _t('previous_provider');
default: return _t('unknown') + status;
}
}
};
/**
* Ask for confirmation then delete the specified provider
@ -196,7 +196,7 @@ Application.Controllers.controller('AuthentificationController', ['$scope', '$st
return {
title: _t('confirmation_required'),
msg: _t('do_you_really_want_to_delete_the_TYPE_authentication_provider_NAME', { TYPE: $scope.getType(provider.providable_type), NAME: provider.name })
}
};
}
}
},
@ -205,31 +205,31 @@ Application.Controllers.controller('AuthentificationController', ['$scope', '$st
AuthProvider.delete(
{ id: provider.id },
function () {
providers.splice(findIdxById(providers, provider.id), 1)
growl.success(_t('authentication_provider_successfully_deleted'))
providers.splice(findIdxById(providers, provider.id), 1);
growl.success(_t('authentication_provider_successfully_deleted'));
},
function () { growl.error(_t('an_error_occurred_unable_to_delete_the_specified_provider')) }
)
function () { growl.error(_t('an_error_occurred_unable_to_delete_the_specified_provider')); }
);
}
)
}
);
};
}
])
]);
/**
* Page to add a new authentication provider
*/
Application.Controllers.controller('NewAuthenticationController', ['$scope', '$state', '$rootScope', '$uibModal', 'dialogs', 'growl', 'mappingFieldsPromise', 'authProvidersPromise', 'AuthProvider', '_t',
function ($scope, $state, $rootScope, $uibModal, dialogs, growl, mappingFieldsPromise, authProvidersPromise, AuthProvider, _t) {
$scope.mode = 'creation'
$scope.mode = 'creation';
// default parameters for the new authentication provider
$scope.provider = {
name: '',
providable_type: '',
providable_attributes: {}
}
};
/**
* Initialize some provider's specific properties when selecting the provider type
@ -238,10 +238,10 @@ Application.Controllers.controller('NewAuthenticationController', ['$scope', '$s
// === OAuth2Provider ===
if ($scope.provider.providable_type === 'OAuth2Provider') {
if (typeof $scope.provider.providable_attributes.o_auth2_mappings_attributes === 'undefined') {
return $scope.provider.providable_attributes['o_auth2_mappings_attributes'] = []
return $scope.provider.providable_attributes['o_auth2_mappings_attributes'] = [];
}
}
}
};
// Add others providers initializers here if needed ...
/**
@ -249,25 +249,25 @@ Application.Controllers.controller('NewAuthenticationController', ['$scope', '$s
*/
$scope.registerProvider = function () {
// === DatabaseProvider ===
let provider
let provider;
if ($scope.provider.providable_type === 'DatabaseProvider') {
// prevent from adding mode than 1
for (provider of Array.from(authProvidersPromise)) {
if (provider.providable_type === 'DatabaseProvider') {
growl.error(_t('a_local_database_provider_already_exists_unable_to_create_another'))
return false
growl.error(_t('a_local_database_provider_already_exists_unable_to_create_another'));
return false;
}
}
return AuthProvider.save({ auth_provider: $scope.provider }, function (provider) {
growl.success(_t('local_provider_successfully_saved'))
return $state.go('app.admin.members')
})
growl.success(_t('local_provider_successfully_saved'));
return $state.go('app.admin.members');
});
// === OAuth2Provider ===
} else if ($scope.provider.providable_type === 'OAuth2Provider') {
// check the ID mapping
if (!check_oauth2_id_is_mapped($scope.provider.providable_attributes.o_auth2_mappings_attributes)) {
growl.error(_t('it_is_required_to_set_the_matching_between_User.uid_and_the_API_to_add_this_provider'))
return false
growl.error(_t('it_is_required_to_set_the_matching_between_User.uid_and_the_API_to_add_this_provider'));
return false;
}
// discourage the use of unsecure SSO
if (!($scope.provider.providable_attributes.base_url.indexOf('https://') > -1)) {
@ -281,30 +281,30 @@ Application.Controllers.controller('NewAuthenticationController', ['$scope', '$s
msg: _t('beware_the_oauth2_authenticatoin_provider_you_are_about_to_add_isnt_using_HTTPS') +
_t('this_is_a_serious_security_issue_on_internet_and_should_never_be_used_except_for_testing_purposes') +
_t('do_you_really_want_to_continue')
}
};
}
}
},
function () { // unsecured http confirmed
AuthProvider.save({ auth_provider: $scope.provider }, function (provider) {
growl.success(_t('unsecured_oauth2_provider_successfully_added'))
return $state.go('app.admin.members')
})
growl.success(_t('unsecured_oauth2_provider_successfully_added'));
return $state.go('app.admin.members');
});
}
)
);
} else {
AuthProvider.save({ auth_provider: $scope.provider }, function (provider) {
growl.success(_t('oauth2_provider_successfully_added'))
return $state.go('app.admin.members')
})
growl.success(_t('oauth2_provider_successfully_added'));
return $state.go('app.admin.members');
});
}
}
}
};
// Using the AuthenticationController
return new AuthenticationController($scope, $state, $uibModal, mappingFieldsPromise)
return new AuthenticationController($scope, $state, $uibModal, mappingFieldsPromise);
}
])
]);
/**
* Page to edit an already added authentication provider
@ -312,9 +312,9 @@ Application.Controllers.controller('NewAuthenticationController', ['$scope', '$s
Application.Controllers.controller('EditAuthenticationController', ['$scope', '$state', '$stateParams', '$rootScope', '$uibModal', 'dialogs', 'growl', 'providerPromise', 'mappingFieldsPromise', 'AuthProvider', '_t',
function ($scope, $state, $stateParams, $rootScope, $uibModal, dialogs, growl, providerPromise, mappingFieldsPromise, AuthProvider, _t) {
// parameters of the currently edited authentication provider
$scope.provider = providerPromise
$scope.provider = providerPromise;
$scope.mode = 'edition'
$scope.mode = 'edition';
/**
* Update the current provider with the new inputs
@ -322,21 +322,21 @@ Application.Controllers.controller('EditAuthenticationController', ['$scope', '$
$scope.updateProvider = function () {
// check the ID mapping
if (!check_oauth2_id_is_mapped($scope.provider.providable_attributes.o_auth2_mappings_attributes)) {
growl.error(_t('it_is_required_to_set_the_matching_between_User.uid_and_the_API_to_add_this_provider'))
return false
growl.error(_t('it_is_required_to_set_the_matching_between_User.uid_and_the_API_to_add_this_provider'));
return false;
}
return AuthProvider.update(
{ id: $scope.provider.id },
{ auth_provider: $scope.provider },
function (provider) {
growl.success(_t('provider_successfully_updated'))
$state.go('app.admin.members')
growl.success(_t('provider_successfully_updated'));
$state.go('app.admin.members');
},
function () { growl.error(_t('an_error_occurred_unable_to_update_the_provider')) }
)
}
function () { growl.error(_t('an_error_occurred_unable_to_update_the_provider')); }
);
};
// Using the AuthenticationController
return new AuthenticationController($scope, $state, $uibModal, mappingFieldsPromise)
return new AuthenticationController($scope, $state, $uibModal, mappingFieldsPromise);
}
])
]);

View File

@ -12,7 +12,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
/**
* Controller used in the calendar management page
@ -23,29 +23,29 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
/* PRIVATE STATIC CONSTANTS */
// The calendar is divided in slots of 30 minutes
let loadingCb
const BASE_SLOT = '00:30:00'
let loadingCb;
const BASE_SLOT = '00:30:00';
// The bookings can be positioned every half hours
const BOOKING_SNAP = '00:30:00'
const BOOKING_SNAP = '00:30:00';
// We do not allow the creation of slots that are not a multiple of 60 minutes
const SLOT_MULTIPLE = 60
const SLOT_MULTIPLE = 60;
/* PUBLIC SCOPE */
// list of the FabLab machines
$scope.machines = machinesPromise
$scope.machines = machinesPromise;
// currently selected availability
$scope.availability = null
$scope.availability = null;
// bind the availabilities slots with full-Calendar events
$scope.eventSources = []
$scope.eventSources = [];
$scope.eventSources.push({
url: '/api/availabilities',
textColor: 'black'
})
});
// fullCalendar (v2) configuration
$scope.calendarConfig = CalendarConfig({
@ -56,18 +56,18 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
minTime: moment.duration(moment(bookingWindowStart.setting.value).format('HH:mm:ss')),
maxTime: moment.duration(moment(bookingWindowEnd.setting.value).format('HH:mm:ss')),
select (start, end, jsEvent, view) {
return calendarSelectCb(start, end, jsEvent, view)
return calendarSelectCb(start, end, jsEvent, view);
},
eventClick (event, jsEvent, view) {
return calendarEventClickCb(event, jsEvent, view)
return calendarEventClickCb(event, jsEvent, view);
},
eventRender (event, element, view) {
return eventRenderCb(event, element)
return eventRenderCb(event, element);
},
loading (isLoading, view) {
return loadingCb(isLoading, view)
return loadingCb(isLoading, view);
}
})
});
/**
* Open a confirmation modal to cancel the booking of a user for the currently selected event.
@ -84,7 +84,7 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
msg: _t('admin_calendar.do_you_really_want_to_cancel_the_USER_s_reservation_the_DATE_at_TIME_concerning_RESERVATION'
, { GENDER: getGender($scope.currentUser), USER: slot.user.name, DATE: moment(slot.start_at).format('L'), TIME: moment(slot.start_at).format('LT'), RESERVATION: slot.reservable.name }
, 'messageformat')
}
};
}
}
},
@ -96,20 +96,20 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
// update the canceled_at attribute
for (let resa of Array.from($scope.reservations)) {
if (resa.slot_id === data.id) {
resa.canceled_at = data.canceled_at
break
resa.canceled_at = data.canceled_at;
break;
}
}
// notify the admin
return growl.success(_t('admin_calendar.reservation_was_successfully_cancelled'))
return growl.success(_t('admin_calendar.reservation_was_successfully_cancelled'));
},
function (data, status) { // failed
growl.error(_t('admin_calendar.reservation_cancellation_failed'))
growl.error(_t('admin_calendar.reservation_cancellation_failed'));
}
)
);
}
)
}
);
};
/**
* Open a confirmation modal to remove a machine for the currently selected availability,
@ -118,7 +118,7 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
*/
$scope.removeMachine = function (machine) {
if ($scope.availability.machine_ids.length === 1) {
return growl.error(_t('admin_calendar.unable_to_remove_the_last_machine_of_the_slot_delete_the_slot_rather'))
return growl.error(_t('admin_calendar.unable_to_remove_the_last_machine_of_the_slot_delete_the_slot_rather'));
} else {
// open a confirmation dialog
return dialogs.confirm({
@ -129,36 +129,36 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
msg: _t('admin_calendar.do_you_really_want_to_remove_MACHINE_from_this_slot', { GENDER: getGender($scope.currentUser), MACHINE: machine.name }, 'messageformat') + ' ' +
_t('admin_calendar.this_will_prevent_any_new_reservation_on_this_slot_but_wont_cancel_those_existing') + ' ' +
_t('admin_calendar.beware_this_cannot_be_reverted')
}
};
}
}
}
, function () {
// the admin has confirmed, remove the machine
const machines = $scope.availability.machine_ids
const machines = $scope.availability.machine_ids;
for (let m_id = 0; m_id < machines.length; m_id++) {
const key = machines[m_id]
const key = machines[m_id];
if (m_id === machine.id) {
machines.splice(key, 1)
machines.splice(key, 1);
}
}
return Availability.update({ id: $scope.availability.id }, { availability: { machines_attributes: [{ id: machine.id, _destroy: true }] } }
, function (data, status) { // success
// update the machine_ids attribute
$scope.availability.machine_ids = data.machine_ids
$scope.availability.title = data.title
uiCalendarConfig.calendars.calendar.fullCalendar('rerenderEvents')
$scope.availability.machine_ids = data.machine_ids;
$scope.availability.title = data.title;
uiCalendarConfig.calendars.calendar.fullCalendar('rerenderEvents');
// notify the admin
return growl.success(_t('admin_calendar.the_machine_was_successfully_removed_from_the_slot'))
return growl.success(_t('admin_calendar.the_machine_was_successfully_removed_from_the_slot'));
}
, function (data, status) { // failed
growl.error(_t('admin_calendar.deletion_failed'))
growl.error(_t('admin_calendar.deletion_failed'));
}
)
})
);
});
}
}
};
/**
* Callback to alert the admin that the export request was acknowledged and is
@ -167,26 +167,26 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
$scope.alertExport = function (type) {
Export.status({ category: 'availabilities', type }).then(function (res) {
if (!res.data.exists) {
return growl.success(_t('admin_calendar.export_is_running_you_ll_be_notified_when_its_ready'))
return growl.success(_t('admin_calendar.export_is_running_you_ll_be_notified_when_its_ready'));
}
})
}
});
};
/**
* Mark the selected slot as unavailable for new reservations or allow reservations again on it
*/
$scope.toggleLockReservations = function () {
// first, define a shortcut to the lock property
const locked = $scope.availability.lock
const locked = $scope.availability.lock;
// then check if we'll allow reservations locking
let prevent = !locked // if currently locked, allow unlock anyway
let prevent = !locked; // if currently locked, allow unlock anyway
if (!locked) {
prevent = false
prevent = false;
angular.forEach($scope.reservations, function (r) {
if (r.canceled_at === null) {
return prevent = true
return prevent = true;
}
}) // if currently unlocked and has any non-cancelled reservation, disallow locking
}); // if currently unlocked and has any non-cancelled reservation, disallow locking
}
if (!prevent) {
// open a confirmation dialog
@ -197,7 +197,7 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
return {
title: _t('admin_calendar.confirmation_required'),
msg: locked ? _t('admin_calendar.do_you_really_want_to_allow_reservations') : _t('admin_calendar.do_you_really_want_to_block_this_slot')
}
};
}
}
},
@ -207,21 +207,21 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
{ id: $scope.availability.id },
{ lock: !locked },
function (data) { // success
$scope.availability = data
growl.success(locked ? _t('admin_calendar.unlocking_success') : _t('admin_calendar.locking_success'))
uiCalendarConfig.calendars.calendar.fullCalendar('refetchEvents')
$scope.availability = data;
growl.success(locked ? _t('admin_calendar.unlocking_success') : _t('admin_calendar.locking_success'));
uiCalendarConfig.calendars.calendar.fullCalendar('refetchEvents');
},
function (error) { // failed
growl.error(locked ? _t('admin_calendar.unlocking_failed') : _t('admin_calendar.locking_failed'))
console.error(error)
growl.error(locked ? _t('admin_calendar.unlocking_failed') : _t('admin_calendar.locking_failed'));
console.error(error);
}
)
);
}
)
);
} else {
return growl.error(_t('admin_calendar.unlockable_because_reservations'))
return growl.error(_t('admin_calendar.unlockable_because_reservations'));
}
}
};
/**
* Confirm and destroy the slot in $scope.availability
@ -235,7 +235,7 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
return {
title: _t('admin_calendar.confirmation_required'),
msg: _t('admin_calendar.do_you_really_want_to_delete_this_slot')
}
};
}
}
},
@ -244,17 +244,17 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
Availability.delete(
{ id: $scope.availability.id },
function () {
uiCalendarConfig.calendars.calendar.fullCalendar('removeEvents', $scope.availability.id)
uiCalendarConfig.calendars.calendar.fullCalendar('removeEvents', $scope.availability.id);
growl.success(_t('admin_calendar.the_slot_START-END_has_been_successfully_deleted', { START: moment(event.start).format('LL LT'), END: moment(event.end).format('LT') }))
$scope.availability = null
growl.success(_t('admin_calendar.the_slot_START-END_has_been_successfully_deleted', { START: moment(event.start).format('LL LT'), END: moment(event.end).format('LT') }));
$scope.availability = null;
},
function () {
growl.error(_t('admin_calendar.unable_to_delete_the_slot_START-END_because_it_s_already_reserved_by_a_member', { START: moment(event.start).format('LL LT'), END: moment(event.end).format('LT') }))
})
growl.error(_t('admin_calendar.unable_to_delete_the_slot_START-END_because_it_s_already_reserved_by_a_member', { START: moment(event.start).format('LL LT'), END: moment(event.end).format('LT') }));
});
}
)
}
);
};
/* PRIVATE SCOPE */
@ -265,31 +265,31 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
*/
var getGender = function (user) {
if (user.profile) {
if (user.profile.gender === 'true') { return 'male' } else { return 'female' }
} else { return 'other' }
}
if (user.profile.gender === 'true') { return 'male'; } else { return 'female'; }
} else { return 'other'; }
};
// Triggered when the admin drag on the agenda to create a new reservable slot.
// @see http://fullcalendar.io/docs/selection/select_callback/
//
var calendarSelectCb = function (start, end, jsEvent, view) {
start = moment.tz(start.toISOString(), Fablab.timezone)
end = moment.tz(end.toISOString(), Fablab.timezone)
start = moment.tz(start.toISOString(), Fablab.timezone);
end = moment.tz(end.toISOString(), Fablab.timezone);
// first we check that the selected slot is an N-hours multiple (ie. not decimal)
if (Number.isInteger(parseInt((end.valueOf() - start.valueOf()) / (SLOT_MULTIPLE * 1000), 10) / SLOT_MULTIPLE)) {
const today = new Date()
const today = new Date();
if (parseInt((start.valueOf() - today) / (60 * 1000), 10) >= 0) {
// then we open a modal window to let the admin specify the slot type
const modalInstance = $uibModal.open({
templateUrl: '<%= asset_path "admin/calendar/eventModal.html" %>',
controller: 'CreateEventModalController',
resolve: {
start () { return start },
end () { return end },
machinesPromise: ['Machine', function (Machine) { return Machine.query().$promise }],
trainingsPromise: ['Training', function (Training) { return Training.query().$promise }],
spacesPromise: ['Space', function (Space) { return Space.query().$promise }]
} })
start () { return start; },
end () { return end; },
machinesPromise: ['Machine', function (Machine) { return Machine.query().$promise; }],
trainingsPromise: ['Training', function (Training) { return Training.query().$promise; }],
spacesPromise: ['Space', function (Space) { return Space.query().$promise; }]
} });
// when the modal is closed, we send the slot to the server for saving
modalInstance.result.then(
function (availability) {
@ -308,31 +308,31 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
machine_ids: availability.machine_ids
},
true
)
);
},
function () { uiCalendarConfig.calendars.calendar.fullCalendar('unselect') }
)
function () { uiCalendarConfig.calendars.calendar.fullCalendar('unselect'); }
);
}
}
return uiCalendarConfig.calendars.calendar.fullCalendar('unselect')
}
return uiCalendarConfig.calendars.calendar.fullCalendar('unselect');
};
/**
* Triggered when the admin clicks on a availability slot in the agenda.
* @see http://fullcalendar.io/docs/mouse/eventClick/
*/
var calendarEventClickCb = function (event, jsEvent, view) {
$scope.availability = event
$scope.availability = event;
// if the user has clicked on the delete event button, delete the event
if ($(jsEvent.target).hasClass('remove-event')) {
return $scope.removeSlot()
return $scope.removeSlot();
// if the user has only clicked on the event, display its reservations
} else {
return Availability.reservations({ id: event.id }, function (reservations) { $scope.reservations = reservations })
return Availability.reservations({ id: event.id }, function (reservations) { $scope.reservations = reservations; });
}
}
};
/**
* Triggered when fullCalendar tries to graphicaly render an event block.
@ -340,16 +340,16 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
* @see http://fullcalendar.io/docs/event_rendering/eventRender/
*/
var eventRenderCb = function (event, element) {
element.find('.fc-content').prepend('<span class="remove-event">x&nbsp;</span>')
element.find('.fc-content').prepend('<span class="remove-event">x&nbsp;</span>');
if (event.tags.length > 0) {
let html = ''
let html = '';
for (let tag of Array.from(event.tags)) {
html += `<span class='label label-success text-white'>${tag.name}</span> `
html += `<span class='label label-success text-white'>${tag.name}</span> `;
}
element.find('.fc-title').append(`<br/>${html}`)
element.find('.fc-title').append(`<br/>${html}`);
}
// force return to prevent coffee-script auto-return to return random value (possiblity falsy)
}
};
/**
* Triggered when resource fetching starts/stops.
@ -358,12 +358,12 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
return loadingCb = function (isLoading, view) {
if (isLoading) {
// we remove existing events when fetching starts to prevent duplicates
return uiCalendarConfig.calendars.calendar.fullCalendar('removeEvents')
return uiCalendarConfig.calendars.calendar.fullCalendar('removeEvents');
}
}
};
}
])
]);
/**
* Controller used in the slot creation modal window
@ -371,34 +371,34 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
Application.Controllers.controller('CreateEventModalController', ['$scope', '$uibModalInstance', 'moment', 'start', 'end', 'machinesPromise', 'Availability', 'trainingsPromise', 'spacesPromise', 'Tag', 'growl', '_t',
function ($scope, $uibModalInstance, moment, start, end, machinesPromise, Availability, trainingsPromise, spacesPromise, Tag, growl, _t) {
// $uibModal parameter
$scope.start = start
$scope.start = start;
// $uibModal parameter
$scope.end = end
$scope.end = end;
// machines list
$scope.machines = machinesPromise.filter(function (m) { return !m.disabled })
$scope.machines = machinesPromise.filter(function (m) { return !m.disabled; });
// trainings list
$scope.trainings = trainingsPromise.filter(function (t) { return !t.disabled })
$scope.trainings = trainingsPromise.filter(function (t) { return !t.disabled; });
// spaces list
$scope.spaces = spacesPromise.filter(function (s) { return !s.disabled })
$scope.spaces = spacesPromise.filter(function (s) { return !s.disabled; });
// machines associated with the created slot
$scope.selectedMachines = []
$scope.selectedMachines = [];
// training associated with the created slot
$scope.selectedTraining = null
$scope.selectedTraining = null;
// space associated with the created slot
$scope.selectedSpace = null
$scope.selectedSpace = null;
// UI step
$scope.step = 1
$scope.step = 1;
// the user is not able to edit the ending time of the availability, unless he set the type to 'training'
$scope.endDateReadOnly = true
$scope.endDateReadOnly = true;
// timepickers configuration
$scope.timepickers = {
@ -410,27 +410,27 @@ Application.Controllers.controller('CreateEventModalController', ['$scope', '$ui
hstep: 1,
mstep: 5
}
}
};
// slot details
$scope.availability = {
start_at: start,
end_at: end,
available_type: 'machines' // default
}
};
/**
* Adds or removes the provided machine from the current slot
* @param machine {Object}
*/
$scope.toggleSelection = function (machine) {
const index = $scope.selectedMachines.indexOf(machine)
const index = $scope.selectedMachines.indexOf(machine);
if (index > -1) {
return $scope.selectedMachines.splice(index, 1)
return $scope.selectedMachines.splice(index, 1);
} else {
return $scope.selectedMachines.push(machine)
return $scope.selectedMachines.push(machine);
}
}
};
/**
* Callback for the modal window validation: save the slot and closes the modal
@ -438,49 +438,49 @@ Application.Controllers.controller('CreateEventModalController', ['$scope', '$ui
$scope.ok = function () {
if ($scope.availability.available_type === 'machines') {
if ($scope.selectedMachines.length > 0) {
$scope.availability.machine_ids = $scope.selectedMachines.map(function (m) { return m.id })
$scope.availability.machine_ids = $scope.selectedMachines.map(function (m) { return m.id; });
} else {
growl.error(_t('admin_calendar.you_should_select_at_least_a_machine'))
return
growl.error(_t('admin_calendar.you_should_select_at_least_a_machine'));
return;
}
} else if ($scope.availability.available_type === 'training') {
$scope.availability.training_ids = [$scope.selectedTraining.id]
$scope.availability.training_ids = [$scope.selectedTraining.id];
} else if ($scope.availability.available_type === 'space') {
$scope.availability.space_ids = [$scope.selectedSpace.id]
$scope.availability.space_ids = [$scope.selectedSpace.id];
}
return Availability.save(
{ availability: $scope.availability }
, function (availability) { $uibModalInstance.close(availability) })
}
, function (availability) { $uibModalInstance.close(availability); });
};
/**
* Move the modal UI to the next step
*/
$scope.next = function () {
if ($scope.step === 1) { $scope.setNbTotalPlaces() }
return $scope.step++
}
if ($scope.step === 1) { $scope.setNbTotalPlaces(); }
return $scope.step++;
};
/**
* Move the modal UI to the next step
*/
$scope.previous = function () { return $scope.step-- }
$scope.previous = function () { return $scope.step--; };
/**
* Callback to cancel the slot creation
*/
$scope.cancel = function () { $uibModalInstance.dismiss('cancel') }
$scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
/**
* For training avaiabilities, set the maximum number of people allowed to register on this slot
*/
$scope.setNbTotalPlaces = function () {
if ($scope.availability.available_type === 'training') {
return $scope.availability.nb_total_places = $scope.selectedTraining.nb_total_places
return $scope.availability.nb_total_places = $scope.selectedTraining.nb_total_places;
} else if ($scope.availability.available_type === 'space') {
return $scope.availability.nb_total_places = $scope.selectedSpace.default_places
return $scope.availability.nb_total_places = $scope.selectedSpace.default_places;
}
}
};
/* PRIVATE SCOPE */
@ -489,58 +489,58 @@ Application.Controllers.controller('CreateEventModalController', ['$scope', '$ui
*/
const initialize = function () {
if ($scope.trainings.length > 0) {
$scope.selectedTraining = $scope.trainings[0]
$scope.selectedTraining = $scope.trainings[0];
}
if ($scope.spaces.length > 0) {
$scope.selectedSpace = $scope.spaces[0]
$scope.selectedSpace = $scope.spaces[0];
}
Tag.query().$promise.then(function (data) { $scope.tags = data })
Tag.query().$promise.then(function (data) { $scope.tags = data; });
// When we configure a machine availability, do not let the user change the end time, as the total
// time must be dividable by 60 minutes (base slot duration). For training availabilities, the user
// can configure any duration as it does not matters.
$scope.$watch('availability.available_type', function (newValue, oldValue, scope) {
if ((newValue === 'machines') || (newValue === 'space')) {
$scope.endDateReadOnly = true
const diff = moment($scope.end).diff($scope.start, 'hours') // the result is rounded down by moment.js
$scope.end = moment($scope.start).add(diff, 'hours').toDate()
return $scope.availability.end_at = $scope.end
$scope.endDateReadOnly = true;
const diff = moment($scope.end).diff($scope.start, 'hours'); // the result is rounded down by moment.js
$scope.end = moment($scope.start).add(diff, 'hours').toDate();
return $scope.availability.end_at = $scope.end;
} else {
return $scope.endDateReadOnly = false
return $scope.endDateReadOnly = false;
}
})
});
// When the start date is changed, if we are configuring a machine availability,
// maintain the relative length of the slot (ie. change the end time accordingly)
$scope.$watch('start', function (newValue, oldValue, scope) {
// for machine or space availabilities, adjust the end time
if (($scope.availability.available_type === 'machines') || ($scope.availability.available_type === 'space')) {
end = moment($scope.end)
end.add(moment(newValue).diff(oldValue), 'milliseconds')
$scope.end = end.toDate()
end = moment($scope.end);
end.add(moment(newValue).diff(oldValue), 'milliseconds');
$scope.end = end.toDate();
} else { // for training availabilities
// prevent the admin from setting the begining after the and
if (moment(newValue).add(1, 'hour').isAfter($scope.end)) {
$scope.start = oldValue
$scope.start = oldValue;
}
}
// update availability object
return $scope.availability.start_at = $scope.start
})
return $scope.availability.start_at = $scope.start;
});
// Maintain consistency between the end time and the date object in the availability object
return $scope.$watch('end', function (newValue, oldValue, scope) {
// we prevent the admin from setting the end of the availability before its begining
if (moment($scope.start).add(1, 'hour').isAfter(newValue)) {
$scope.end = oldValue
$scope.end = oldValue;
}
// update availability object
return $scope.availability.end_at = $scope.end
})
}
return $scope.availability.end_at = $scope.end;
});
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);

View File

@ -13,7 +13,7 @@
// The validity per user defines how many time a user may ba able to use the same coupon
// Here are the various options for this parameter
const userValidities = ['once', 'forever']
const userValidities = ['once', 'forever'];
/**
* Controller used in the coupon creation page
@ -24,10 +24,10 @@ Application.Controllers.controller('NewCouponController', ['$scope', '$state', '
$scope.coupon = {
active: true,
type: 'percent_off'
}
};
// Options for the validity per user
$scope.validities = userValidities
$scope.validities = userValidities;
// Default parameters for AngularUI-Bootstrap datepicker (used for coupon validity limit selection)
$scope.datePicker = {
@ -37,17 +37,17 @@ Application.Controllers.controller('NewCouponController', ['$scope', '$state', '
options: {
startingDay: Fablab.weekStartingDay
}
}
};
/**
* Shows/hides the validity limit datepicker
* @param $event {Object} jQuery event object
*/
$scope.toggleDatePicker = function ($event) {
$event.preventDefault()
$event.stopPropagation()
return $scope.datePicker.opened = !$scope.datePicker.opened
}
$event.preventDefault();
$event.stopPropagation();
return $scope.datePicker.opened = !$scope.datePicker.opened;
};
/**
* Callback to save the new coupon in $scope.coupon and redirect the user to the listing page
@ -55,11 +55,11 @@ Application.Controllers.controller('NewCouponController', ['$scope', '$state', '
return $scope.saveCoupon = () =>
Coupon.save({ coupon: $scope.coupon }, coupon => $state.go('app.admin.pricing')
, function (err) {
growl.error(_t('unable_to_create_the_coupon_check_code_already_used'))
return console.error(err)
})
growl.error(_t('unable_to_create_the_coupon_check_code_already_used'));
return console.error(err);
});
}
])
]);
/**
* Controller used in the coupon edition page
@ -69,16 +69,16 @@ Application.Controllers.controller('EditCouponController', ['$scope', '$state',
/* PUBLIC SCOPE */
// Used in the form to freeze unmodifiable fields
$scope.mode = 'EDIT'
$scope.mode = 'EDIT';
// Coupon to edit
$scope.coupon = couponPromise
$scope.coupon = couponPromise;
// Options for the validity per user
$scope.validities = userValidities
$scope.validities = userValidities;
// Mapping for validation errors
$scope.errors = {}
$scope.errors = {};
// Default parameters for AngularUI-Bootstrap datepicker (used for coupon validity limit selection)
$scope.datePicker = {
@ -88,29 +88,29 @@ Application.Controllers.controller('EditCouponController', ['$scope', '$state',
options: {
startingDay: Fablab.weekStartingDay
}
}
};
/**
* Shows/hides the validity limit datepicker
* @param $event {Object} jQuery event object
*/
$scope.toggleDatePicker = function ($event) {
$event.preventDefault()
$event.stopPropagation()
return $scope.datePicker.opened = !$scope.datePicker.opened
}
$event.preventDefault();
$event.stopPropagation();
return $scope.datePicker.opened = !$scope.datePicker.opened;
};
/**
* Callback to save the coupon's changes to the API
*/
$scope.updateCoupon = function () {
$scope.errors = {}
$scope.errors = {};
return Coupon.update({ id: $scope.coupon.id }, { coupon: $scope.coupon }, coupon => $state.go('app.admin.pricing')
, function (err) {
growl.error(_t('unable_to_update_the_coupon_an_error_occurred'))
return $scope.errors = err.data
})
}
growl.error(_t('unable_to_update_the_coupon_an_error_occurred'));
return $scope.errors = err.data;
});
};
/* PRIVATE SCOPE */
@ -120,11 +120,11 @@ Application.Controllers.controller('EditCouponController', ['$scope', '$state',
const initialize = function () {
// parse the date if any
if (couponPromise.valid_until) {
return $scope.coupon.valid_until = moment(couponPromise.valid_until).toDate()
return $scope.coupon.valid_until = moment(couponPromise.valid_until).toDate();
}
}
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);

View File

@ -11,7 +11,7 @@
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
/* COMMON CODE */
@ -47,7 +47,7 @@ class EventsController {
options: {
startingDay: Fablab.weekStartingDay
}
}
};
/**
* For use with ngUpload (https://github.com/twilson63/ngUpload).
@ -57,19 +57,19 @@ class EventsController {
*/
$scope.submited = function (content) {
if ((content.id == null)) {
$scope.alerts = []
$scope.alerts = [];
angular.forEach(content, function (v, k) {
angular.forEach(v, function (err) { $scope.alerts.push({ msg: k + ': ' + err, type: 'danger' }) })
})
angular.forEach(v, function (err) { $scope.alerts.push({ msg: k + ': ' + err, type: 'danger' }); });
});
} else {
$state.go('app.public.events_list')
$state.go('app.public.events_list');
}
}
};
/**
* Changes the user's view to the events list page
*/
$scope.cancel = function () { $state.go('app.public.events_list') }
$scope.cancel = function () { $state.go('app.public.events_list'); };
/**
* For use with 'ng-class', returns the CSS class name for the uploads previews.
@ -78,16 +78,16 @@ class EventsController {
*/
$scope.fileinputClass = function (v) {
if (v) {
return 'fileinput-exists'
return 'fileinput-exists';
} else {
return 'fileinput-new'
return 'fileinput-new';
}
}
};
/**
* This will create a single new empty entry into the event's attachements list.
*/
$scope.addFile = function () { $scope.event.event_files_attributes.push({}) }
$scope.addFile = function () { $scope.event.event_files_attributes.push({}); };
/**
* This will remove the given file from the event's attachements list. If the file was previously uploaded
@ -96,40 +96,40 @@ class EventsController {
* @param file {Object} the file to delete
*/
$scope.deleteFile = function (file) {
const index = $scope.event.event_files_attributes.indexOf(file)
const index = $scope.event.event_files_attributes.indexOf(file);
if (file.id != null) {
return file._destroy = true
return file._destroy = true;
} else {
return $scope.event.event_files_attributes.splice(index, 1)
return $scope.event.event_files_attributes.splice(index, 1);
}
}
};
/**
* Show/Hide the "start" datepicker (open the drop down/close it)
*/
$scope.toggleStartDatePicker = function ($event) {
$event.preventDefault()
$event.stopPropagation()
return $scope.datePicker.startOpened = !$scope.datePicker.startOpened
}
$event.preventDefault();
$event.stopPropagation();
return $scope.datePicker.startOpened = !$scope.datePicker.startOpened;
};
/**
* Show/Hide the "end" datepicker (open the drop down/close it)
*/
$scope.toggleEndDatePicker = function ($event) {
$event.preventDefault()
$event.stopPropagation()
return $scope.datePicker.endOpened = !$scope.datePicker.endOpened
}
$event.preventDefault();
$event.stopPropagation();
return $scope.datePicker.endOpened = !$scope.datePicker.endOpened;
};
/**
* Masks/displays the recurrence pane allowing the admin to set the current event as recursive
*/
$scope.toggleRecurrenceEnd = function (e) {
e.preventDefault()
e.stopPropagation()
return $scope.datePicker.recurrenceEndOpened = !$scope.datePicker.recurrenceEndOpened
}
e.preventDefault();
e.stopPropagation();
return $scope.datePicker.recurrenceEndOpened = !$scope.datePicker.recurrenceEndOpened;
};
/**
* Initialize a new price item in the additional prices list
@ -138,22 +138,22 @@ class EventsController {
$scope.event.prices.push({
category: null,
amount: null
})
}
});
};
/**
* Remove the price or mark it as 'to delete'
*/
$scope.removePrice = function (price, event) {
event.preventDefault()
event.stopPropagation()
event.preventDefault();
event.stopPropagation();
if (price.id) {
price._destroy = true
price._destroy = true;
} else {
const index = $scope.event.prices.indexOf(price)
$scope.event.prices.splice(index, 1)
const index = $scope.event.prices.indexOf(price);
$scope.event.prices.splice(index, 1);
}
}
};
}
}
@ -165,47 +165,47 @@ Application.Controllers.controller('AdminEventsController', ['$scope', '$state',
/* PUBLIC SCOPE */
// By default, the pagination mode is activated to limit the page size
$scope.paginateActive = true
$scope.paginateActive = true;
// The events displayed on the page
$scope.events = eventsPromise
$scope.events = eventsPromise;
// Current virtual page
$scope.page = 1
$scope.page = 1;
// Temporary datastore for creating new elements
$scope.inserted = {
category: null,
theme: null,
age_range: null
}
};
// 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;
// List of price categories for the events
$scope.priceCategories = priceCategoriesPromise
$scope.priceCategories = priceCategoriesPromise;
// Default: we display all events (no restriction)
$scope.eventsScope =
{ selected: '' }
{ selected: '' };
/**
* Adds a bucket of events to the bottom of the page, grouped by month
*/
$scope.loadMoreEvents = function () {
$scope.page += 1
$scope.page += 1;
return Event.query({ page: $scope.page, scope: $scope.eventsScope.selected }, function (data) {
$scope.events = $scope.events.concat(data)
return paginationCheck(data, $scope.events)
})
}
$scope.events = $scope.events.concat(data);
return paginationCheck(data, $scope.events);
});
};
/**
* Saves a new element / Update an existing one to the server (form validation callback)
@ -215,11 +215,11 @@ Application.Controllers.controller('AdminEventsController', ['$scope', '$state',
*/
$scope.saveElement = function (model, data, id) {
if (id != null) {
return getModel(model)[0].update({ id }, data)
return getModel(model)[0].update({ id }, data);
} else {
return getModel(model)[0].save(data, function (resp) { getModel(model)[1][getModel(model)[1].length - 1].id = resp.id })
return getModel(model)[0].save(data, function (resp) { getModel(model)[1][getModel(model)[1].length - 1].id = resp.id; });
}
}
};
/**
* Deletes the element at the specified index
@ -228,12 +228,12 @@ Application.Controllers.controller('AdminEventsController', ['$scope', '$state',
*/
$scope.removeElement = function (model, index) {
if ((model === 'category') && (getModel(model)[1].length === 1)) {
growl.error(_t('at_least_one_category_is_required') + ' ' + _t('unable_to_delete_the_last_one'))
return false
growl.error(_t('at_least_one_category_is_required') + ' ' + _t('unable_to_delete_the_last_one'));
return false;
}
if (getModel(model)[1][index].related_to > 0) {
growl.error(_t('unable_to_delete_ELEMENT_already_in_use_NUMBER_times', { ELEMENT: model, NUMBER: getModel(model)[1][index].related_to }, 'messageformat'))
return false
growl.error(_t('unable_to_delete_ELEMENT_already_in_use_NUMBER_times', { ELEMENT: model, NUMBER: getModel(model)[1][index].related_to }, 'messageformat'));
return false;
}
return dialogs.confirm({
resolve: {
@ -241,15 +241,15 @@ Application.Controllers.controller('AdminEventsController', ['$scope', '$state',
return {
title: _t('confirmation_required'),
msg: _t('do_you_really_want_to_delete_this_ELEMENT', { ELEMENT: model }, 'messageformat')
}
};
}
}
}
, function () { // delete confirmed
getModel(model)[0].delete(getModel(model)[1][index], null, function () { getModel(model)[1].splice(index, 1) }
, function () { growl.error(_t('unable_to_delete_an_error_occured')) })
})
}
getModel(model)[0].delete(getModel(model)[1][index], null, function () { getModel(model)[1].splice(index, 1); }
, function () { growl.error(_t('unable_to_delete_an_error_occured')); });
});
};
/**
* Creates a new empty entry in the $scope[model] array
@ -259,9 +259,9 @@ Application.Controllers.controller('AdminEventsController', ['$scope', '$state',
$scope.inserted[model] = {
name: '',
related_to: 0
}
return getModel(model)[1].push($scope.inserted[model])
}
};
return getModel(model)[1].push($scope.inserted[model]);
};
/**
* Removes the newly inserted but not saved element / Cancel the current element modification
@ -271,11 +271,11 @@ Application.Controllers.controller('AdminEventsController', ['$scope', '$state',
*/
$scope.cancelElement = function (model, rowform, index) {
if (getModel(model)[1][index].id != null) {
return rowform.$cancel()
return rowform.$cancel();
} else {
return getModel(model)[1].splice(index, 1)
return getModel(model)[1].splice(index, 1);
}
}
};
/**
* Open a modal dialog allowing the definition of a new price category.
@ -286,20 +286,20 @@ Application.Controllers.controller('AdminEventsController', ['$scope', '$state',
templateUrl: '<%= asset_path "admin/events/price_form.html" %>',
size: 'md',
resolve: {
category () { return {} }
category () { return {}; }
},
controller: 'PriceCategoryController' }).result['finally'](null).then(function (p_cat) {
// save the price category to the API
PriceCategory.save(p_cat, function (cat) {
$scope.priceCategories.push(cat)
return growl.success(_t('price_category_successfully_created'))
$scope.priceCategories.push(cat);
return growl.success(_t('price_category_successfully_created'));
}
, function (err) {
growl.error(_t('unable_to_add_the_price_category_check_name_already_used'))
return console.error(err)
})
})
}
growl.error(_t('unable_to_add_the_price_category_check_name_already_used'));
return console.error(err);
});
});
};
/**
* Update the given price category with the new properties
* to specify in a modal dialog
@ -308,27 +308,27 @@ Application.Controllers.controller('AdminEventsController', ['$scope', '$state',
*/
$scope.editPriceCategory = function (id, index) {
if ($scope.priceCategories[index].id !== id) {
return growl.error(_t('unexpected_error_occurred_please_refresh'))
return growl.error(_t('unexpected_error_occurred_please_refresh'));
} else {
return $uibModal.open({
templateUrl: '<%= asset_path "admin/events/price_form.html" %>',
size: 'md',
resolve: {
category () { return $scope.priceCategories[index] }
category () { return $scope.priceCategories[index]; }
},
controller: 'PriceCategoryController' }).result['finally'](null).then(function (p_cat) {
// update the price category to the API
PriceCategory.update({ id }, { price_category: p_cat }, function (cat) {
$scope.priceCategories[index] = cat
return growl.success(_t('price_category_successfully_updated'))
$scope.priceCategories[index] = cat;
return growl.success(_t('price_category_successfully_updated'));
}
, function (err) {
growl.error(_t('unable_to_update_the_price_category'))
return console.error(err)
})
})
growl.error(_t('unable_to_update_the_price_category'));
return console.error(err);
});
});
}
}
};
/**
* Delete the given price category from the API
@ -337,9 +337,9 @@ Application.Controllers.controller('AdminEventsController', ['$scope', '$state',
*/
$scope.removePriceCategory = function (id, index) {
if ($scope.priceCategories[index].id !== id) {
return growl.error(_t('unexpected_error_occurred_please_refresh'))
return growl.error(_t('unexpected_error_occurred_please_refresh'));
} else if ($scope.priceCategories[index].events > 0) {
return growl.error(_t('unable_to_delete_this_price_category_because_it_is_already_used'))
return growl.error(_t('unable_to_delete_this_price_category_because_it_is_already_used'));
} else {
return dialogs.confirm(
{
@ -348,7 +348,7 @@ Application.Controllers.controller('AdminEventsController', ['$scope', '$state',
return {
title: _t('confirmation_required'),
msg: _t('do_you_really_want_to_delete_this_price_category')
}
};
}
}
},
@ -356,15 +356,15 @@ Application.Controllers.controller('AdminEventsController', ['$scope', '$state',
PriceCategory.remove(
{ id },
function () { // successfully deleted
growl.success(_t('price_category_successfully_deleted'))
$scope.priceCategories.splice(index, 1)
growl.success(_t('price_category_successfully_deleted'));
$scope.priceCategories.splice(index, 1);
},
function () { growl.error(_t('price_category_deletion_failed')) }
)
function () { growl.error(_t('price_category_deletion_failed')); }
);
}
)
);
}
}
};
/**
* Triggered when the admin changes the events filter (all, passed, future).
@ -372,18 +372,18 @@ Application.Controllers.controller('AdminEventsController', ['$scope', '$state',
*/
$scope.changeScope = function () {
Event.query({ page: 1, scope: $scope.eventsScope.selected }, function (data) {
$scope.events = data
return paginationCheck(data, $scope.events)
})
return $scope.page = 1
}
$scope.events = data;
return paginationCheck(data, $scope.events);
});
return $scope.page = 1;
};
/* PRIVATE SCOPE */
/**
* Kind of constructor: these actions will be realized first when the controller is loaded
*/
const initialize = function () { paginationCheck(eventsPromise, $scope.events) }
const initialize = function () { paginationCheck(eventsPromise, $scope.events); };
/**
* Check if all events are already displayed OR if the button 'load more events'
@ -394,14 +394,14 @@ Application.Controllers.controller('AdminEventsController', ['$scope', '$state',
var paginationCheck = function (lastEvents, events) {
if (lastEvents.length > 0) {
if (events.length >= lastEvents[0].nb_total_events) {
return $scope.paginateActive = false
return $scope.paginateActive = false;
} else {
return $scope.paginateActive = true
return $scope.paginateActive = true;
}
} else {
return $scope.paginateActive = false
return $scope.paginateActive = false;
}
}
};
/**
* Return the model and the datastore matching the given name
@ -410,54 +410,54 @@ Application.Controllers.controller('AdminEventsController', ['$scope', '$state',
*/
var getModel = function (name) {
switch (name) {
case 'category': return [Category, $scope.categories]
case 'theme': return [EventTheme, $scope.themes]
case 'age_range': return [AgeRange, $scope.ageRanges]
default: return [null, []]
case 'category': return [Category, $scope.categories];
case 'theme': return [EventTheme, $scope.themes];
case 'age_range': return [AgeRange, $scope.ageRanges];
default: return [null, []];
}
}
};
// init the controller (call at the end !)
return initialize()
return initialize();
}
])
]);
/**
* Controller used in the reservations listing page for a specific event
*/
Application.Controllers.controller('ShowEventReservationsController', ['$scope', 'eventPromise', 'reservationsPromise', function ($scope, eventPromise, reservationsPromise) {
// retrieve the event from the ID provided in the current URL
$scope.event = eventPromise
$scope.event = eventPromise;
// list of reservations for the current event
return $scope.reservations = reservationsPromise
}])
return $scope.reservations = reservationsPromise;
}]);
/**
* Controller used in the event creation page
*/
Application.Controllers.controller('NewEventController', ['$scope', '$state', 'CSRF', 'categoriesPromise', 'themesPromise', 'ageRangesPromise', 'priceCategoriesPromise', '_t',
function ($scope, $state, CSRF, categoriesPromise, themesPromise, ageRangesPromise, priceCategoriesPromise, _t) {
CSRF.setMetaTags()
CSRF.setMetaTags();
// API URL where the form will be posted
$scope.actionUrl = '/api/events/'
$scope.actionUrl = '/api/events/';
// Form action on the above URL
$scope.method = 'post'
$scope.method = 'post';
// 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;
// List of availables price's categories
$scope.priceCategories = priceCategoriesPromise
$scope.priceCategories = priceCategoriesPromise;
// Default event parameters
$scope.event = {
@ -470,7 +470,7 @@ Application.Controllers.controller('NewEventController', ['$scope', '$state', 'C
recurrence: 'none',
category_id: null,
prices: []
}
};
// Possible types of recurrences for an event
$scope.recurrenceTypes = [
@ -479,12 +479,12 @@ Application.Controllers.controller('NewEventController', ['$scope', '$state', 'C
{ label: _t('every_week'), value: 'week' },
{ label: _t('every_month'), value: 'month' },
{ label: _t('every_year'), value: 'year' }
]
];
// Using the EventsController
return new EventsController($scope, $state)
return new EventsController($scope, $state);
}
])
]);
/**
* Controller used in the events edition page
@ -494,25 +494,25 @@ Application.Controllers.controller('EditEventController', ['$scope', '$state', '
/* PUBLIC SCOPE */
// API URL where the form will be posted
$scope.actionUrl = `/api/events/${$stateParams.id}`
$scope.actionUrl = `/api/events/${$stateParams.id}`;
// Form action on the above URL
$scope.method = 'put'
$scope.method = 'put';
// Retrieve the event details, in case of error the user is redirected to the events listing
$scope.event = eventPromise
$scope.event = eventPromise;
// List of categories for the events
$scope.categories = categoriesPromise
$scope.categories = categoriesPromise;
// List of availables price's categories
$scope.priceCategories = priceCategoriesPromise
$scope.priceCategories = priceCategoriesPromise;
// List of events themes
$scope.themes = themesPromise
$scope.themes = themesPromise;
// List of age ranges
$scope.ageRanges = ageRangesPromise
$scope.ageRanges = ageRangesPromise;
/* PRIVATE SCOPE */
@ -520,17 +520,17 @@ Application.Controllers.controller('EditEventController', ['$scope', '$state', '
* Kind of constructor: these actions will be realized first when the controller is loaded
*/
const initialize = function () {
CSRF.setMetaTags()
CSRF.setMetaTags();
// init the dates to JS objects
$scope.event.start_date = moment($scope.event.start_date).toDate()
$scope.event.end_date = moment($scope.event.end_date).toDate()
$scope.event.start_date = moment($scope.event.start_date).toDate();
$scope.event.end_date = moment($scope.event.end_date).toDate();
// Using the EventsController
return new EventsController($scope, $state)
}
return new EventsController($scope, $state);
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);

View File

@ -15,51 +15,51 @@
* DS205: Consider reworking code to avoid use of IIFEs
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Controllers.controller('GraphsController', ['$scope', '$state', '$rootScope', 'es', 'Statistics', '_t',
function ($scope, $state, $rootScope, es, Statistics, _t) {
/* PRIVATE STATIC CONSTANTS */
// height of the HTML/SVG charts elements in pixels
const CHART_HEIGHT = 500
const CHART_HEIGHT = 500;
// Label of the charts' horizontal axes
const X_AXIS_LABEL = _t('date')
const X_AXIS_LABEL = _t('date');
// Label of the charts' vertical axes
const Y_AXIS_LABEL = _t('number')
const Y_AXIS_LABEL = _t('number');
// Colors for the line charts. Each new line uses the next color in this array
const CHART_COLORS = ['#b35a94', '#1c5794', '#00b49e', '#6fac48', '#ebcf4a', '#fd7e33', '#ca3436', '#a26e3a']
const CHART_COLORS = ['#b35a94', '#1c5794', '#00b49e', '#6fac48', '#ebcf4a', '#fd7e33', '#ca3436', '#a26e3a'];
/* PUBLIC SCOPE */
// ui-view transitions optimization: if true, the charts will never be refreshed
$scope.preventRefresh = false
$scope.preventRefresh = false;
// statistics structure in elasticSearch
$scope.statistics = []
$scope.statistics = [];
// statistics data recovered from elasticSearch
$scope.data = null
$scope.data = null;
// default interval: one day
$scope.display =
{ interval: 'week' }
{ interval: 'week' };
// active tab will be set here
$scope.selectedIndex = null
$scope.selectedIndex = null;
// for palmares graphs, filters values are stored here
$scope.ranking = {
sortCriterion: 'ca',
groupCriterion: 'subType'
}
};
// default: we do not open the datepicker menu
$scope.datePicker =
{ show: false }
{ show: false };
// datePicker parameters for interval beginning
$scope.datePickerStart = {
@ -71,7 +71,7 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
options: {
startingDay: Fablab.weekStartingDay
}
}
};
// datePicker parameters for interval ending
$scope.datePickerEnd = {
@ -83,19 +83,19 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
options: {
startingDay: Fablab.weekStartingDay
}
}
};
/**
* Callback to open the datepicker (interval start)
* @param {Object} jQuery event object
*/
$scope.toggleStartDatePicker = $event => toggleDatePicker($event, $scope.datePickerStart)
$scope.toggleStartDatePicker = $event => toggleDatePicker($event, $scope.datePickerStart);
/**
* Callback to open the datepicker (interval end)
* @param {Object} jQuery event object
*/
$scope.toggleEndDatePicker = $event => toggleDatePicker($event, $scope.datePickerEnd)
$scope.toggleEndDatePicker = $event => toggleDatePicker($event, $scope.datePickerEnd);
/**
* Callback called when the active tab is changed.
@ -103,23 +103,23 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
* @param tab {Object} elasticsearch statistic structure
*/
$scope.setActiveTab = function (tab) {
$scope.selectedIndex = tab
$scope.ranking.groupCriterion = 'subType'
$scope.selectedIndex = tab;
$scope.ranking.groupCriterion = 'subType';
if (tab.ca) {
$scope.ranking.sortCriterion = 'ca'
$scope.ranking.sortCriterion = 'ca';
} else {
$scope.ranking.sortCriterion = tab.types[0].key
$scope.ranking.sortCriterion = tab.types[0].key;
}
return refreshChart()
}
return refreshChart();
};
/**
* Callback to close the date-picking popup and refresh the results
*/
$scope.validateDateChange = function () {
$scope.datePicker.show = false
return refreshChart()
}
$scope.datePicker.show = false;
return refreshChart();
};
/* PRIVATE SCOPE */
@ -128,25 +128,25 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
*/
const initialize = function () {
Statistics.query(function (stats) {
$scope.statistics = stats
$scope.statistics = stats;
// watch the interval changes to refresh the graph
$scope.$watch(scope => scope.display.interval
, (newValue, oldValue) => refreshChart())
, (newValue, oldValue) => refreshChart());
$scope.$watch(scope => scope.ranking.sortCriterion
, (newValue, oldValue) => refreshChart())
, (newValue, oldValue) => refreshChart());
$scope.$watch(scope => scope.ranking.groupCriterion
, (newValue, oldValue) => refreshChart())
return refreshChart()
})
, (newValue, oldValue) => refreshChart());
return refreshChart();
});
// workaround for angular-bootstrap::tabs behavior: on tab deletion, another tab will be selected
// which will cause every tabs to reload, one by one, when the view is closed
return $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
if ((fromState.name === 'app.admin.stats_graphs') && (Object.keys(fromParams).length === 0)) {
return $scope.preventRefresh = true
return $scope.preventRefresh = true;
}
})
}
});
};
/**
* Generic function to toggle a bootstrap datePicker
@ -154,10 +154,10 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
* @param datePicker {Object} settings object of the concerned datepicker. Must have an 'opened' property
*/
var toggleDatePicker = function ($event, datePicker) {
$event.preventDefault()
$event.stopPropagation()
return datePicker.opened = !datePicker.opened
}
$event.preventDefault();
$event.stopPropagation();
return datePicker.opened = !datePicker.opened;
};
/**
* Query elasticSearch according to the current parameters and update the chart
@ -166,19 +166,19 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
if ($scope.selectedIndex && !$scope.preventRefresh) {
return query($scope.selectedIndex, function (aggregations, error) {
if (error) {
return console.error(error)
return console.error(error);
} else {
if ($scope.selectedIndex.graph.chart_type !== 'discreteBarChart') {
$scope.data = formatAggregations(aggregations)
return angular.forEach($scope.data, (datum, key) => updateChart($scope.selectedIndex.graph.chart_type, datum, key))
$scope.data = formatAggregations(aggregations);
return angular.forEach($scope.data, (datum, key) => updateChart($scope.selectedIndex.graph.chart_type, datum, key));
} else {
$scope.data = formatRankingAggregations(aggregations, $scope.selectedIndex.graph.limit, $scope.ranking.groupCriterion)
return updateChart($scope.selectedIndex.graph.chart_type, $scope.data.ranking, $scope.selectedIndex.es_type_key)
$scope.data = formatRankingAggregations(aggregations, $scope.selectedIndex.graph.limit, $scope.ranking.groupCriterion);
return updateChart($scope.selectedIndex.graph.chart_type, $scope.data.ranking, $scope.selectedIndex.es_type_key);
}
}
})
});
}
}
};
/**
* Callback used in NVD3 to print timestamps as literal dates on the X axis
@ -187,45 +187,45 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
/* WARNING !! These tests (typeof/instanceof) may become broken on nvd3 update */
if ($scope.display.interval === 'day') {
if ((typeof d === 'number') || d instanceof Date) {
return d3.time.format(Fablab.d3DateFormat)(moment(d).toDate())
return d3.time.format(Fablab.d3DateFormat)(moment(d).toDate());
} else { // typeof d == 'string'
return d
return d;
}
} else if ($scope.display.interval === 'week') {
if ((typeof x === 'number') || d instanceof Date) {
return d3.time.format(_t('week_short') + ' %U')(moment(d).toDate())
return d3.time.format(_t('week_short') + ' %U')(moment(d).toDate());
} else if (typeof d === 'number') {
return _t('week_of_START_to_END', { START: moment(d).format('L'), END: moment(d).add(6, 'days').format('L') })
return _t('week_of_START_to_END', { START: moment(d).format('L'), END: moment(d).add(6, 'days').format('L') });
} else { // typeof d == 'string'
return d
return d;
}
} else if ($scope.display.interval === 'month') {
if (typeof d === 'number') {
const label = moment(d).format('MMMM YYYY')
return label.substr(0, 1).toUpperCase() + label.substr(1).toLowerCase()
const label = moment(d).format('MMMM YYYY');
return label.substr(0, 1).toUpperCase() + label.substr(1).toLowerCase();
} else { // typeof d == 'string'
return d
return d;
}
}
}
};
/**
* Format aggregations as retuned by elasticSearch to an understandable format for NVD3
* @param aggs {Object} as returned by elasticsearch
*/
var formatAggregations = function (aggs) {
const format = {}
const format = {};
angular.forEach(aggs, function (type, type_key) { // go through aggs[$TYPE] where $TYPE = month|year|hour|booking|...
format[type_key] = []
format[type_key] = [];
if (type.subgroups) {
return angular.forEach(type.subgroups.buckets, subgroup => // go through aggs.$TYPE.subgroups.buckets where each bucket represent a $SUBTYPE
angular.forEach($scope.selectedIndex.types, function (cur_type) { // in the mean time, go through the types of the current index (active tab) ...
if (cur_type.key === type_key) { // ... looking for the type matching $TYPE
return (() => {
const result = []
const result = [];
for (let it_st = 0, end = cur_type.subtypes.length - 1; it_st <= end; it_st++) { // when we've found it, iterate over its subtypes ...
const cur_subtype = cur_type.subtypes[it_st]
const cur_subtype = cur_type.subtypes[it_st];
if (subgroup.key === cur_subtype.key) { // ... which match $SUBTYPE
// then we construct NVD3 dataSource according to these information
var dataSource = {
@ -234,31 +234,31 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
total: 0,
color: CHART_COLORS[it_st],
area: true
}
};
// finally, we iterate over 'intervals' buckets witch contains
// per date aggregations for our current dataSource
angular.forEach(subgroup.intervals.buckets, function (interval) {
dataSource.values.push({
x: interval.key,
y: interval.total.value
})
return dataSource.total += parseInt(interval.total.value)
})
dataSource.key += ` (${dataSource.total})`
result.push(format[type_key].push(dataSource))
});
return dataSource.total += parseInt(interval.total.value);
});
dataSource.key += ` (${dataSource.total})`;
result.push(format[type_key].push(dataSource));
} else {
result.push(undefined)
result.push(undefined);
}
}
return result
})()
return result;
})();
}
})
)
);
}
})
return format
}
});
return format;
};
/**
* Format aggregations for ranking charts to an understandable format for NVD3
@ -268,31 +268,31 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
*/
var formatRankingAggregations = function (aggs, limit, typeKey) {
const format =
{ ranking: [] }
{ ranking: [] };
let it = 0
let it = 0;
while (it < aggs.subgroups.buckets.length) {
const bucket = aggs.subgroups.buckets[it]
const bucket = aggs.subgroups.buckets[it];
const dataSource = {
values: [],
key: getRankingLabel(bucket.key, typeKey),
color: CHART_COLORS[it],
area: true
}
};
dataSource.values.push({
x: getRankingLabel(bucket.key, typeKey),
y: bucket.total.value
})
format.ranking.push(dataSource)
it++
});
format.ranking.push(dataSource);
it++;
}
const getY = object => object.values[0].y
format.ranking = stableSort(format.ranking, 'DESC', getY).slice(0, limit)
const getY = object => object.values[0].y;
format.ranking = stableSort(format.ranking, 'DESC', getY).slice(0, limit);
for (let i = 0, end = format.ranking.length; i <= end; i++) {
if (typeof format.ranking[i] === 'undefined') { format.ranking.splice(i, 1) }
if (typeof format.ranking[i] === 'undefined') { format.ranking.splice(i, 1); }
}
return format
}
return format;
};
/**
* For BarCharts, return the label for a given bar
@ -305,7 +305,7 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
for (let type of Array.from($scope.selectedIndex.types)) {
for (let subtype of Array.from(type.subtypes)) {
if (subtype.key === key) {
return subtype.label
return subtype.label;
}
}
}
@ -313,15 +313,15 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
for (let field of Array.from($scope.selectedIndex.additional_fields)) {
if (field.key === typeKey) {
switch (field.data_type) {
case 'date': return moment(key).format('LL'); break
case 'list': return key.name; break
default: return key
case 'date': return moment(key).format('LL'); break;
case 'list': return key.name; break;
default: return key;
}
}
}
}
}
}
};
/**
* Prepare the elasticSearch query for the stats matching the current controller's parameters
@ -333,57 +333,57 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
var query = function (index, callback) {
// invalid callback handeling
if (typeof (callback) !== 'function') {
console.error('[graphsController::query] Error: invalid callback provided')
return
console.error('[graphsController::query] Error: invalid callback provided');
return;
}
if (!index) {
callback([], '[graphsController::query] Error: invalid index provided')
return
callback([], '[graphsController::query] Error: invalid index provided');
return;
}
if (index.graph.chart_type !== 'discreteBarChart') {
// list statistics types
const stat_types = []
const stat_types = [];
for (let t of Array.from(index.types)) {
if (t.graph) {
stat_types.push(t.key)
stat_types.push(t.key);
}
}
// exception handeling
if (stat_types.length === 0) {
callback([], 'Error: Unable to retrieve any graphical statistic types in the provided index')
callback([], 'Error: Unable to retrieve any graphical statistic types in the provided index');
}
let type_it = 0
const results = {}
let error = ''
let type_it = 0;
const results = {};
let error = '';
var recursiveCb = function () {
if (type_it < stat_types.length) {
return queryElasticStats(index.es_type_key, stat_types[type_it], function (prevResults, prevError) {
if (prevError) {
console.error(`[graphsController::query] ${prevError}`)
error += `\n${prevError}`
console.error(`[graphsController::query] ${prevError}`);
error += `\n${prevError}`;
}
results[stat_types[type_it]] = prevResults
type_it++
return recursiveCb()
})
results[stat_types[type_it]] = prevResults;
type_it++;
return recursiveCb();
});
} else {
return callback(results)
return callback(results);
}
}
return recursiveCb()
};
return recursiveCb();
} else { // palmares (ranking)
return queryElasticRanking(index.es_type_key, $scope.ranking.groupCriterion, $scope.ranking.sortCriterion, function (results, error) {
if (error) {
return callback([], error)
return callback([], error);
} else {
return callback(results)
return callback(results);
}
})
});
}
}
};
/**
* Run the elasticSearch query to retreive the /stats/type aggregations
@ -395,11 +395,11 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
var queryElasticStats = function (esType, statType, callback) {
// handle invalid callback
if (typeof (callback) !== 'function') {
console.error('[graphsController::queryElasticStats] Error: invalid callback provided')
return
console.error('[graphsController::queryElasticStats] Error: invalid callback provided');
return;
}
if (!esType || !statType) {
callback([], '[graphsController::queryElasticStats] Error: invalid parameters provided')
callback([], '[graphsController::queryElasticStats] Error: invalid parameters provided');
}
// run query
@ -416,12 +416,12 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
}
, function (error, response) {
if (error) {
return callback([], `Error: something unexpected occurred during elasticSearch query: ${error}`)
return callback([], `Error: something unexpected occurred during elasticSearch query: ${error}`);
} else {
return callback(response.aggregations)
return callback(response.aggregations);
}
})
}
});
};
/**
* For ranking displays, run the elasticSearch query to retreive the /stats/type aggregations
@ -434,10 +434,10 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
var queryElasticRanking = function (esType, groupKey, sortKey, callback) {
// handle invalid callback
if (typeof (callback) !== 'function') {
return console.error('[graphsController::queryElasticRanking] Error: invalid callback provided')
return console.error('[graphsController::queryElasticRanking] Error: invalid callback provided');
}
if (!esType || !groupKey || !sortKey) {
return callback([], '[graphsController::queryElasticRanking] Error: invalid parameters provided')
return callback([], '[graphsController::queryElasticRanking] Error: invalid parameters provided');
}
// run query
@ -450,18 +450,18 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
}
, function (error, response) {
if (error) {
return callback([], `Error: something unexpected occurred during elasticSearch query: ${error}`)
return callback([], `Error: something unexpected occurred during elasticSearch query: ${error}`);
} else {
return callback(response.aggregations)
return callback(response.aggregations);
}
})
}
});
};
/**
* Parse a final elastic results bucket and return a D3 compatible object
* @param bucket {{key_as_string:{String}, key:{Number}, doc_count:{Number}, total:{{value:{Number}}}}} interval bucket
*/
const parseElasticBucket = bucket => [ bucket.key, bucket.total.value ]
const parseElasticBucket = bucket => [ bucket.key, bucket.total.value ];
/**
* Build an object representing the content of the REST-JSON query to elasticSearch, based on the parameters
@ -519,18 +519,18 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
}
}
}
}
};
// scale weeks on sunday as nvd3 supports only these weeks
if (interval === 'week') {
q.aggregations.subgroups.aggregations.intervals.date_histogram['offset'] = '-1d'
q.aggregations.subgroups.aggregations.intervals.date_histogram['offset'] = '-1d';
// scale days to UTC time
} else if (interval === 'day') {
const offset = moment().utcOffset()
q.aggregations.subgroups.aggregations.intervals.date_histogram['offset'] = (-offset) + 'm'
const offset = moment().utcOffset();
q.aggregations.subgroups.aggregations.intervals.date_histogram['offset'] = (-offset) + 'm';
}
return q
}
return q;
};
/**
* Build an object representing the content of the REST-JSON query to elasticSearch, based on the parameters
@ -587,21 +587,21 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
}
}
}
}
};
// results must be sorted and limited later by angular
if (sortKey !== 'ca') {
angular.forEach(q.query.bool.must, function (must) {
if (must.term) {
return must.term.type = sortKey
return must.term.type = sortKey;
}
})
});
} else {
q.aggregations.subgroups.aggregations.total.sum.field = sortKey
q.aggregations.subgroups.aggregations.total.sum.field = sortKey;
}
return q
}
return q;
};
/**
* Redraw the NDV3 chart using the provided data
@ -610,76 +610,76 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
* @param type {String} which chart to update (statistic type key)
*/
var updateChart = function (chart_type, data, type) {
const id = `#chart-${type} svg`
const id = `#chart-${type} svg`;
// clean old charts
d3.selectAll(id + ' > *').remove()
d3.selectAll(id + ' > *').remove();
return nv.addGraph(function () {
// no data or many dates, display line charts
let chart
let chart;
if ((data.length === 0) || ((data[0].values.length > 1) && (chart_type !== 'discreteBarChart'))) {
if (chart_type === 'stackedAreaChart') {
chart = nv.models.stackedAreaChart().useInteractiveGuideline(true)
chart = nv.models.stackedAreaChart().useInteractiveGuideline(true);
} else {
chart = nv.models.lineChart().useInteractiveGuideline(true)
chart = nv.models.lineChart().useInteractiveGuideline(true);
}
if (data.length > 0) {
if ($scope.display.interval === 'day') {
setTimeScale(chart.xAxis, chart.xScale, [d3.time.day, data[0].values.length])
setTimeScale(chart.xAxis, chart.xScale, [d3.time.day, data[0].values.length]);
} else if ($scope.display.interval === 'week') {
setTimeScale(chart.xAxis, chart.xScale, [d3.time.week, data[0].values.length])
setTimeScale(chart.xAxis, chart.xScale, [d3.time.week, data[0].values.length]);
} else if ($scope.display.interval === 'month') {
setTimeScale(chart.xAxis, chart.xScale, [d3.time.month, data[0].values.length])
setTimeScale(chart.xAxis, chart.xScale, [d3.time.month, data[0].values.length]);
}
}
chart.xAxis.tickFormat(xAxisTickFormatFunction)
chart.yAxis.tickFormat(d3.format('d'))
chart.xAxis.tickFormat(xAxisTickFormatFunction);
chart.yAxis.tickFormat(d3.format('d'));
chart.xAxis.axisLabel(X_AXIS_LABEL)
chart.yAxis.axisLabel(Y_AXIS_LABEL)
chart.xAxis.axisLabel(X_AXIS_LABEL);
chart.yAxis.axisLabel(Y_AXIS_LABEL);
// only one date, display histograms
} else {
chart = nv.models.discreteBarChart()
chart.tooltip.enabled(false)
chart.showValues(true)
chart.x(d => d.label)
chart.y(d => d.value)
data = prepareDataForBarChart(data, type)
chart = nv.models.discreteBarChart();
chart.tooltip.enabled(false);
chart.showValues(true);
chart.x(d => d.label);
chart.y(d => d.value);
data = prepareDataForBarChart(data, type);
}
// common for each charts
chart.margin({ left: 100, right: 100 })
chart.noData(_t('no_data_for_this_period'))
chart.height(CHART_HEIGHT)
chart.margin({ left: 100, right: 100 });
chart.noData(_t('no_data_for_this_period'));
chart.height(CHART_HEIGHT);
// add new chart to the page
d3.select(id).datum(data).transition().duration(350).call(chart)
d3.select(id).datum(data).transition().duration(350).call(chart);
// resize the graph when the page is resized
nv.utils.windowResize(chart.update)
nv.utils.windowResize(chart.update);
// return the chart
return chart
})
}
return chart;
});
};
/**
* Given an NVD3 line chart axis, scale it to display ordinated dates, according to the given arguments
*/
var setTimeScale = function (nvd3Axis, nvd3Scale, argsArray) {
const scale = d3.time.scale()
const scale = d3.time.scale();
nvd3Axis.scale(scale)
nvd3Scale(scale)
nvd3Axis.scale(scale);
nvd3Scale(scale);
if (!argsArray && !argsArray.length) {
const oldTicks = nvd3Axis.axis.ticks
return nvd3Axis.axis.ticks = () => oldTicks.apply(nvd3Axis.axis, argsArray)
const oldTicks = nvd3Axis.axis.ticks;
return nvd3Axis.axis.ticks = () => oldTicks.apply(nvd3Axis.axis, argsArray);
}
}
};
/**
* Translate line chart data in dates row to bar chart data, one bar per type.
@ -689,19 +689,19 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
key: type,
values: []
}
]
];
for (let info of Array.from(data)) {
if (info) {
newData[0].values.push({
'label': info.key,
'value': info.values[0].y,
'color': info.color
})
});
}
}
return newData
}
return newData;
};
/**
* Sort the provided array, in the specified order, on the value returned by the callback.
@ -714,37 +714,37 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
*/
var stableSort = function (array, order, getValue) {
// prepare sorting
const keys_order = []
const result = []
const keys_order = [];
const result = [];
for (let i = 0, end = array.length; i <= end; i++) {
keys_order[array[i]] = i
result.push(array[i])
keys_order[array[i]] = i;
result.push(array[i]);
}
// callback for javascript native Array.sort()
const sort_fc = function (a, b) {
const val_a = getValue(a)
const val_b = getValue(b)
const val_a = getValue(a);
const val_b = getValue(b);
if (val_a === val_b) {
return keys_order[a] - keys_order[b]
return keys_order[a] - keys_order[b];
}
if (val_a < val_b) {
if (order === 'ASC') {
return -1
} else { return 1 }
return -1;
} else { return 1; }
} else {
if (order === 'ASC') {
return 1
} else { return -1 }
return 1;
} else { return -1; }
}
}
};
// finish the sort
result.sort(sort_fc)
return result
}
result.sort(sort_fc);
return result;
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);

View File

@ -13,17 +13,17 @@
*/
Application.Controllers.controller('GroupsController', ['$scope', 'groupsPromise', 'Group', 'growl', '_t', function ($scope, groupsPromise, Group, growl, _t) {
// List of users groups
$scope.groups = groupsPromise
$scope.groups = groupsPromise;
// Default: we show only enabled groups
$scope.groupFiltering = 'enabled'
$scope.groupFiltering = 'enabled';
// Available options for filtering groups by status
$scope.filterDisabled = [
'enabled',
'disabled',
'all'
]
];
/**
* Removes the newly inserted but not saved group / Cancel the current group modification
@ -32,20 +32,20 @@ Application.Controllers.controller('GroupsController', ['$scope', 'groupsPromise
*/
$scope.cancelGroup = function (rowform, index) {
if ($scope.groups[index].id != null) {
return rowform.$cancel()
return rowform.$cancel();
} else {
return $scope.groups.splice(index, 1)
return $scope.groups.splice(index, 1);
}
}
};
/**
* Creates a new empty entry in the $scope.groups array
*/
$scope.addGroup = function () {
$scope.inserted =
{ name: '' }
return $scope.groups.push($scope.inserted)
}
{ name: '' };
return $scope.groups.push($scope.inserted);
};
/**
* Saves a new group / Update an existing group to the server (form validation callback)
@ -55,18 +55,18 @@ Application.Controllers.controller('GroupsController', ['$scope', 'groupsPromise
$scope.saveGroup = function (data, id) {
if (id != null) {
return Group.update({ id }, { group: data }, response => growl.success(_t('group_form.changes_successfully_saved'))
, error => growl.error(_t('group_form.an_error_occurred_while_saving_changes')))
, error => growl.error(_t('group_form.an_error_occurred_while_saving_changes')));
} else {
return Group.save({ group: data }, function (resp) {
growl.success(_t('group_form.new_group_successfully_saved'))
return $scope.groups[$scope.groups.length - 1].id = resp.id
growl.success(_t('group_form.new_group_successfully_saved'));
return $scope.groups[$scope.groups.length - 1].id = resp.id;
}
, function (error) {
growl.error(_t('.group_forman_error_occurred_when_saving_the_new_group'))
return $scope.groups.splice($scope.groups.length - 1, 1)
})
growl.error(_t('.group_forman_error_occurred_when_saving_the_new_group'));
return $scope.groups.splice($scope.groups.length - 1, 1);
});
}
}
};
/**
* Deletes the group at the specified index
@ -74,27 +74,27 @@ Application.Controllers.controller('GroupsController', ['$scope', 'groupsPromise
*/
$scope.removeGroup = index =>
Group.delete({ id: $scope.groups[index].id }, function (resp) {
growl.success(_t('group_form.group_successfully_deleted'))
return $scope.groups.splice(index, 1)
growl.success(_t('group_form.group_successfully_deleted'));
return $scope.groups.splice(index, 1);
}
, error => growl.error(_t('group_form.unable_to_delete_group_because_some_users_and_or_groups_are_still_linked_to_it')))
, error => growl.error(_t('group_form.unable_to_delete_group_because_some_users_and_or_groups_are_still_linked_to_it')));
/**
* Enable/disable the group at the specified index
* @param index {number} group index in the $scope.groups array
*/
return $scope.toggleDisableGroup = function (index) {
const group = $scope.groups[index]
const group = $scope.groups[index];
if (!group.disabled && (group.users > 0)) {
return growl.error(_t('group_form.unable_to_disable_group_with_users', { USERS: group.users }, 'messageformat'))
return growl.error(_t('group_form.unable_to_disable_group_with_users', { USERS: group.users }, 'messageformat'));
} else {
return Group.update({ id: group.id }, { group: { disabled: !group.disabled } }, function (response) {
$scope.groups[index] = response
return growl.success(_t('group_form.group_successfully_enabled_disabled', { STATUS: response.disabled }, 'messageformat'))
$scope.groups[index] = response;
return growl.success(_t('group_form.group_successfully_enabled_disabled', { STATUS: response.disabled }, 'messageformat'));
}
, error => growl.error(_t('group_form.unable_to_enable_disable_group', { STATUS: !group.disabled }, 'messageformat')))
, error => growl.error(_t('group_form.unable_to_enable_disable_group', { STATUS: !group.disabled }, 'messageformat')));
}
}
};
}
])
]);

View File

@ -12,7 +12,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
/**
* Controller used in the admin invoices listing page
@ -22,28 +22,28 @@ Application.Controllers.controller('InvoicesController', ['$scope', '$state', 'I
/* PRIVATE STATIC CONSTANTS */
// number of invoices loaded each time we click on 'load more...'
const INVOICES_PER_PAGE = 20
const INVOICES_PER_PAGE = 20;
/* PUBLIC SCOPE */
// List of all users invoices
$scope.invoices = invoices
$scope.invoices = invoices;
// Invoices filters
$scope.searchInvoice = {
date: null,
name: '',
reference: ''
}
};
// currently displayed page of invoices (search results)
$scope.page = 1
$scope.page = 1;
// true when all invoices are loaded
$scope.noMoreResults = false
$scope.noMoreResults = false;
// Default invoices ordering/sorting
$scope.orderInvoice = '-reference'
$scope.orderInvoice = '-reference';
// Invoices parameters
$scope.invoice = {
@ -74,16 +74,16 @@ Application.Controllers.controller('InvoicesController', ['$scope', '$state', 'I
legals: {
content: ''
}
}
};
// Placeholding date for the invoice creation
$scope.today = moment()
$scope.today = moment();
// Placeholding date for the reservation begin
$scope.inOneWeek = moment().add(1, 'week').startOf('hour')
$scope.inOneWeek = moment().add(1, 'week').startOf('hour');
// Placeholding date for the reservation end
$scope.inOneWeekAndOneHour = moment().add(1, 'week').add(1, 'hour').startOf('hour')
$scope.inOneWeekAndOneHour = moment().add(1, 'week').add(1, 'hour').startOf('hour');
/**
* Change the invoices ordering criterion to the one provided
@ -91,14 +91,14 @@ Application.Controllers.controller('InvoicesController', ['$scope', '$state', 'I
*/
$scope.setOrderInvoice = function (orderBy) {
if ($scope.orderInvoice === orderBy) {
$scope.orderInvoice = `-${orderBy}`
$scope.orderInvoice = `-${orderBy}`;
} else {
$scope.orderInvoice = orderBy
$scope.orderInvoice = orderBy;
}
resetSearchInvoice()
return invoiceSearch()
}
resetSearchInvoice();
return invoiceSearch();
};
/**
* Open a modal window asking the admin the details to refund the user about the provided invoice
@ -110,65 +110,65 @@ Application.Controllers.controller('InvoicesController', ['$scope', '$state', 'I
templateUrl: '<%= asset_path "admin/invoices/avoirModal.html" %>',
controller: 'AvoirModalController',
resolve: {
invoice () { return invoice }
invoice () { return invoice; }
}
})
});
// once done, update the invoice model and inform the admin
return modalInstance.result.then(function (res) {
$scope.invoices.unshift(res.avoir)
$scope.invoices.unshift(res.avoir);
return Invoice.get({ id: invoice.id }, function (data) {
invoice.has_avoir = data.has_avoir
return growl.success(_t('refund_invoice_successfully_created'))
})
})
}
invoice.has_avoir = data.has_avoir;
return growl.success(_t('refund_invoice_successfully_created'));
});
});
};
/**
* Generate an invoice reference sample from the parametrized model
* @returns {string} invoice reference sample
*/
$scope.mkReference = function () {
let sample = $scope.invoice.reference.model
let sample = $scope.invoice.reference.model;
if (sample) {
// invoice number per day (dd..dd)
sample = sample.replace(/d+(?![^\[]*])/g, function (match, offset, string) { return padWithZeros(2, match.length) })
sample = sample.replace(/d+(?![^\[]*])/g, function (match, offset, string) { return padWithZeros(2, match.length); });
// invoice number per month (mm..mm)
sample = sample.replace(/m+(?![^\[]*])/g, function (match, offset, string) { return padWithZeros(12, match.length) })
sample = sample.replace(/m+(?![^\[]*])/g, function (match, offset, string) { return padWithZeros(12, match.length); });
// invoice number per year (yy..yy)
sample = sample.replace(/y+(?![^\[]*])/g, function (match, offset, string) { return padWithZeros(8, match.length) })
sample = sample.replace(/y+(?![^\[]*])/g, function (match, offset, string) { return padWithZeros(8, match.length); });
// date information
sample = sample.replace(/[YMD]+(?![^\[]*])/g, function (match, offset, string) { return $scope.today.format(match) })
sample = sample.replace(/[YMD]+(?![^\[]*])/g, function (match, offset, string) { return $scope.today.format(match); });
// information about online selling (X[text])
sample = sample.replace(/X\[([^\]]+)\]/g, function (match, p1, offset, string) { return p1 })
sample = sample.replace(/X\[([^\]]+)\]/g, function (match, p1, offset, string) { return p1; });
// information about wallet (W[text]) - does not apply here
sample = sample.replace(/W\[([^\]]+)\]/g, '')
sample = sample.replace(/W\[([^\]]+)\]/g, '');
// information about refunds (R[text]) - does not apply here
sample = sample.replace(/R\[([^\]]+)\]/g, '')
sample = sample.replace(/R\[([^\]]+)\]/g, '');
}
return sample
}
return sample;
};
/**
* Generate an order nmuber sample from the parametrized model
* @returns {string} invoice reference sample
*/
$scope.mkNumber = function () {
let sample = $scope.invoice.number.model
let sample = $scope.invoice.number.model;
if (sample) {
// global order number (nn..nn)
sample = sample.replace(/n+(?![^\[]*])/g, function (match, offset, string) { return padWithZeros(327, match.length) })
sample = sample.replace(/n+(?![^\[]*])/g, function (match, offset, string) { return padWithZeros(327, match.length); });
// order number per year (yy..yy)
sample = sample.replace(/y+(?![^\[]*])/g, function (match, offset, string) { return padWithZeros(8, match.length) })
sample = sample.replace(/y+(?![^\[]*])/g, function (match, offset, string) { return padWithZeros(8, match.length); });
// order number per month (mm..mm)
sample = sample.replace(/m+(?![^\[]*])/g, function (match, offset, string) { return padWithZeros(12, match.length) })
sample = sample.replace(/m+(?![^\[]*])/g, function (match, offset, string) { return padWithZeros(12, match.length); });
// order number per day (dd..dd)
sample = sample.replace(/d+(?![^\[]*])/g, function (match, offset, string) { return padWithZeros(2, match.length) })
sample = sample.replace(/d+(?![^\[]*])/g, function (match, offset, string) { return padWithZeros(2, match.length); });
// date information
sample = sample.replace(/[YMD]+(?![^\[]*])/g, function (match, offset, string) { return $scope.today.format(match) })
sample = sample.replace(/[YMD]+(?![^\[]*])/g, function (match, offset, string) { return $scope.today.format(match); });
}
return sample
}
return sample;
};
/**
* Open a modal dialog allowing the user to edit the invoice reference generation template
@ -180,27 +180,27 @@ Application.Controllers.controller('InvoicesController', ['$scope', '$state', 'I
size: 'lg',
resolve: {
model () {
return $scope.invoice.reference.model
return $scope.invoice.reference.model;
}
},
controller ($scope, $uibModalInstance, model) {
$scope.model = model
$scope.ok = function () { $uibModalInstance.close($scope.model) }
$scope.cancel = function () { $uibModalInstance.dismiss('cancel') }
$scope.model = model;
$scope.ok = function () { $uibModalInstance.close($scope.model); };
$scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
}
})
});
modalInstance.result.then(function (model) {
Setting.update({ name: 'invoice_reference' }, { value: model }, function (data) {
$scope.invoice.reference.model = model
growl.success(_t('invoice_reference_successfully_saved'))
$scope.invoice.reference.model = model;
growl.success(_t('invoice_reference_successfully_saved'));
}
, function (error) {
growl.error(_t('an_error_occurred_while_saving_invoice_reference'))
console.error(error)
})
})
}
growl.error(_t('an_error_occurred_while_saving_invoice_reference'));
console.error(error);
});
});
};
/**
* Open a modal dialog allowing the user to edit the invoice code
@ -212,47 +212,47 @@ Application.Controllers.controller('InvoicesController', ['$scope', '$state', 'I
size: 'lg',
resolve: {
model () {
return $scope.invoice.code.model
return $scope.invoice.code.model;
},
active () {
return $scope.invoice.code.active
return $scope.invoice.code.active;
}
},
controller ($scope, $uibModalInstance, model, active) {
$scope.codeModel = model
$scope.isSelected = active
$scope.codeModel = model;
$scope.isSelected = active;
$scope.ok = function () { $uibModalInstance.close({ model: $scope.codeModel, active: $scope.isSelected }) }
$scope.cancel = function () { $uibModalInstance.dismiss('cancel') }
$scope.ok = function () { $uibModalInstance.close({ model: $scope.codeModel, active: $scope.isSelected }); };
$scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
}
})
});
return modalInstance.result.then(function (result) {
Setting.update({ name: 'invoice_code-value' }, { value: result.model }, function (data) {
$scope.invoice.code.model = result.model
$scope.invoice.code.model = result.model;
if (result.active) {
return growl.success(_t('invoicing_code_succesfully_saved'))
return growl.success(_t('invoicing_code_succesfully_saved'));
}
}
, function (error) {
growl.error(_t('an_error_occurred_while_saving_the_invoicing_code'))
return console.error(error)
})
growl.error(_t('an_error_occurred_while_saving_the_invoicing_code'));
return console.error(error);
});
return Setting.update({ name: 'invoice_code-active' }, { value: result.active ? 'true' : 'false' }, function (data) {
$scope.invoice.code.active = result.active
$scope.invoice.code.active = result.active;
if (result.active) {
return growl.success(_t('code_successfully_activated'))
return growl.success(_t('code_successfully_activated'));
} else {
return growl.success(_t('code_successfully_disabled'))
return growl.success(_t('code_successfully_disabled'));
}
}
, function (error) {
growl.error(_t('an_error_occurred_while_activating_the_invoicing_code'))
return console.error(error)
})
})
}
growl.error(_t('an_error_occurred_while_activating_the_invoicing_code'));
return console.error(error);
});
});
};
/**
* Open a modal dialog allowing the user to edit the invoice number
@ -264,27 +264,27 @@ Application.Controllers.controller('InvoicesController', ['$scope', '$state', 'I
size: 'lg',
resolve: {
model () {
return $scope.invoice.number.model
return $scope.invoice.number.model;
}
},
controller ($scope, $uibModalInstance, model) {
$scope.model = model
$scope.ok = function () { $uibModalInstance.close($scope.model) }
$scope.cancel = function () { $uibModalInstance.dismiss('cancel') }
$scope.model = model;
$scope.ok = function () { $uibModalInstance.close($scope.model); };
$scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
}
})
});
return modalInstance.result.then(function (model) {
Setting.update({ name: 'invoice_order-nb' }, { value: model }, function (data) {
$scope.invoice.number.model = model
return growl.success(_t('order_number_successfully_saved'))
$scope.invoice.number.model = model;
return growl.success(_t('order_number_successfully_saved'));
}
, function (error) {
growl.error(_t('an_error_occurred_while_saving_the_order_number'))
return console.error(error)
})
})
}
growl.error(_t('an_error_occurred_while_saving_the_order_number'));
return console.error(error);
});
});
};
/**
* Open a modal dialog allowing the user to edit the VAT parameters for the invoices
@ -297,95 +297,95 @@ Application.Controllers.controller('InvoicesController', ['$scope', '$state', 'I
size: 'lg',
resolve: {
rate () {
return $scope.invoice.VAT.rate
return $scope.invoice.VAT.rate;
},
active () {
return $scope.invoice.VAT.active
return $scope.invoice.VAT.active;
}
},
controller ($scope, $uibModalInstance, rate, active) {
$scope.rate = rate
$scope.isSelected = active
$scope.rate = rate;
$scope.isSelected = active;
$scope.ok = function () { $uibModalInstance.close({ rate: $scope.rate, active: $scope.isSelected }) }
return $scope.cancel = function () { $uibModalInstance.dismiss('cancel') }
$scope.ok = function () { $uibModalInstance.close({ rate: $scope.rate, active: $scope.isSelected }); };
return $scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
}
})
});
return modalInstance.result.then(function (result) {
Setting.update({ name: 'invoice_VAT-rate' }, { value: result.rate + '' }, function (data) {
$scope.invoice.VAT.rate = result.rate
$scope.invoice.VAT.rate = result.rate;
if (result.active) {
return growl.success(_t('VAT_rate_successfully_saved'))
return growl.success(_t('VAT_rate_successfully_saved'));
}
}
, function (error) {
growl.error(_t('an_error_occurred_while_saving_the_VAT_rate'))
return console.error(error)
})
growl.error(_t('an_error_occurred_while_saving_the_VAT_rate'));
return console.error(error);
});
return Setting.update({ name: 'invoice_VAT-active' }, { value: result.active ? 'true' : 'false' }, function (data) {
$scope.invoice.VAT.active = result.active
$scope.invoice.VAT.active = result.active;
if (result.active) {
return growl.success(_t('VAT_successfully_activated'))
return growl.success(_t('VAT_successfully_activated'));
} else {
return growl.success(_t('VAT_successfully_disabled'))
return growl.success(_t('VAT_successfully_disabled'));
}
}
, function (error) {
growl.error(_t('an_error_occurred_while_activating_the_VAT'))
return console.error(error)
})
})
}
growl.error(_t('an_error_occurred_while_activating_the_VAT'));
return console.error(error);
});
});
};
/**
* Callback to save the value of the text zone when editing is done
*/
$scope.textEditEnd = function (event) {
const parsed = parseHtml($scope.invoice.text.content)
const parsed = parseHtml($scope.invoice.text.content);
return Setting.update({ name: 'invoice_text' }, { value: parsed }, function (data) {
$scope.invoice.text.content = parsed
return growl.success(_t('text_successfully_saved'))
$scope.invoice.text.content = parsed;
return growl.success(_t('text_successfully_saved'));
}
, function (error) {
growl.error(_t('an_error_occurred_while_saving_the_text'))
return console.error(error)
})
}
growl.error(_t('an_error_occurred_while_saving_the_text'));
return console.error(error);
});
};
/**
* Callback to save the value of the legal information zone when editing is done
*/
$scope.legalsEditEnd = function (event) {
const parsed = parseHtml($scope.invoice.legals.content)
const parsed = parseHtml($scope.invoice.legals.content);
return Setting.update({ name: 'invoice_legals' }, { value: parsed }, function (data) {
$scope.invoice.legals.content = parsed
return growl.success(_t('address_and_legal_information_successfully_saved'))
$scope.invoice.legals.content = parsed;
return growl.success(_t('address_and_legal_information_successfully_saved'));
}
, function (error) {
growl.error(_t('an_error_occurred_while_saving_the_address_and_the_legal_information'))
return console.error(error)
})
}
growl.error(_t('an_error_occurred_while_saving_the_address_and_the_legal_information'));
return console.error(error);
});
};
/**
* Callback when any of the filters changes.
* Full reload the results list
*/
$scope.handleFilterChange = function () {
resetSearchInvoice()
return invoiceSearch()
}
resetSearchInvoice();
return invoiceSearch();
};
/**
* Callback for the 'load more' button.
* Will load the next results of the current search, if any
*/
$scope.showNextInvoices = function () {
$scope.page += 1
return invoiceSearch(true)
}
$scope.page += 1;
return invoiceSearch(true);
};
/* PRIVATE SCOPE */
@ -394,23 +394,23 @@ Application.Controllers.controller('InvoicesController', ['$scope', '$state', 'I
*/
const initialize = function () {
if (!invoices[0] || (invoices[0].maxInvoices <= $scope.invoices.length)) {
$scope.noMoreResults = true
$scope.noMoreResults = true;
}
// retrieve settings from the DB through the API
$scope.invoice.legals.content = settings['invoice_legals']
$scope.invoice.text.content = settings['invoice_text']
$scope.invoice.VAT.rate = parseFloat(settings['invoice_VAT-rate'])
$scope.invoice.VAT.active = (settings['invoice_VAT-active'] === 'true')
$scope.invoice.number.model = settings['invoice_order-nb']
$scope.invoice.code.model = settings['invoice_code-value']
$scope.invoice.code.active = (settings['invoice_code-active'] === 'true')
$scope.invoice.reference.model = settings['invoice_reference']
$scope.invoice.legals.content = settings['invoice_legals'];
$scope.invoice.text.content = settings['invoice_text'];
$scope.invoice.VAT.rate = parseFloat(settings['invoice_VAT-rate']);
$scope.invoice.VAT.active = (settings['invoice_VAT-active'] === 'true');
$scope.invoice.number.model = settings['invoice_order-nb'];
$scope.invoice.code.model = settings['invoice_code-value'];
$scope.invoice.code.active = (settings['invoice_code-active'] === 'true');
$scope.invoice.reference.model = settings['invoice_reference'];
$scope.invoice.logo = {
filetype: 'image/png',
filename: 'logo.png',
base64: settings['invoice_logo']
}
};
// Watch the logo, when a change occurs, save it
return $scope.$watch('invoice.logo', function () {
@ -418,15 +418,15 @@ Application.Controllers.controller('InvoicesController', ['$scope', '$state', 'I
return Setting.update(
{ name: 'invoice_logo' },
{ value: $scope.invoice.logo.base64 },
function (data) { growl.success(_t('logo_successfully_saved')) },
function (data) { growl.success(_t('logo_successfully_saved')); },
function (error) {
growl.error(_t('an_error_occurred_while_saving_the_logo'))
return console.error(error)
growl.error(_t('an_error_occurred_while_saving_the_logo'));
return console.error(error);
}
)
);
}
})
}
});
};
/**
* Output the given integer with leading zeros. If the given value is longer than the given
@ -434,7 +434,7 @@ Application.Controllers.controller('InvoicesController', ['$scope', '$state', 'I
* @param value {number} the integer to pad
* @param length {number} the length of the resulting string.
*/
var padWithZeros = function (value, length) { return (1e15 + value + '').slice(-length) }
var padWithZeros = function (value, length) { return (1e15 + value + '').slice(-length); };
/**
* Remove every unsupported html tag from the given html text (like <p>, <span>, ...).
@ -445,20 +445,20 @@ Application.Controllers.controller('InvoicesController', ['$scope', '$state', 'I
var parseHtml = function (html) {
return html.replace(/<\/?(\w+)((\s+\w+(\s*=\s*(?:".*?"|'.*?'|[^'">\s]+))?)+\s*|\s*)\/?>/g, function (match, p1, offset, string) {
if (['b', 'u', 'i', 'br'].includes(p1)) {
return match
return match;
} else {
return ''
return '';
}
})
}
});
};
/**
* Reinitialize the context of invoices' search to display new results set
*/
var resetSearchInvoice = function () {
$scope.page = 1
return $scope.noMoreResults = false
}
$scope.page = 1;
return $scope.noMoreResults = false;
};
/**
* Run a search query with the current parameters set concerning invoices, then affect or concat the results
@ -477,21 +477,21 @@ Application.Controllers.controller('InvoicesController', ['$scope', '$state', 'I
}
}, function (invoices) {
if (concat) {
$scope.invoices = $scope.invoices.concat(invoices)
$scope.invoices = $scope.invoices.concat(invoices);
} else {
$scope.invoices = invoices
$scope.invoices = invoices;
}
if (!invoices[0] || (invoices[0].maxInvoices <= $scope.invoices.length)) {
return $scope.noMoreResults = true
return $scope.noMoreResults = true;
}
})
}
});
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);
/**
* Controller used in the invoice refunding modal window
@ -501,17 +501,17 @@ Application.Controllers.controller('AvoirModalController', ['$scope', '$uibModal
/* PUBLIC SCOPE */
// invoice linked to the current refund
$scope.invoice = invoice
$scope.invoice = invoice;
// Associative array containing invoice_item ids associated with boolean values
$scope.partial = {}
$scope.partial = {};
// Default refund parameters
$scope.avoir = {
invoice_id: invoice.id,
subscription_to_expire: false,
invoice_items_ids: []
}
};
// Possible refunding methods
$scope.avoirModes = [
@ -520,12 +520,12 @@ Application.Controllers.controller('AvoirModalController', ['$scope', '$uibModal
{ name: _t('by_cheque'), value: 'cheque' },
{ name: _t('by_transfer'), value: 'transfer' },
{ name: _t('by_wallet'), value: 'wallet' }
]
];
// If a subscription was took with the current invoice, should it be canceled or not
$scope.subscriptionExpireOptions = {}
$scope.subscriptionExpireOptions[_t('yes')] = true
$scope.subscriptionExpireOptions[_t('no')] = false
$scope.subscriptionExpireOptions = {};
$scope.subscriptionExpireOptions[_t('yes')] = true;
$scope.subscriptionExpireOptions[_t('no')] = false;
// AngularUI-Bootstrap datepicker parameters to define when to refund
$scope.datePicker = {
@ -534,47 +534,47 @@ Application.Controllers.controller('AvoirModalController', ['$scope', '$uibModal
options: {
startingDay: Fablab.weekStartingDay
}
}
};
/**
* Callback to open the datepicker
*/
$scope.openDatePicker = function ($event) {
$event.preventDefault()
$event.stopPropagation()
return $scope.datePicker.opened = true
}
$event.preventDefault();
$event.stopPropagation();
return $scope.datePicker.opened = true;
};
/**
* Validate the refunding and generate a refund invoice
*/
$scope.ok = function () {
// check that at least 1 element of the invoice is refunded
$scope.avoir.invoice_items_ids = []
$scope.avoir.invoice_items_ids = [];
for (let itemId in $scope.partial) {
const refundItem = $scope.partial[itemId]
if (refundItem) { $scope.avoir.invoice_items_ids.push(parseInt(itemId)) }
const refundItem = $scope.partial[itemId];
if (refundItem) { $scope.avoir.invoice_items_ids.push(parseInt(itemId)); }
}
if ($scope.avoir.invoice_items_ids.length === 0) {
return growl.error(_t('you_must_select_at_least_one_element_to_create_a_refund'))
return growl.error(_t('you_must_select_at_least_one_element_to_create_a_refund'));
} else {
return Invoice.save(
{ avoir: $scope.avoir },
function (avoir) { // success
$uibModalInstance.close({ avoir, invoice: $scope.invoice })
$uibModalInstance.close({ avoir, invoice: $scope.invoice });
},
function (err) { // failed
growl.error(_t('unable_to_create_the_refund'))
growl.error(_t('unable_to_create_the_refund'));
}
)
);
}
}
};
/**
* Cancel the refund, dismiss the modal window
*/
$scope.cancel = function () { $uibModalInstance.dismiss('cancel') }
$scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
/* PRIVATE SCOPE */
@ -584,19 +584,19 @@ Application.Controllers.controller('AvoirModalController', ['$scope', '$uibModal
const initialize = function () {
// if the invoice was payed with stripe, allow to refund through stripe
Invoice.get({ id: invoice.id }, function (data) {
$scope.invoice = data
$scope.invoice = data;
// default : all elements of the invoice are refund
return Array.from(data.items).map(function (item) {
return ($scope.partial[item.id] = (typeof item.avoir_item_id !== 'number'))
})
})
return ($scope.partial[item.id] = (typeof item.avoir_item_id !== 'number'));
});
});
if (invoice.stripe) {
return $scope.avoirModes.push({ name: _t('online_payment'), value: 'stripe' })
return $scope.avoirModes.push({ name: _t('online_payment'), value: 'stripe' });
}
}
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);

View File

@ -13,7 +13,7 @@
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
/* COMMON CODE */
@ -38,7 +38,7 @@
class MembersController {
constructor ($scope, $state, Group, Training) {
// Retrieve the profiles groups (eg. students ...)
Group.query(function (groups) { $scope.groups = groups.filter(function (g) { return (g.slug !== 'admins') && !g.disabled }) })
Group.query(function (groups) { $scope.groups = groups.filter(function (g) { return (g.slug !== 'admins') && !g.disabled; }); });
// Retrieve the list of available trainings
Training.query().$promise.then(function (data) {
@ -47,9 +47,9 @@ class MembersController {
id: d.id,
name: d.name,
disabled: d.disabled
})
})
})
});
});
});
// Default parameters for AngularUI-Bootstrap datepicker
$scope.datePicker = {
@ -59,27 +59,27 @@ class MembersController {
options: {
startingDay: Fablab.weekStartingDay
}
}
};
/**
* Shows the birth day datepicker
* @param $event {Object} jQuery event object
*/
$scope.openDatePicker = function ($event) {
$event.preventDefault()
$event.stopPropagation()
return $scope.datePicker.opened = true
}
$event.preventDefault();
$event.stopPropagation();
return $scope.datePicker.opened = true;
};
/**
* Shows the end of subscription datepicker
* @param $event {Object} jQuery event object
*/
$scope.openSubscriptionDatePicker = function ($event) {
$event.preventDefault()
$event.stopPropagation()
return $scope.datePicker.subscription_date_opened = true
}
$event.preventDefault();
$event.stopPropagation();
return $scope.datePicker.subscription_date_opened = true;
};
/**
* For use with ngUpload (https://github.com/twilson63/ngUpload).
@ -89,24 +89,24 @@ class MembersController {
*/
$scope.submited = function (content) {
if ((content.id == null)) {
$scope.alerts = []
$scope.alerts = [];
return angular.forEach(content, function (v, k) {
angular.forEach(v, function (err) {
$scope.alerts.push({
msg: k + ': ' + err,
type: 'danger'
})
})
})
});
});
});
} else {
return $state.go('app.admin.members')
return $state.go('app.admin.members');
}
}
};
/**
* Changes the admin's view to the members list page
*/
$scope.cancel = function () { $state.go('app.admin.members') }
$scope.cancel = function () { $state.go('app.admin.members'); };
/**
* For use with 'ng-class', returns the CSS class name for the uploads previews.
@ -115,11 +115,11 @@ class MembersController {
*/
$scope.fileinputClass = function (v) {
if (v) {
return 'fileinput-exists'
return 'fileinput-exists';
} else {
return 'fileinput-new'
return 'fileinput-new';
}
}
};
}
}
@ -131,12 +131,12 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce',
/* PRIVATE STATIC CONSTANTS */
// number of users loaded each time we click on 'load more...'
const USERS_PER_PAGE = 20
const USERS_PER_PAGE = 20;
/* PUBLIC SCOPE */
// members list
$scope.members = membersPromise
$scope.members = membersPromise;
$scope.member = {
// Members plain-text filtering. Default: not filtered
@ -147,13 +147,13 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce',
page: 1,
// true when all members where loaded
noMore: false
}
};
// admins list
$scope.admins = adminsPromise.admins
$scope.admins = adminsPromise.admins;
// Admins ordering/sorting. Default: not sorted
$scope.orderAdmin = null
$scope.orderAdmin = null;
/**
* Change the members ordering criterion to the one provided
@ -161,14 +161,14 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce',
*/
$scope.setOrderMember = function (orderBy) {
if ($scope.member.order === orderBy) {
$scope.member.order = `-${orderBy}`
$scope.member.order = `-${orderBy}`;
} else {
$scope.member.order = orderBy
$scope.member.order = orderBy;
}
resetSearchMember()
return memberSearch()
}
resetSearchMember();
return memberSearch();
};
/**
* Change the admins ordering criterion to the one provided
@ -176,11 +176,11 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce',
*/
$scope.setOrderAdmin = function (orderAdmin) {
if ($scope.orderAdmin === orderAdmin) {
return $scope.orderAdmin = `-${orderAdmin}`
return $scope.orderAdmin = `-${orderAdmin}`;
} else {
return $scope.orderAdmin = orderAdmin
return $scope.orderAdmin = orderAdmin;
}
}
};
/**
* Ask for confirmation then delete the specified administrator
@ -195,7 +195,7 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce',
return {
title: _t('confirmation_required'),
msg: $sce.trustAsHtml(_t('do_you_really_want_to_delete_this_administrator_this_cannot_be_undone') + '<br/><br/>' + _t('this_may_take_a_while_please_wait'))
}
};
}
}
},
@ -203,31 +203,31 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce',
Admin.delete(
{ id: admin.id },
function () {
admins.splice(findAdminIdxById(admins, admin.id), 1)
return growl.success(_t('administrator_successfully_deleted'))
admins.splice(findAdminIdxById(admins, admin.id), 1);
return growl.success(_t('administrator_successfully_deleted'));
},
function (error) { growl.error(_t('unable_to_delete_the_administrator')) }
)
function (error) { growl.error(_t('unable_to_delete_the_administrator')); }
);
}
)
}
);
};
/**
* Callback for the 'load more' button.
* Will load the next results of the current search, if any
*/
$scope.showNextMembers = function () {
$scope.member.page += 1
return memberSearch(true)
}
$scope.member.page += 1;
return memberSearch(true);
};
/**
* Callback when the search field content changes: reload the search results
*/
$scope.updateTextSearch = function () {
resetSearchMember()
return memberSearch()
}
resetSearchMember();
return memberSearch();
};
/**
* Callback to alert the admin that the export request was acknowledged and is
@ -236,10 +236,10 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce',
$scope.alertExport = function (type) {
Export.status({ category: 'users', type }).then(function (res) {
if (!res.data.exists) {
return growl.success(_t('export_is_running_you_ll_be_notified_when_its_ready'))
return growl.success(_t('export_is_running_you_ll_be_notified_when_its_ready'));
}
})
}
});
};
/* PRIVATE SCOPE */
@ -248,9 +248,9 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce',
*/
const initialize = function () {
if (!membersPromise[0] || (membersPromise[0].maxMembers <= $scope.members.length)) {
return $scope.member.noMore = true
return $scope.member.noMore = true;
}
}
};
/**
* Iterate through the provided array and return the index of the requested admin
@ -259,16 +259,16 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce',
* @returns {Number} index of the requested admin, in the provided array
*/
var findAdminIdxById = function (admins, id) {
return (admins.map(function (admin) { return admin.id })).indexOf(id)
}
return (admins.map(function (admin) { return admin.id; })).indexOf(id);
};
/**
* Reinitialize the context of members's search to display new results set
*/
var resetSearchMember = function () {
$scope.member.noMore = false
return $scope.member.page = 1
}
$scope.member.noMore = false;
return $scope.member.page = 1;
};
/**
* Run a search query with the current parameters set ($scope.member[searchText,order,page])
@ -285,21 +285,21 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce',
}
}, function (members) {
if (concat) {
$scope.members = $scope.members.concat(members)
$scope.members = $scope.members.concat(members);
} else {
$scope.members = members
$scope.members = members;
}
if (!members[0] || (members[0].maxMembers <= $scope.members.length)) {
return $scope.member.noMore = true
return $scope.member.noMore = true;
}
})
}
});
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);
/**
* Controller used in the member edition page
@ -309,51 +309,51 @@ Application.Controllers.controller('EditMemberController', ['$scope', '$state',
/* PUBLIC SCOPE */
// API URL where the form will be posted
$scope.actionUrl = `/api/members/${$stateParams.id}`
$scope.actionUrl = `/api/members/${$stateParams.id}`;
// Form action on the above URL
$scope.method = 'patch'
$scope.method = 'patch';
// List of tags associables with user
$scope.tags = tagsPromise
$scope.tags = tagsPromise;
// The user to edit
$scope.user = memberPromise
$scope.user = memberPromise;
// Should the passord be modified?
$scope.password =
{ change: false }
{ change: false };
// the user subscription
if (($scope.user.subscribed_plan != null) && ($scope.user.subscription != null)) {
$scope.subscription = $scope.user.subscription
$scope.subscription.expired_at = $scope.subscription.expired_at
$scope.subscription = $scope.user.subscription;
$scope.subscription.expired_at = $scope.subscription.expired_at;
} else {
Plan.query({ group_id: $scope.user.group_id }, function (plans) {
$scope.plans = plans
$scope.plans = plans;
return Array.from($scope.plans).map(function (plan) {
return (plan.nameToDisplay = $filter('humanReadablePlanName')(plan))
})
})
return (plan.nameToDisplay = $filter('humanReadablePlanName')(plan));
});
});
}
// Available trainings list
$scope.trainings = []
$scope.trainings = [];
// Profiles types (student/standard/...)
$scope.groups = []
$scope.groups = [];
// the user wallet
$scope.wallet = walletPromise
$scope.wallet = walletPromise;
// user wallet transactions
$scope.transactions = transactionsPromise
$scope.transactions = transactionsPromise;
// used in wallet partial template to identify parent view
$scope.view = 'member_edit'
$scope.view = 'member_edit';
// current active authentication provider
$scope.activeProvider = activeProviderPromise
$scope.activeProvider = activeProviderPromise;
/**
* Open a modal dialog, allowing the admin to extend the current user's subscription (freely or not)
@ -366,8 +366,8 @@ Application.Controllers.controller('EditMemberController', ['$scope', '$state',
templateUrl: '<%= asset_path "admin/subscriptions/expired_at_modal.html" %>',
size: 'lg',
controller: ['$scope', '$uibModalInstance', 'Subscription', function ($scope, $uibModalInstance, Subscription) {
$scope.new_expired_at = angular.copy(subscription.expired_at)
$scope.free = free
$scope.new_expired_at = angular.copy(subscription.expired_at);
$scope.free = free;
$scope.datePicker = {
opened: false,
format: Fablab.uibDateFormat,
@ -375,32 +375,32 @@ Application.Controllers.controller('EditMemberController', ['$scope', '$state',
startingDay: Fablab.weekStartingDay
},
minDate: new Date()
}
};
$scope.openDatePicker = function (ev) {
ev.preventDefault()
ev.stopPropagation()
return $scope.datePicker.opened = true
}
ev.preventDefault();
ev.stopPropagation();
return $scope.datePicker.opened = true;
};
$scope.ok = function () {
Subscription.update(
{ id: subscription.id },
{ subscription: { expired_at: $scope.new_expired_at, free } },
function (_subscription) {
growl.success(_t('you_successfully_changed_the_expiration_date_of_the_user_s_subscription'))
return $uibModalInstance.close(_subscription)
growl.success(_t('you_successfully_changed_the_expiration_date_of_the_user_s_subscription'));
return $uibModalInstance.close(_subscription);
},
function (error) { growl.error(_t('a_problem_occurred_while_saving_the_date')) }
)
}
function (error) { growl.error(_t('a_problem_occurred_while_saving_the_date')); }
);
};
$scope.cancel = function () { $uibModalInstance.dismiss('cancel') }
$scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
}]
})
});
// once the form was validated successfully ...
return modalInstance.result.then(function (subscription) { $scope.subscription.expired_at = subscription.expired_at })
}
return modalInstance.result.then(function (subscription) { $scope.subscription.expired_at = subscription.expired_at; });
};
/**
* Open a modal dialog allowing the admin to set a subscription for the given user.
@ -414,10 +414,10 @@ Application.Controllers.controller('EditMemberController', ['$scope', '$state',
size: 'lg',
controller: ['$scope', '$uibModalInstance', 'Subscription', 'Group', function ($scope, $uibModalInstance, Subscription, Group) {
// selected user
$scope.user = user
$scope.user = user;
// available plans for the selected user
$scope.plans = plans
$scope.plans = plans;
/**
* Generate a string identifying the given plan by literal human-readable name
@ -427,33 +427,33 @@ Application.Controllers.controller('EditMemberController', ['$scope', '$state',
* will be included.
* @returns {String}
*/
$scope.humanReadablePlanName = function (plan, groups, short) { return `${$filter('humanReadablePlanName')(plan, groups, short)}` }
$scope.humanReadablePlanName = function (plan, groups, short) { return `${$filter('humanReadablePlanName')(plan, groups, short)}`; };
/**
* Modal dialog validation callback
*/
$scope.ok = function () {
$scope.subscription.user_id = user.id
$scope.subscription.user_id = user.id;
return Subscription.save({ }, { subscription: $scope.subscription }, function (_subscription) {
growl.success(_t('subscription_successfully_purchased'))
$uibModalInstance.close(_subscription)
return $state.reload()
growl.success(_t('subscription_successfully_purchased'));
$uibModalInstance.close(_subscription);
return $state.reload();
}
, function (error) {
growl.error(_t('a_problem_occurred_while_taking_the_subscription'))
console.error(error)
})
}
growl.error(_t('a_problem_occurred_while_taking_the_subscription'));
console.error(error);
});
};
/**
* Modal dialog cancellation callback
*/
$scope.cancel = function () { $uibModalInstance.dismiss('cancel') }
$scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
}]
})
});
// once the form was validated succesfully ...
return modalInstance.result.then(function (subscription) { $scope.subscription = subscription })
}
return modalInstance.result.then(function (subscription) { $scope.subscription = subscription; });
};
$scope.createWalletCreditModal = function (user, wallet) {
const modalInstance = $uibModal.open({
@ -461,13 +461,13 @@ Application.Controllers.controller('EditMemberController', ['$scope', '$state',
templateUrl: '<%= asset_path "wallet/credit_modal.html" %>',
controller: ['$scope', '$uibModalInstance', 'Wallet', function ($scope, $uibModalInstance, Wallet) {
// default: do not generate a refund invoice
$scope.generate_avoir = false
$scope.generate_avoir = false;
// date of the generated refund invoice
$scope.avoir_date = null
$scope.avoir_date = null;
// optional description shown on the refund invoice
$scope.description = ''
$scope.description = '';
// default configuration for the avoir date selector widget
$scope.datePicker = {
@ -476,16 +476,16 @@ Application.Controllers.controller('EditMemberController', ['$scope', '$state',
options: {
startingDay: Fablab.weekStartingDay
}
}
};
/**
* Callback to open/close the date picker
*/
$scope.toggleDatePicker = function ($event) {
$event.preventDefault()
$event.stopPropagation()
return $scope.datePicker.opened = !$scope.datePicker.opened
}
$event.preventDefault();
$event.stopPropagation();
return $scope.datePicker.opened = !$scope.datePicker.opened;
};
/**
* Modal dialog validation callback
@ -500,33 +500,33 @@ Application.Controllers.controller('EditMemberController', ['$scope', '$state',
avoir_description: $scope.description
},
function (_wallet) {
growl.success(_t('wallet_credit_successfully'))
return $uibModalInstance.close(_wallet)
growl.success(_t('wallet_credit_successfully'));
return $uibModalInstance.close(_wallet);
},
function (error) {
growl.error(_t('a_problem_occurred_for_wallet_credit'))
console.error(error)
growl.error(_t('a_problem_occurred_for_wallet_credit'));
console.error(error);
}
)
}
);
};
/**
* Modal dialog cancellation callback
*/
$scope.cancel = function () { $uibModalInstance.dismiss('cancel') }
$scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
}
] })
] });
// once the form was validated succesfully ...
return modalInstance.result.then(function (wallet) {
$scope.wallet = wallet
return Wallet.transactions({ id: wallet.id }, function (transactions) { $scope.transactions = transactions })
})
}
$scope.wallet = wallet;
return Wallet.transactions({ id: wallet.id }, function (transactions) { $scope.transactions = transactions; });
});
};
/**
* To use as callback in Array.prototype.filter to get only enabled plans
*/
$scope.filterDisabledPlans = function (plan) { return !plan.disabled }
$scope.filterDisabledPlans = function (plan) { return !plan.disabled; };
/* PRIVATE SCOPE */
@ -534,83 +534,83 @@ Application.Controllers.controller('EditMemberController', ['$scope', '$state',
* Kind of constructor: these actions will be realized first when the controller is loaded
*/
const initialize = function () {
CSRF.setMetaTags()
CSRF.setMetaTags();
// init the birth date to JS object
$scope.user.profile.birthday = moment($scope.user.profile.birthday).toDate()
$scope.user.profile.birthday = moment($scope.user.profile.birthday).toDate();
// the user subscription
if (($scope.user.subscribed_plan != null) && ($scope.user.subscription != null)) {
$scope.subscription = $scope.user.subscription
$scope.subscription.expired_at = $scope.subscription.expired_at
$scope.subscription = $scope.user.subscription;
$scope.subscription.expired_at = $scope.subscription.expired_at;
} else {
Plan.query({ group_id: $scope.user.group_id }, function (plans) {
$scope.plans = plans
$scope.plans = plans;
return Array.from($scope.plans).map(function (plan) {
return (plan.nameToDisplay = `${plan.base_name} - ${plan.interval}`)
})
})
return (plan.nameToDisplay = `${plan.base_name} - ${plan.interval}`);
});
});
}
// Using the MembersController
return new MembersController($scope, $state, Group, Training)
}
return new MembersController($scope, $state, Group, Training);
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);
/**
* Controller used in the member's creation page (admin view)
*/
Application.Controllers.controller('NewMemberController', ['$scope', '$state', '$stateParams', 'Member', 'Training', 'Group', 'CSRF',
function ($scope, $state, $stateParams, Member, Training, Group, CSRF) {
CSRF.setMetaTags()
CSRF.setMetaTags();
/* PUBLIC SCOPE */
// API URL where the form will be posted
$scope.actionUrl = '/api/members'
$scope.actionUrl = '/api/members';
// Form action on the above URL
$scope.method = 'post'
$scope.method = 'post';
// Should the passord be set manually or generated?
$scope.password =
{ change: false }
{ change: false };
// Default member's profile parameters
$scope.user =
{ plan_interval: '' }
{ plan_interval: '' };
// Callback when the admin check/unckeck the box telling that the new user is an organization.
// Disable or enable the organization fields in the form, accordingly
$scope.toggleOrganization = function () {
if ($scope.user.organization) {
if (!$scope.user.profile) { $scope.user.profile = {} }
return $scope.user.profile.organization = {}
if (!$scope.user.profile) { $scope.user.profile = {}; }
return $scope.user.profile.organization = {};
} else {
return $scope.user.profile.organization = undefined
return $scope.user.profile.organization = undefined;
}
}
};
// Using the MembersController
return new MembersController($scope, $state, Group, Training)
return new MembersController($scope, $state, Group, Training);
}
])
]);
/**
* Controller used in the admin's creation page (admin view)
*/
Application.Controllers.controller('NewAdminController', ['$state', '$scope', 'Admin', 'growl', '_t', function ($state, $scope, Admin, growl, _t) {
// default admin profile
let getGender
let getGender;
$scope.admin = {
profile_attributes: {
gender: true
}
}
};
// Default parameters for AngularUI-Bootstrap datepicker
$scope.datePicker = {
@ -619,13 +619,13 @@ Application.Controllers.controller('NewAdminController', ['$state', '$scope', 'A
options: {
startingDay: Fablab.weekStartingDay
}
}
};
/**
* Shows the birth day datepicker
* @param $event {Object} jQuery event object
*/
$scope.openDatePicker = function ($event) { $scope.datePicker.opened = true }
$scope.openDatePicker = function ($event) { $scope.datePicker.opened = true; };
/**
* Send the new admin, currently stored in $scope.admin, to the server for database saving
@ -635,14 +635,14 @@ Application.Controllers.controller('NewAdminController', ['$state', '$scope', 'A
{},
{ admin: $scope.admin },
function () {
growl.success(_t('administrator_successfully_created_he_will_receive_his_connection_directives_by_email', { GENDER: getGender($scope.admin) }, 'messageformat'))
return $state.go('app.admin.members')
growl.success(_t('administrator_successfully_created_he_will_receive_his_connection_directives_by_email', { GENDER: getGender($scope.admin) }, 'messageformat'));
return $state.go('app.admin.members');
}
, function (error) {
console.log(error)
console.log(error);
}
)
}
);
};
/* PRIVATE SCOPE */
@ -653,9 +653,9 @@ Application.Controllers.controller('NewAdminController', ['$state', '$scope', 'A
*/
return getGender = function (user) {
if (user.profile_attributes) {
if (user.profile_attributes.gender) { return 'male' } else { return 'female' }
} else { return 'other' }
}
if (user.profile_attributes.gender) { return 'male'; } else { return 'female'; }
} else { return 'other'; }
};
}
])
]);

View File

@ -15,46 +15,46 @@ Application.Controllers.controller('OpenAPIClientsController', ['$scope', 'clien
/* PUBLIC SCOPE */
// clients list
$scope.clients = clientsPromise
$scope.order = null
$scope.clientFormVisible = false
$scope.client = {}
$scope.clients = clientsPromise;
$scope.order = null;
$scope.clientFormVisible = false;
$scope.client = {};
$scope.toggleForm = () => $scope.clientFormVisible = !$scope.clientFormVisible
$scope.toggleForm = () => $scope.clientFormVisible = !$scope.clientFormVisible;
// Change the order criterion to the one provided
// @param orderBy {string} ordering criterion
//
$scope.setOrder = function (orderBy) {
if ($scope.order === orderBy) {
return $scope.order = `-${orderBy}`
return $scope.order = `-${orderBy}`;
} else {
return $scope.order = orderBy
return $scope.order = orderBy;
}
}
};
$scope.saveClient = function (client) {
if (client.id != null) {
OpenAPIClient.update({ id: client.id }, { open_api_client: client }, function (clientResp) {
client = clientResp
return growl.success(_t('client_successfully_updated'))
})
client = clientResp;
return growl.success(_t('client_successfully_updated'));
});
} else {
OpenAPIClient.save({ open_api_client: client }, function (client) {
$scope.clients.push(client)
return growl.success(_t('client_successfully_created'))
})
$scope.clients.push(client);
return growl.success(_t('client_successfully_created'));
});
}
$scope.clientFormVisible = false
$scope.clientForm.$setPristine()
return $scope.client = {}
}
$scope.clientFormVisible = false;
$scope.clientForm.$setPristine();
return $scope.client = {};
};
$scope.editClient = function (client) {
$scope.clientFormVisible = true
return $scope.client = client
}
$scope.clientFormVisible = true;
return $scope.client = client;
};
$scope.deleteClient = index =>
dialogs.confirm({
@ -63,16 +63,16 @@ Application.Controllers.controller('OpenAPIClientsController', ['$scope', 'clien
return {
title: _t('confirmation_required'),
msg: _t('do_you_really_want_to_delete_this_open_api_client')
}
};
}
}
}
, () =>
OpenAPIClient.delete({ id: $scope.clients[index].id }, function () {
$scope.clients.splice(index, 1)
return growl.success(_t('client_successfully_deleted'))
$scope.clients.splice(index, 1);
return growl.success(_t('client_successfully_deleted'));
})
)
);
return $scope.resetToken = client =>
dialogs.confirm({
@ -81,16 +81,16 @@ Application.Controllers.controller('OpenAPIClientsController', ['$scope', 'clien
return {
title: _t('confirmation_required'),
msg: _t('do_you_really_want_to_revoke_this_open_api_access')
}
};
}
}
}
, () =>
OpenAPIClient.resetToken({ id: client.id }, {}, function (clientResp) {
client.token = clientResp.token
return growl.success(_t('access_successfully_revoked'))
client.token = clientResp.token;
return growl.success(_t('access_successfully_revoked'));
})
)
);
}
])
]);

View File

@ -16,23 +16,23 @@
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
/* COMMON CODE */
class PlanController {
constructor ($scope, groups, prices, partners, CSRF) {
// protection against request forgery
CSRF.setMetaTags()
CSRF.setMetaTags();
// groups list
$scope.groups = groups.filter(function (g) { return (g.slug !== 'admins') && !g.disabled })
$scope.groups = groups.filter(function (g) { return (g.slug !== 'admins') && !g.disabled; });
// users with role 'partner', notifiables for a partner plan
$scope.partners = partners.users
$scope.partners = partners.users;
// Subscriptions prices, machines prices and training prices, per groups
$scope.group_pricing = prices
$scope.group_pricing = prices;
/**
* For use with 'ng-class', returns the CSS class name for the uploads previews.
@ -41,11 +41,11 @@ class PlanController {
*/
$scope.fileinputClass = function (v) {
if (v) {
return 'fileinput-exists'
return 'fileinput-exists';
} else {
return 'fileinput-new'
return 'fileinput-new';
}
}
};
/**
* Mark the provided file for deletion
@ -53,9 +53,9 @@ class PlanController {
*/
$scope.deleteFile = function (file) {
if ((file != null) && (file.id != null)) {
return file._destroy = true
return file._destroy = true;
}
}
};
}
}
@ -67,13 +67,13 @@ Application.Controllers.controller('NewPlanController', ['$scope', '$uibModal',
/* PUBLIC SCOPE */
// current form is used to create a new plan
$scope.mode = 'creation'
$scope.mode = 'creation';
// prices bindings
$scope.prices = {
training: {},
machine: {}
}
};
// form inputs bindings
$scope.plan = {
@ -86,19 +86,19 @@ Application.Controllers.controller('NewPlanController', ['$scope', '$uibModal',
partnerId: null,
partnerContact: null,
ui_weight: 0
}
};
// API URL where the form will be posted
$scope.actionUrl = '/api/plans/'
$scope.actionUrl = '/api/plans/';
// HTTP method for the rest API
$scope.method = 'POST'
$scope.method = 'POST';
/**
* Checks if the partner contact is a valid data. Used in the form validation process
* @returns {boolean}
*/
$scope.partnerIsValid = function () { return ($scope.plan.type === 'Plan') || ($scope.plan.partnerId || ($scope.plan.partnerContact && $scope.plan.partnerContact.email)) }
$scope.partnerIsValid = function () { return ($scope.plan.type === 'Plan') || ($scope.plan.partnerId || ($scope.plan.partnerContact && $scope.plan.partnerContact.email)); };
/**
* Open a modal dialog allowing the admin to create a new partner user
@ -109,32 +109,32 @@ Application.Controllers.controller('NewPlanController', ['$scope', '$uibModal',
templateUrl: '<%= asset_path "shared/_partner_new_modal.html" %>',
size: 'lg',
controller: ['$scope', '$uibModalInstance', 'User', function ($scope, $uibModalInstance, User) {
$scope.partner = {}
$scope.partner = {};
$scope.ok = function () {
User.save(
{},
{ user: $scope.partner },
function (user) {
$scope.partner.id = user.id
$scope.partner.name = `${user.first_name} ${user.last_name}`
$uibModalInstance.close($scope.partner)
$scope.partner.id = user.id;
$scope.partner.name = `${user.first_name} ${user.last_name}`;
$uibModalInstance.close($scope.partner);
},
function (error) {
growl.error(_t('new_plan.unable_to_save_this_user_check_that_there_isnt_an_already_a_user_with_the_same_name'))
console.error(error)
growl.error(_t('new_plan.unable_to_save_this_user_check_that_there_isnt_an_already_a_user_with_the_same_name'));
console.error(error);
}
)
}
$scope.cancel = function () { $uibModalInstance.dismiss('cancel') }
);
};
$scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
}]
})
});
// once the form was validated successfully ...
return modalInstance.result.then(function (partner) {
$scope.partners.push(partner)
return $scope.plan.partnerId = partner.id
})
}
$scope.partners.push(partner);
return $scope.plan.partnerId = partner.id;
});
};
/**
* Display some messages and redirect the user, once the form was submitted, depending on the result status
@ -143,22 +143,22 @@ Application.Controllers.controller('NewPlanController', ['$scope', '$uibModal',
*/
$scope.afterSubmit = function (content) {
if ((content.id == null) && (content.plan_ids == null)) {
return growl.error(_t('new_plan.unable_to_create_the_subscription_please_try_again'))
return growl.error(_t('new_plan.unable_to_create_the_subscription_please_try_again'));
} else {
growl.success(_t('new_plan.successfully_created_subscription(s)_dont_forget_to_redefine_prices'))
growl.success(_t('new_plan.successfully_created_subscription(s)_dont_forget_to_redefine_prices'));
if (content.plan_ids != null) {
return $state.go('app.admin.pricing')
return $state.go('app.admin.pricing');
} else {
if (content.id != null) {
return $state.go('app.admin.plans.edit', { id: content.id })
return $state.go('app.admin.plans.edit', { id: content.id });
}
}
}
}
};
return new PlanController($scope, groups, prices, partners, CSRF)
return new PlanController($scope, groups, prices, partners, CSRF);
}
])
]);
/**
* Controller used in the plan edition form
@ -168,30 +168,30 @@ Application.Controllers.controller('EditPlanController', ['$scope', 'groups', 'p
/* PUBLIC SCOPE */
// List of spaces
$scope.spaces = spaces
$scope.spaces = spaces;
// List of plans
$scope.plans = plans
$scope.plans = plans;
// List of machines
$scope.machines = machines
$scope.machines = machines;
// List of groups
$scope.groups = groups
$scope.groups = groups;
// current form is used for edition mode
$scope.mode = 'edition'
$scope.mode = 'edition';
// edited plan data
$scope.plan = planPromise
if ($scope.plan.type === null) { $scope.plan.type = 'Plan' }
if ($scope.plan.disabled) { $scope.plan.disabled = 'true' }
$scope.plan = planPromise;
if ($scope.plan.type === null) { $scope.plan.type = 'Plan'; }
if ($scope.plan.disabled) { $scope.plan.disabled = 'true'; }
// API URL where the form will be posted
$scope.actionUrl = `/api/plans/${$stateParams.id}`
$scope.actionUrl = `/api/plans/${$stateParams.id}`;
// HTTP method for the rest API
$scope.method = 'PATCH'
$scope.method = 'PATCH';
/**
* If a parent plan was set ($scope.plan.parent), the prices will be copied from this parent plan into
@ -202,34 +202,34 @@ Application.Controllers.controller('EditPlanController', ['$scope', 'groups', 'p
return Plan.get({ id: $scope.plan.parent }, function (parentPlan) {
Array.from(parentPlan.prices).map(function (parentPrice) {
return (function () {
const result = []
const result = [];
for (let childKey in $scope.plan.prices) {
const childPrice = $scope.plan.prices[childKey]
const childPrice = $scope.plan.prices[childKey];
if ((childPrice.priceable_type === parentPrice.priceable_type) && (childPrice.priceable_id === parentPrice.priceable_id)) {
$scope.plan.prices[childKey].amount = parentPrice.amount
break
$scope.plan.prices[childKey].amount = parentPrice.amount;
break;
} else {
result.push(undefined)
result.push(undefined);
}
}
return result
})()
})
return result;
})();
});
}
)
);
// if no plan were selected, unset every prices
} else {
return (function () {
const result = []
const result = [];
for (let key in $scope.plan.prices) {
const price = $scope.plan.prices[key]
result.push($scope.plan.prices[key].amount = 0)
const price = $scope.plan.prices[key];
result.push($scope.plan.prices[key].amount = 0);
}
return result
})()
return result;
})();
}
}
};
/**
* Display some messages once the form was submitted, depending on the result status (failed/succeeded)
@ -237,12 +237,12 @@ Application.Controllers.controller('EditPlanController', ['$scope', 'groups', 'p
*/
$scope.afterSubmit = function (content) {
if ((content.id == null) && (content.plan_ids == null)) {
return growl.error(_t('edit_plan.unable_to_save_subscription_changes_please_try_again'))
return growl.error(_t('edit_plan.unable_to_save_subscription_changes_please_try_again'));
} else {
growl.success(_t('edit_plan.subscription_successfully_changed'))
return $state.go('app.admin.pricing')
growl.success(_t('edit_plan.subscription_successfully_changed'));
return $state.go('app.admin.pricing');
}
}
};
/**
* Generate a string identifying the given plan by literal humain-readable name
@ -252,7 +252,7 @@ Application.Controllers.controller('EditPlanController', ['$scope', 'groups', 'p
* will be included.
* @returns {String}
*/
$scope.humanReadablePlanName = function (plan, groups, short) { return `${$filter('humanReadablePlanName')(plan, groups, short)}` }
$scope.humanReadablePlanName = function (plan, groups, short) { return `${$filter('humanReadablePlanName')(plan, groups, short)}`; };
/**
* Retrieve the machine from its ID
@ -262,10 +262,10 @@ Application.Controllers.controller('EditPlanController', ['$scope', 'groups', 'p
$scope.getMachine = function (machine_id) {
for (let machine of Array.from($scope.machines)) {
if (machine.id === machine_id) {
return machine
return machine;
}
}
}
};
/**
* Retrieve the space from its ID
@ -275,12 +275,12 @@ Application.Controllers.controller('EditPlanController', ['$scope', 'groups', 'p
$scope.getSpace = function (space_id) {
for (let space of Array.from($scope.spaces)) {
if (space.id === space_id) {
return space
return space;
}
}
}
};
// Using the PlansController
return new PlanController($scope, groups, prices, partners, CSRF)
return new PlanController($scope, groups, prices, partners, CSRF);
}
])
]);

View File

@ -9,7 +9,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
/**
* Controller used in price category creation/edition form dialog
@ -17,16 +17,16 @@
Application.Controllers.controller('PriceCategoryController', ['$scope', '$uibModalInstance', 'category',
function ($scope, $uibModalInstance, category) {
// Price category to edit/empty object for new category
$scope.category = category
$scope.category = category;
/**
* Callback for form validation
*/
$scope.ok = () => $uibModalInstance.close($scope.category)
$scope.ok = () => $uibModalInstance.close($scope.category);
/**
* Do not validate the modifications, hide the modal
*/
return $scope.cancel = () => $uibModalInstance.dismiss('cancel')
return $scope.cancel = () => $uibModalInstance.dismiss('cancel');
}
])
]);

View File

@ -13,7 +13,7 @@
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
/**
* Controller used in the prices edition page
@ -22,80 +22,80 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
function ($scope, $state, $uibModal, $filter, TrainingsPricing, Credit, Pricing, Plan, Coupon, plans, groups, growl, machinesPricesPromise, Price, dialogs, trainingsPricingsPromise, trainingsPromise, machineCreditsPromise, machinesPromise, trainingCreditsPromise, couponsPromise, spacesPromise, spacesPricesPromise, spacesCreditsPromise, _t) {
/* PUBLIC SCOPE */
// List of machines prices (not considering any plan)
$scope.machinesPrices = machinesPricesPromise
$scope.machinesPrices = machinesPricesPromise;
// List of trainings pricing
$scope.trainingsPricings = trainingsPricingsPromise
$scope.trainingsPricings = trainingsPricingsPromise;
// List of available subscriptions plans (eg. student/month, PME/year ...)
$scope.plans = plans
$scope.enabledPlans = plans.filter(function (p) { return !p.disabled })
$scope.plans = plans;
$scope.enabledPlans = plans.filter(function (p) { return !p.disabled; });
// List of groups (eg. normal, student ...)
$scope.groups = groups.filter(function (g) { return g.slug !== 'admins' })
$scope.enabledGroups = groups.filter(function (g) { return (g.slug !== 'admins') && !g.disabled })
$scope.groups = groups.filter(function (g) { return g.slug !== 'admins'; });
$scope.enabledGroups = groups.filter(function (g) { return (g.slug !== 'admins') && !g.disabled; });
// Associate free machine hours with subscriptions
$scope.machineCredits = machineCreditsPromise
$scope.machineCredits = machineCreditsPromise;
// Array of associations (plan <-> training)
$scope.trainingCredits = trainingCreditsPromise
$scope.trainingCredits = trainingCreditsPromise;
// Associate a plan with all its trainings ids
$scope.trainingCreditsGroups = {}
$scope.trainingCreditsGroups = {};
// List of trainings
$scope.trainings = trainingsPromise.filter(function (t) { return !t.disabled })
$scope.trainings = trainingsPromise.filter(function (t) { return !t.disabled; });
// List of machines
$scope.machines = machinesPromise
$scope.enabledMachines = machinesPromise.filter(function (m) { return !m.disabled })
$scope.machines = machinesPromise;
$scope.enabledMachines = machinesPromise.filter(function (m) { return !m.disabled; });
// List of coupons
$scope.coupons = couponsPromise
$scope.coupons = couponsPromise;
// List of spaces
$scope.spaces = spacesPromise
$scope.enabledSpaces = spacesPromise.filter(function (s) { return !s.disabled })
$scope.spaces = spacesPromise;
$scope.enabledSpaces = spacesPromise.filter(function (s) { return !s.disabled; });
// Associate free space hours with subscriptions
$scope.spaceCredits = spacesCreditsPromise
$scope.spaceCredits = spacesCreditsPromise;
// List of spaces prices (not considering any plan)
$scope.spacesPrices = spacesPricesPromise
$scope.spacesPrices = spacesPricesPromise;
// The plans list ordering. Default: by group
$scope.orderPlans = 'group_id'
$scope.orderPlans = 'group_id';
// Status of the drop-down menu in Credits tab
$scope.status =
{ isopen: false }
{ isopen: false };
// Default: we show only enabled plans
$scope.planFiltering = 'enabled'
$scope.planFiltering = 'enabled';
// Available options for filtering plans by status
$scope.filterDisabled = [
'enabled',
'disabled',
'all'
]
];
$scope.findTrainingsPricing = function (trainingsPricings, trainingId, groupId) {
for (let trainingsPricing of Array.from(trainingsPricings)) {
if ((trainingsPricing.training_id === trainingId) && (trainingsPricing.group_id === groupId)) {
return trainingsPricing
return trainingsPricing;
}
}
}
};
$scope.updateTrainingsPricing = function (data, trainingsPricing) {
if (data != null) {
return TrainingsPricing.update({ id: trainingsPricing.id }, { trainings_pricing: { amount: data } }).$promise
return TrainingsPricing.update({ id: trainingsPricing.id }, { trainings_pricing: { amount: data } }).$promise;
} else {
return _t('pricing.please_specify_a_number')
return _t('pricing.please_specify_a_number');
}
}
};
/**
* Retrieve a plan from its given identifier and returns it
@ -105,10 +105,10 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
$scope.getPlanFromId = function (id) {
for (let plan of Array.from($scope.plans)) {
if (plan.id === parseInt(id)) {
return plan
return plan;
}
}
}
};
/**
* Retrieve a group from its given identifier and returns it
@ -118,10 +118,10 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
$scope.getGroupFromId = function (groups, id) {
for (let group of Array.from(groups)) {
if (group.id === parseInt(id)) {
return group
return group;
}
}
}
};
/**
* Returns a human readable string of named trainings, according to the provided array.
@ -131,17 +131,17 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
*/
$scope.showTrainings = function (trainings) {
if (!angular.isArray(trainings) || !(trainings.length > 0)) {
return _t('pricing.none')
return _t('pricing.none');
}
const selected = []
const selected = [];
angular.forEach($scope.trainings, function (t) {
if (trainings.indexOf(t.id) >= 0) {
return selected.push(t.name)
return selected.push(t.name);
}
})
if (selected.length) { return selected.join(' | ') } else { return _t('pricing.none') }
}
});
if (selected.length) { return selected.join(' | '); } else { return _t('pricing.none'); }
};
/**
* Validation callback when editing training's credits. Save the changes.
@ -155,10 +155,10 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
{ training_credit_nb: newdata.training_credits }
, angular.noop() // do nothing in case of success
, function (error) {
growl.error(_t('pricing.an_error_occurred_while_saving_the_number_of_credits'))
console.error(error)
growl.error(_t('pricing.an_error_occurred_while_saving_the_number_of_credits'));
console.error(error);
}
)
);
// save the associated trainings
return angular.forEach($scope.trainingCreditsGroups, function (original, key) {
@ -167,22 +167,22 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
// iterate through the previous credits to remove
angular.forEach(original, function (oldTrainingId) {
if (newdata.training_ids.indexOf(oldTrainingId) === -1) {
const tc = findTrainingCredit(oldTrainingId, planId)
const tc = findTrainingCredit(oldTrainingId, planId);
if (tc) {
return tc.$delete({}
, function () {
$scope.trainingCredits.splice($scope.trainingCredits.indexOf(tc), 1)
return $scope.trainingCreditsGroups[planId].splice($scope.trainingCreditsGroups[planId].indexOf(tc.id), 1)
$scope.trainingCredits.splice($scope.trainingCredits.indexOf(tc), 1);
return $scope.trainingCreditsGroups[planId].splice($scope.trainingCreditsGroups[planId].indexOf(tc.id), 1);
}
, function (error) {
growl.error(_t('pricing.an_error_occurred_while_deleting_credit_with_the_TRAINING', { TRAINING: tc.creditable.name }))
console.error(error)
})
growl.error(_t('pricing.an_error_occurred_while_deleting_credit_with_the_TRAINING', { TRAINING: tc.creditable.name }));
console.error(error);
});
} else {
return growl.error(_t('pricing.an_error_occurred_unable_to_find_the_credit_to_revoke'))
return growl.error(_t('pricing.an_error_occurred_unable_to_find_the_credit_to_revoke'));
}
}
})
});
// iterate through the new credits to add
return angular.forEach(newdata.training_ids, function (newTrainingId) {
@ -195,39 +195,39 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
}
}
, function (newTc) { // success
$scope.trainingCredits.push(newTc)
return $scope.trainingCreditsGroups[newTc.plan_id].push(newTc.creditable_id)
$scope.trainingCredits.push(newTc);
return $scope.trainingCreditsGroups[newTc.plan_id].push(newTc.creditable_id);
}
, function (error) { // failed
const training = getTrainingFromId(newTrainingId)
growl.error(_t('pricing.an_error_occurred_while_creating_credit_with_the_TRAINING', { TRAINING: training.name }))
return console.error(error)
})
const training = getTrainingFromId(newTrainingId);
growl.error(_t('pricing.an_error_occurred_while_creating_credit_with_the_TRAINING', { TRAINING: training.name }));
return console.error(error);
});
}
})
});
}
}
})
}
});
};
/**
* Cancel the current training credit modification
* @param rowform {Object} see http://vitalets.github.io/angular-xeditable/
*/
$scope.cancelTrainingCredit = function (rowform) { rowform.$cancel() }
$scope.cancelTrainingCredit = function (rowform) { rowform.$cancel(); };
/**
* Create a new empty entry in the $scope.machineCredits array
* @param e {Object} see https://docs.angularjs.org/guide/expression#-event-
*/
$scope.addMachineCredit = function (e) {
e.preventDefault()
e.stopPropagation()
e.preventDefault();
e.stopPropagation();
$scope.inserted =
{ creditable_type: 'Machine' }
$scope.machineCredits.push($scope.inserted)
return $scope.status.isopen = !$scope.status.isopen
}
{ creditable_type: 'Machine' };
$scope.machineCredits.push($scope.inserted);
return $scope.status.isopen = !$scope.status.isopen;
};
/**
* In the Credits tab, return the name of the machine/space associated with the given credit
@ -235,16 +235,16 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
* @returns {String}
*/
$scope.showCreditableName = function (credit) {
let selected = _t('pricing.not_set')
let selected = _t('pricing.not_set');
if (credit && credit.creditable_id) {
const object = $scope.getCreditable(credit)
selected = object.name
const object = $scope.getCreditable(credit);
selected = object.name;
if (credit.creditable_type === 'Machine') {
selected += ` ( id. ${object.id} )`
selected += ` ( id. ${object.id} )`;
}
}
return selected
}
return selected;
};
/**
* In the Credits tab, return the machine/space associated with the given credit
@ -252,24 +252,24 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
* @returns {Object}
*/
$scope.getCreditable = function (credit) {
let selected
let selected;
if (credit && credit.creditable_id) {
if (credit.creditable_type === 'Machine') {
angular.forEach($scope.machines, function (m) {
if (m.id === credit.creditable_id) {
return selected = m
return selected = m;
}
})
});
} else if (credit.creditable_type === 'Space') {
angular.forEach($scope.spaces, function (s) {
if (s.id === credit.creditable_id) {
return selected = s
return selected = s;
}
})
});
}
}
return selected
}
return selected;
};
/**
* Validation callback when editing machine's credits. Save the changes.
@ -280,31 +280,31 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
$scope.saveMachineCredit = function (data, id) {
for (let mc of Array.from($scope.machineCredits)) {
if ((mc.plan_id === data.plan_id) && (mc.creditable_id === data.creditable_id) && ((id === null) || (mc.id !== id))) {
growl.error(_t('pricing.error_a_credit_linking_this_machine_with_that_subscription_already_exists'))
growl.error(_t('pricing.error_a_credit_linking_this_machine_with_that_subscription_already_exists'));
if (!id) {
$scope.machineCredits.pop()
$scope.machineCredits.pop();
}
return false
return false;
}
}
if (id != null) {
return Credit.update({ id }, { credit: data }, function () { growl.success(_t('pricing.changes_have_been_successfully_saved')) })
return Credit.update({ id }, { credit: data }, function () { growl.success(_t('pricing.changes_have_been_successfully_saved')); });
} else {
data.creditable_type = 'Machine'
data.creditable_type = 'Machine';
return Credit.save(
{ credit: data }
, function (resp) {
$scope.machineCredits[$scope.machineCredits.length - 1].id = resp.id
return growl.success(_t('pricing.credit_was_successfully_saved'))
$scope.machineCredits[$scope.machineCredits.length - 1].id = resp.id;
return growl.success(_t('pricing.credit_was_successfully_saved'));
}
, function (err) {
$scope.machineCredits.pop()
growl.error(_t('pricing.error_creating_credit'))
console.error(err)
})
$scope.machineCredits.pop();
growl.error(_t('pricing.error_creating_credit'));
console.error(err);
});
}
}
};
/**
* Removes the newly inserted but not saved machine credit / Cancel the current machine credit modification
@ -313,33 +313,33 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
*/
$scope.cancelMachineCredit = function (rowform, index) {
if ($scope.machineCredits[index].id != null) {
return rowform.$cancel()
return rowform.$cancel();
} else {
return $scope.machineCredits.splice(index, 1)
return $scope.machineCredits.splice(index, 1);
}
}
};
/**
* Deletes the machine credit at the specified index
* @param index {number} machine credit index in the $scope.machineCredits array
*/
$scope.removeMachineCredit = function (index) {
Credit.delete($scope.machineCredits[index])
$scope.machineCredits.splice(index, 1)
}
Credit.delete($scope.machineCredits[index]);
$scope.machineCredits.splice(index, 1);
};
/**
* Create a new empty entry in the $scope.spaceCredits array
* @param e {Object} see https://docs.angularjs.org/guide/expression#-event-
*/
$scope.addSpaceCredit = function (e) {
e.preventDefault()
e.stopPropagation()
e.preventDefault();
e.stopPropagation();
$scope.inserted =
{ creditable_type: 'Space' }
$scope.spaceCredits.push($scope.inserted)
$scope.status.isopen = !$scope.status.isopen
}
{ creditable_type: 'Space' };
$scope.spaceCredits.push($scope.inserted);
$scope.status.isopen = !$scope.status.isopen;
};
/**
* Validation callback when editing space's credits. Save the changes.
@ -350,30 +350,30 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
$scope.saveSpaceCredit = function (data, id) {
for (let sc of Array.from($scope.spaceCredits)) {
if ((sc.plan_id === data.plan_id) && (sc.creditable_id === data.creditable_id) && ((id === null) || (sc.id !== id))) {
growl.error(_t('pricing.error_a_credit_linking_this_space_with_that_subscription_already_exists'))
growl.error(_t('pricing.error_a_credit_linking_this_space_with_that_subscription_already_exists'));
if (!id) {
$scope.spaceCredits.pop()
$scope.spaceCredits.pop();
}
return false
return false;
}
}
if (id != null) {
return Credit.update({ id }, { credit: data }, function () { growl.success(_t('pricing.changes_have_been_successfully_saved')) })
return Credit.update({ id }, { credit: data }, function () { growl.success(_t('pricing.changes_have_been_successfully_saved')); });
} else {
data.creditable_type = 'Space'
data.creditable_type = 'Space';
return Credit.save(
{ credit: data }
, function (resp) {
$scope.spaceCredits[$scope.spaceCredits.length - 1].id = resp.id
return growl.success(_t('pricing.credit_was_successfully_saved'))
$scope.spaceCredits[$scope.spaceCredits.length - 1].id = resp.id;
return growl.success(_t('pricing.credit_was_successfully_saved'));
}
, function (err) {
$scope.spaceCredits.pop()
return growl.error(_t('pricing.error_creating_credit'))
})
$scope.spaceCredits.pop();
return growl.error(_t('pricing.error_creating_credit'));
});
}
}
};
/**
* Removes the newly inserted but not saved space credit / Cancel the current space credit modification
@ -382,20 +382,20 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
*/
$scope.cancelSpaceCredit = function (rowform, index) {
if ($scope.spaceCredits[index].id != null) {
return rowform.$cancel()
return rowform.$cancel();
} else {
return $scope.spaceCredits.splice(index, 1)
return $scope.spaceCredits.splice(index, 1);
}
}
};
/**
* Deletes the space credit at the specified index
* @param index {number} space credit index in the $scope.spaceCredits array
*/
$scope.removeSpaceCredit = function (index) {
Credit.delete($scope.spaceCredits[index])
return $scope.spaceCredits.splice(index, 1)
}
Credit.delete($scope.spaceCredits[index]);
return $scope.spaceCredits.splice(index, 1);
};
/**
* If the plan does not have a type, return a default value for display purposes
@ -404,9 +404,9 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
*/
$scope.getPlanType = function (type) {
if (type === 'PartnerPlan') {
return _t('pricing.partner')
} else { return _t('pricing.standard') }
}
return _t('pricing.partner');
} else { return _t('pricing.standard'); }
};
/**
* Change the plans ordering criterion to the one provided
@ -414,11 +414,11 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
*/
$scope.setOrderPlans = function (orderBy) {
if ($scope.orderPlans === orderBy) {
return $scope.orderPlans = `-${orderBy}`
return $scope.orderPlans = `-${orderBy}`;
} else {
return $scope.orderPlans = orderBy
return $scope.orderPlans = orderBy;
}
}
};
/**
* Retrieve a price from prices array by a machineId and a groupId
@ -426,21 +426,21 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
$scope.findPriceBy = function (prices, machineId, groupId) {
for (let price of Array.from(prices)) {
if ((price.priceable_id === machineId) && (price.group_id === groupId)) {
return price
return price;
}
}
}
};
/**
* update a price for a machine and a group, not considering any plan
*/
$scope.updatePrice = function (data, price) {
if (data != null) {
return Price.update({ id: price.id }, { price: { amount: data } }).$promise
return Price.update({ id: price.id }, { price: { amount: data } }).$promise;
} else {
return _t('pricing.please_specify_a_number')
return _t('pricing.please_specify_a_number');
}
}
};
/**
* Delete the specified subcription plan
@ -448,7 +448,7 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
*/
$scope.deletePlan = function (plans, id) {
if (typeof id !== 'number') {
return console.error('[EditPricingController::deletePlan] Error: invalid id parameter')
return console.error('[EditPricingController::deletePlan] Error: invalid id parameter');
} else {
// open a confirmation dialog
return dialogs.confirm(
@ -458,7 +458,7 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
return {
title: _t('pricing.confirmation_required'),
msg: _t('pricing.do_you_really_want_to_delete_this_subscription_plan')
}
};
}
}
},
@ -467,18 +467,18 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
Plan.delete(
{ id },
function (res) {
growl.success(_t('pricing.subscription_plan_was_successfully_deleted'))
return $scope.plans.splice(findItemIdxById(plans, id), 1)
growl.success(_t('pricing.subscription_plan_was_successfully_deleted'));
return $scope.plans.splice(findItemIdxById(plans, id), 1);
},
function (error) {
if (error.statusText) { console.error(`[EditPricingController::deletePlan] Error: ${error.statusText}`) }
growl.error(_t('pricing.unable_to_delete_the_specified_subscription_an_error_occurred'))
if (error.statusText) { console.error(`[EditPricingController::deletePlan] Error: ${error.statusText}`); }
growl.error(_t('pricing.unable_to_delete_the_specified_subscription_an_error_occurred'));
}
)
);
}
)
);
}
}
};
/**
* Generate a string identifying the given plan by literal humain-readable name
@ -488,7 +488,7 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
* will be included.
* @returns {String}
*/
$scope.humanReadablePlanName = function (plan, groups, short) { return `${$filter('humanReadablePlanName')(plan, groups, short)}` }
$scope.humanReadablePlanName = function (plan, groups, short) { return `${$filter('humanReadablePlanName')(plan, groups, short)}`; };
/**
* Delete a coupon from the server's database and, in case of success, from the list in memory
@ -497,7 +497,7 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
*/
$scope.deleteCoupon = function (coupons, id) {
if (typeof id !== 'number') {
return console.error('[EditPricingController::deleteCoupon] Error: invalid id parameter')
return console.error('[EditPricingController::deleteCoupon] Error: invalid id parameter');
} else {
// open a confirmation dialog
return dialogs.confirm({
@ -506,28 +506,28 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
return {
title: _t('pricing.confirmation_required'),
msg: _t('pricing.do_you_really_want_to_delete_this_coupon')
}
};
}
}
}
, function () {
// the admin has confirmed, delete the coupon
Coupon.delete({ id }, function (res) {
growl.success(_t('coupon_was_successfully_deleted'))
return $scope.coupons.splice(findItemIdxById(coupons, id), 1)
growl.success(_t('coupon_was_successfully_deleted'));
return $scope.coupons.splice(findItemIdxById(coupons, id), 1);
}
, function (error) {
if (error.statusText) { console.error(`[EditPricingController::deleteCoupon] Error: ${error.statusText}`) }
if (error.statusText) { console.error(`[EditPricingController::deleteCoupon] Error: ${error.statusText}`); }
if (error.status === 422) {
return growl.error(_t('pricing.unable_to_delete_the_specified_coupon_already_in_use'))
return growl.error(_t('pricing.unable_to_delete_the_specified_coupon_already_in_use'));
} else {
return growl.error(_t('pricing.unable_to_delete_the_specified_coupon_an_unexpected_error_occurred'))
return growl.error(_t('pricing.unable_to_delete_the_specified_coupon_an_unexpected_error_occurred'));
}
})
})
});
});
}
}
};
/**
* Open a modal allowing to select an user and send him the details of the provided coupon
@ -537,33 +537,33 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
$uibModal.open({
templateUrl: '<%= asset_path "admin/pricing/sendCoupon.html" %>',
resolve: {
coupon () { return coupon }
coupon () { return coupon; }
},
size: 'md',
controller: ['$scope', '$uibModalInstance', 'Coupon', 'coupon', '_t', function ($scope, $uibModalInstance, Coupon, coupon, _t) {
// Member, receiver of the coupon
$scope.ctrl =
{ member: null }
{ member: null };
// Details of the coupon to send
$scope.coupon = coupon
$scope.coupon = coupon;
// Callback to validate sending of the coupon
$scope.ok = function () {
Coupon.send({ coupon_code: coupon.code, user_id: $scope.ctrl.member.id }, function (res) {
growl.success(_t('pricing.coupon_successfully_sent_to_USER', { USER: $scope.ctrl.member.name }))
return $uibModalInstance.close({ user_id: $scope.ctrl.member.id })
growl.success(_t('pricing.coupon_successfully_sent_to_USER', { USER: $scope.ctrl.member.name }));
return $uibModalInstance.close({ user_id: $scope.ctrl.member.id });
}
, function (err) {
growl.error(_t('pricing.an_error_occurred_unable_to_send_the_coupon'))
console.error(err)
})
}
growl.error(_t('pricing.an_error_occurred_unable_to_send_the_coupon'));
console.error(err);
});
};
// Callback to close the modal and cancel the sending process
$scope.cancel = function () { $uibModalInstance.dismiss('cancel') }
$scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
}]
})
}
});
};
/* PRIVATE SCOPE */
@ -571,21 +571,21 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
* Kind of constructor: these actions will be realized first when the controller is loaded
*/
const initialize = function () {
$scope.trainingCreditsGroups = groupCreditsByPlan($scope.trainingCredits)
$scope.trainingCreditsGroups = groupCreditsByPlan($scope.trainingCredits);
// adds empty array for plan which hasn't any credits yet
return (function () {
const result = []
const result = [];
for (let plan of Array.from($scope.plans)) {
if ($scope.trainingCreditsGroups[plan.id] == null) {
result.push($scope.trainingCreditsGroups[plan.id] = [])
result.push($scope.trainingCreditsGroups[plan.id] = []);
} else {
result.push(undefined)
result.push(undefined);
}
}
return result
})()
}
return result;
})();
};
/**
* Retrieve an item index by its ID from the given array of objects
@ -594,23 +594,23 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
* @returns {number} item index in the provided array
*/
var findItemIdxById = function (items, id) {
return (items.map(function (item) { return item.id })).indexOf(id)
}
return (items.map(function (item) { return item.id; })).indexOf(id);
};
/**
* Group the given credits array into a map associating the plan ID with its associated trainings/machines
* @return {Object} the association map
*/
var groupCreditsByPlan = function (credits) {
const creditsMap = {}
const creditsMap = {};
angular.forEach(credits, function (c) {
if (!creditsMap[c.plan_id]) {
creditsMap[c.plan_id] = []
creditsMap[c.plan_id] = [];
}
return creditsMap[c.plan_id].push(c.creditable_id)
})
return creditsMap
}
return creditsMap[c.plan_id].push(c.creditable_id);
});
return creditsMap;
};
/**
* Iterate through $scope.traininfCredits to find the credit matching the given criterion
@ -618,15 +618,15 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
* @param planId {number|string} plan ID
*/
var findTrainingCredit = function (trainingId, planId) {
trainingId = parseInt(trainingId)
planId = parseInt(planId)
trainingId = parseInt(trainingId);
planId = parseInt(planId);
for (let credit of Array.from($scope.trainingCredits)) {
if ((credit.plan_id === planId) && (credit.creditable_id === trainingId)) {
return credit
return credit;
}
}
}
};
/**
* Retrieve a training from its given identifier and returns it
@ -636,12 +636,12 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
var getTrainingFromId = function (id) {
for (let training of Array.from($scope.trainings)) {
if (training.id === parseInt(id)) {
return training
return training;
}
}
}
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);

View File

@ -10,18 +10,18 @@
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Controllers.controller('ProjectElementsController', ['$scope', '$state', 'Component', 'Licence', 'Theme', 'componentsPromise', 'licencesPromise', 'themesPromise',
function ($scope, $state, Component, Licence, Theme, componentsPromise, licencesPromise, themesPromise) {
// Materials list (plastic, wood ...)
$scope.components = componentsPromise
$scope.components = componentsPromise;
// Licences list (Creative Common ...)
$scope.licences = licencesPromise
$scope.licences = licencesPromise;
// Themes list (cooking, sport ...)
$scope.themes = themesPromise
$scope.themes = themesPromise;
/**
* Saves a new component / Update an existing material to the server (form validation callback)
@ -30,29 +30,29 @@ Application.Controllers.controller('ProjectElementsController', ['$scope', '$sta
*/
$scope.saveComponent = function (data, id) {
if (id != null) {
return Component.update({ id }, data)
return Component.update({ id }, data);
} else {
return Component.save(data, resp => $scope.components[$scope.components.length - 1].id = resp.id)
return Component.save(data, resp => $scope.components[$scope.components.length - 1].id = resp.id);
}
}
};
/**
* Deletes the component at the specified index
* @param index {number} component index in the $scope.components array
*/
$scope.removeComponent = function (index) {
Component.delete($scope.components[index])
return $scope.components.splice(index, 1)
}
Component.delete($scope.components[index]);
return $scope.components.splice(index, 1);
};
/**
* Creates a new empty entry in the $scope.components array
*/
$scope.addComponent = function () {
$scope.inserted =
{ name: '' }
return $scope.components.push($scope.inserted)
}
{ name: '' };
return $scope.components.push($scope.inserted);
};
/**
* Removes the newly inserted but not saved component / Cancel the current component modification
@ -61,11 +61,11 @@ Application.Controllers.controller('ProjectElementsController', ['$scope', '$sta
*/
$scope.cancelComponent = function (rowform, index) {
if ($scope.components[index].id != null) {
return rowform.$cancel()
return rowform.$cancel();
} else {
return $scope.components.splice(index, 1)
return $scope.components.splice(index, 1);
}
}
};
/**
* Saves a new theme / Update an existing theme to the server (form validation callback)
@ -74,29 +74,29 @@ Application.Controllers.controller('ProjectElementsController', ['$scope', '$sta
*/
$scope.saveTheme = function (data, id) {
if (id != null) {
return Theme.update({ id }, data)
return Theme.update({ id }, data);
} else {
return Theme.save(data, resp => $scope.themes[$scope.themes.length - 1].id = resp.id)
return Theme.save(data, resp => $scope.themes[$scope.themes.length - 1].id = resp.id);
}
}
};
/**
* Deletes the theme at the specified index
* @param index {number} theme index in the $scope.themes array
*/
$scope.removeTheme = function (index) {
Theme.delete($scope.themes[index])
return $scope.themes.splice(index, 1)
}
Theme.delete($scope.themes[index]);
return $scope.themes.splice(index, 1);
};
/**
* Creates a new empty entry in the $scope.themes array
*/
$scope.addTheme = function () {
$scope.inserted =
{ name: '' }
return $scope.themes.push($scope.inserted)
}
{ name: '' };
return $scope.themes.push($scope.inserted);
};
/**
* Removes the newly inserted but not saved theme / Cancel the current theme modification
@ -105,11 +105,11 @@ Application.Controllers.controller('ProjectElementsController', ['$scope', '$sta
*/
$scope.cancelTheme = function (rowform, index) {
if ($scope.themes[index].id != null) {
return rowform.$cancel()
return rowform.$cancel();
} else {
return $scope.themes.splice(index, 1)
return $scope.themes.splice(index, 1);
}
}
};
/**
* Saves a new licence / Update an existing licence to the server (form validation callback)
@ -118,20 +118,20 @@ Application.Controllers.controller('ProjectElementsController', ['$scope', '$sta
*/
$scope.saveLicence = function (data, id) {
if (id != null) {
return Licence.update({ id }, data)
return Licence.update({ id }, data);
} else {
return Licence.save(data, resp => $scope.licences[$scope.licences.length - 1].id = resp.id)
return Licence.save(data, resp => $scope.licences[$scope.licences.length - 1].id = resp.id);
}
}
};
/**
* Deletes the licence at the specified index
* @param index {number} licence index in the $scope.licences array
*/
$scope.removeLicence = function (index) {
Licence.delete($scope.licences[index])
return $scope.licences.splice(index, 1)
}
Licence.delete($scope.licences[index]);
return $scope.licences.splice(index, 1);
};
/**
* Creates a new empty entry in the $scope.licences array
@ -140,9 +140,9 @@ Application.Controllers.controller('ProjectElementsController', ['$scope', '$sta
$scope.inserted = {
name: '',
description: ''
}
return $scope.licences.push($scope.inserted)
}
};
return $scope.licences.push($scope.inserted);
};
/**
* Removes the newly inserted but not saved licence / Cancel the current licence modification
@ -151,10 +151,10 @@ Application.Controllers.controller('ProjectElementsController', ['$scope', '$sta
*/
return $scope.cancelLicence = function (rowform, index) {
if ($scope.licences[index].id != null) {
return rowform.$cancel()
return rowform.$cancel();
} else {
return $scope.licences.splice(index, 1)
return $scope.licences.splice(index, 1);
}
}
};
}
])
]);

View File

@ -10,7 +10,7 @@
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Controllers.controller('SettingsController', ['$scope', 'Setting', 'growl', 'settingsPromise', 'cgvFile', 'cguFile', 'logoFile', 'logoBlackFile', 'faviconFile', 'profileImageFile', 'CSRF', '_t',
function ($scope, Setting, growl, settingsPromise, cgvFile, cguFile, logoFile, logoBlackFile, faviconFile, profileImageFile, CSRF, _t) {
@ -20,7 +20,7 @@ Application.Controllers.controller('SettingsController', ['$scope', 'Setting', '
$scope.timepicker = {
hstep: 1,
mstep: 15
}
};
// API URL where the upload forms will be posted
$scope.actionUrl = {
@ -30,7 +30,7 @@ Application.Controllers.controller('SettingsController', ['$scope', 'Setting', '
logoBlack: '/api/custom_assets',
favicon: '/api/custom_assets',
profileImage: '/api/custom_assets'
}
};
// Form actions on the above URL
$scope.methods = {
@ -40,84 +40,84 @@ Application.Controllers.controller('SettingsController', ['$scope', 'Setting', '
logoBlack: 'post',
favicon: 'post',
profileImage: 'post'
}
};
// Are we uploading the files currently (if so, display the loader)
$scope.loader = {
cgu: false,
cgv: false
}
};
// various parametrable settings
$scope.twitterSetting = { name: 'twitter_name', value: settingsPromise.twitter_name }
$scope.aboutTitleSetting = { name: 'about_title', value: settingsPromise.about_title }
$scope.aboutBodySetting = { name: 'about_body', value: settingsPromise.about_body }
$scope.aboutContactsSetting = { name: 'about_contacts', value: settingsPromise.about_contacts }
$scope.homeBlogpostSetting = { name: 'home_blogpost', value: settingsPromise.home_blogpost }
$scope.machineExplicationsAlert = { name: 'machine_explications_alert', value: settingsPromise.machine_explications_alert }
$scope.trainingExplicationsAlert = { name: 'training_explications_alert', value: settingsPromise.training_explications_alert }
$scope.trainingInformationMessage = { name: 'training_information_message', value: settingsPromise.training_information_message }
$scope.subscriptionExplicationsAlert = { name: 'subscription_explications_alert', value: settingsPromise.subscription_explications_alert }
$scope.eventExplicationsAlert = { name: 'event_explications_alert', value: settingsPromise.event_explications_alert }
$scope.spaceExplicationsAlert = { name: 'space_explications_alert', value: settingsPromise.space_explications_alert }
$scope.windowStart = { name: 'booking_window_start', value: settingsPromise.booking_window_start }
$scope.windowEnd = { name: 'booking_window_end', value: settingsPromise.booking_window_end }
$scope.mainColorSetting = { name: 'main_color', value: settingsPromise.main_color }
$scope.secondColorSetting = { name: 'secondary_color', value: settingsPromise.secondary_color }
$scope.fablabName = { name: 'fablab_name', value: settingsPromise.fablab_name }
$scope.nameGenre = { name: 'name_genre', value: settingsPromise.name_genre }
$scope.machinesSortBy = { name: 'machines_sort_by', value: settingsPromise.machines_sort_by }
$scope.cguFile = cguFile.custom_asset
$scope.cgvFile = cgvFile.custom_asset
$scope.customLogo = logoFile.custom_asset
$scope.customLogoBlack = logoBlackFile.custom_asset
$scope.customFavicon = faviconFile.custom_asset
$scope.profileImage = profileImageFile.custom_asset
$scope.twitterSetting = { name: 'twitter_name', value: settingsPromise.twitter_name };
$scope.aboutTitleSetting = { name: 'about_title', value: settingsPromise.about_title };
$scope.aboutBodySetting = { name: 'about_body', value: settingsPromise.about_body };
$scope.aboutContactsSetting = { name: 'about_contacts', value: settingsPromise.about_contacts };
$scope.homeBlogpostSetting = { name: 'home_blogpost', value: settingsPromise.home_blogpost };
$scope.machineExplicationsAlert = { name: 'machine_explications_alert', value: settingsPromise.machine_explications_alert };
$scope.trainingExplicationsAlert = { name: 'training_explications_alert', value: settingsPromise.training_explications_alert };
$scope.trainingInformationMessage = { name: 'training_information_message', value: settingsPromise.training_information_message };
$scope.subscriptionExplicationsAlert = { name: 'subscription_explications_alert', value: settingsPromise.subscription_explications_alert };
$scope.eventExplicationsAlert = { name: 'event_explications_alert', value: settingsPromise.event_explications_alert };
$scope.spaceExplicationsAlert = { name: 'space_explications_alert', value: settingsPromise.space_explications_alert };
$scope.windowStart = { name: 'booking_window_start', value: settingsPromise.booking_window_start };
$scope.windowEnd = { name: 'booking_window_end', value: settingsPromise.booking_window_end };
$scope.mainColorSetting = { name: 'main_color', value: settingsPromise.main_color };
$scope.secondColorSetting = { name: 'secondary_color', value: settingsPromise.secondary_color };
$scope.fablabName = { name: 'fablab_name', value: settingsPromise.fablab_name };
$scope.nameGenre = { name: 'name_genre', value: settingsPromise.name_genre };
$scope.machinesSortBy = { name: 'machines_sort_by', value: settingsPromise.machines_sort_by };
$scope.cguFile = cguFile.custom_asset;
$scope.cgvFile = cgvFile.custom_asset;
$scope.customLogo = logoFile.custom_asset;
$scope.customLogoBlack = logoBlackFile.custom_asset;
$scope.customFavicon = faviconFile.custom_asset;
$scope.profileImage = profileImageFile.custom_asset;
$scope.enableMove = {
name: 'booking_move_enable',
value: (settingsPromise.booking_move_enable === 'true')
}
};
$scope.moveDelay = {
name: 'booking_move_delay',
value: parseInt(settingsPromise.booking_move_delay, 10)
}
};
$scope.enableCancel = {
name: 'booking_cancel_enable',
value: (settingsPromise.booking_cancel_enable === 'true')
}
};
$scope.cancelDelay = {
name: 'booking_cancel_delay',
value: parseInt(settingsPromise.booking_cancel_delay, 10)
}
};
$scope.enableReminder = {
name: 'reminder_enable',
value: (settingsPromise.reminder_enable === 'true')
}
};
$scope.reminderDelay = {
name: 'reminder_delay',
value: parseInt(settingsPromise.reminder_delay, 10)
}
};
$scope.visibilityYearly = {
name: 'visibility_yearly',
value: parseInt(settingsPromise.visibility_yearly, 10)
}
};
$scope.visibilityOthers = {
name: 'visibility_others',
value: parseInt(settingsPromise.visibility_others, 10)
}
};
$scope.displayNameEnable = {
name: 'display_name_enable',
value: (settingsPromise.display_name_enable === 'true')
}
};
/**
* For use with 'ng-class', returns the CSS class name for the uploads previews.
@ -126,11 +126,11 @@ Application.Controllers.controller('SettingsController', ['$scope', 'Setting', '
*/
$scope.fileinputClass = function (v) {
if (v) {
return 'fileinput-exists'
return 'fileinput-exists';
} else {
return 'fileinput-new'
return 'fileinput-new';
}
}
};
/**
* Callback to save the setting value to the database
@ -138,24 +138,24 @@ Application.Controllers.controller('SettingsController', ['$scope', 'Setting', '
*/
$scope.save = function (setting) {
// trim empty html
let value
let value;
if ((setting.value === '<br>') || (setting.value === '<p><br></p>')) {
setting.value = ''
setting.value = '';
}
// convert dates to ISO format
if (setting.value instanceof Date) {
setting.value = setting.value.toISOString()
setting.value = setting.value.toISOString();
}
if (setting.value !== null) {
value = setting.value.toString()
value = setting.value.toString();
} else {
({ value } = setting)
({ value } = setting);
}
return Setting.update({ name: setting.name }, { value }, data => growl.success(_t('settings.customization_of_SETTING_successfully_saved', { SETTING: _t(`settings.${setting.name}`) }))
, error => console.log(error))
}
, error => console.log(error));
};
/**
* For use with ngUpload (https://github.com/twilson63/ngUpload).
@ -165,46 +165,46 @@ Application.Controllers.controller('SettingsController', ['$scope', 'Setting', '
*/
$scope.submited = function (content) {
if ((content.custom_asset == null)) {
$scope.alerts = []
$scope.alerts = [];
return angular.forEach(content, (v, k) =>
angular.forEach(v, err => growl.error(err))
)
);
} else {
growl.success(_t('settings.file_successfully_updated'))
growl.success(_t('settings.file_successfully_updated'));
if (content.custom_asset.name === 'cgu-file') {
$scope.cguFile = content.custom_asset
$scope.methods.cgu = 'put'
if (!($scope.actionUrl.cgu.indexOf('/cgu-file') > 0)) { $scope.actionUrl.cgu += '/cgu-file' }
return $scope.loader.cgu = false
$scope.cguFile = content.custom_asset;
$scope.methods.cgu = 'put';
if (!($scope.actionUrl.cgu.indexOf('/cgu-file') > 0)) { $scope.actionUrl.cgu += '/cgu-file'; }
return $scope.loader.cgu = false;
} else if (content.custom_asset.name === 'cgv-file') {
$scope.cgvFile = content.custom_asset
$scope.methods.cgv = 'put'
if (!($scope.actionUrl.cgv.indexOf('/cgv-file') > 0)) { $scope.actionUrl.cgv += '/cgv-file' }
return $scope.loader.cgv = false
$scope.cgvFile = content.custom_asset;
$scope.methods.cgv = 'put';
if (!($scope.actionUrl.cgv.indexOf('/cgv-file') > 0)) { $scope.actionUrl.cgv += '/cgv-file'; }
return $scope.loader.cgv = false;
} else if (content.custom_asset.name === 'logo-file') {
$scope.customLogo = content.custom_asset
$scope.methods.logo = 'put'
if (!($scope.actionUrl.logo.indexOf('/logo-file') > 0)) { return $scope.actionUrl.logo += '/logo-file' }
$scope.customLogo = content.custom_asset;
$scope.methods.logo = 'put';
if (!($scope.actionUrl.logo.indexOf('/logo-file') > 0)) { return $scope.actionUrl.logo += '/logo-file'; }
} else if (content.custom_asset.name === 'logo-black-file') {
$scope.customLogoBlack = content.custom_asset
$scope.methods.logoBlack = 'put'
if (!($scope.actionUrl.logoBlack.indexOf('/logo-black-file') > 0)) { return $scope.actionUrl.logoBlack += '/logo-black-file' }
$scope.customLogoBlack = content.custom_asset;
$scope.methods.logoBlack = 'put';
if (!($scope.actionUrl.logoBlack.indexOf('/logo-black-file') > 0)) { return $scope.actionUrl.logoBlack += '/logo-black-file'; }
} else if (content.custom_asset.name === 'favicon-file') {
$scope.customFavicon = content.custom_asset
$scope.methods.favicon = 'put'
if (!($scope.actionUrl.favicon.indexOf('/favicon-file') > 0)) { return $scope.actionUrl.favicon += '/favicon-file' }
$scope.customFavicon = content.custom_asset;
$scope.methods.favicon = 'put';
if (!($scope.actionUrl.favicon.indexOf('/favicon-file') > 0)) { return $scope.actionUrl.favicon += '/favicon-file'; }
} else if (content.custom_asset.name === 'profile-image-file') {
$scope.profileImage = content.custom_asset
$scope.methods.profileImage = 'put'
if (!($scope.actionUrl.profileImage.indexOf('/profile-image-file') > 0)) { return $scope.actionUrl.profileImage += '/profile-image-file' }
$scope.profileImage = content.custom_asset;
$scope.methods.profileImage = 'put';
if (!($scope.actionUrl.profileImage.indexOf('/profile-image-file') > 0)) { return $scope.actionUrl.profileImage += '/profile-image-file'; }
}
}
}
};
/**
* @param target {String} 'cgu' | 'cgv'
*/
$scope.addLoader = target => $scope.loader[target] = true
$scope.addLoader = target => $scope.loader[target] = true;
/* PRIVATE SCOPE */
@ -213,44 +213,44 @@ Application.Controllers.controller('SettingsController', ['$scope', 'Setting', '
*/
const initialize = function () {
// set the authenticity tokens in the forms
CSRF.setMetaTags()
CSRF.setMetaTags();
// we prevent the admin from setting the closing time before the opening time
$scope.$watch('windowEnd.value', function (newValue, oldValue, scope) {
if ($scope.windowStart && moment($scope.windowStart.value).isAfter(newValue)) {
return $scope.windowEnd.value = oldValue
return $scope.windowEnd.value = oldValue;
}
})
});
// change form methods to PUT if items already exists
if (cguFile.custom_asset) {
$scope.methods.cgu = 'put'
$scope.actionUrl.cgu += '/cgu-file'
$scope.methods.cgu = 'put';
$scope.actionUrl.cgu += '/cgu-file';
}
if (cgvFile.custom_asset) {
$scope.methods.cgv = 'put'
$scope.actionUrl.cgv += '/cgv-file'
$scope.methods.cgv = 'put';
$scope.actionUrl.cgv += '/cgv-file';
}
if (logoFile.custom_asset) {
$scope.methods.logo = 'put'
$scope.actionUrl.logo += '/logo-file'
$scope.methods.logo = 'put';
$scope.actionUrl.logo += '/logo-file';
}
if (logoBlackFile.custom_asset) {
$scope.methods.logoBlack = 'put'
$scope.actionUrl.logoBlack += '/logo-black-file'
$scope.methods.logoBlack = 'put';
$scope.actionUrl.logoBlack += '/logo-black-file';
}
if (faviconFile.custom_asset) {
$scope.methods.favicon = 'put'
$scope.actionUrl.favicon += '/favicon-file'
$scope.methods.favicon = 'put';
$scope.actionUrl.favicon += '/favicon-file';
}
if (profileImageFile.custom_asset) {
$scope.methods.profileImage = 'put'
return $scope.actionUrl.profileImage += '/profile-image-file'
$scope.methods.profileImage = 'put';
return $scope.actionUrl.profileImage += '/profile-image-file';
}
}
};
// init the controller (call at the end !)
return initialize()
return initialize();
}
])
]);

View File

@ -13,74 +13,74 @@
* DS205: Consider reworking code to avoid use of IIFEs
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Controllers.controller('StatisticsController', ['$scope', '$state', '$rootScope', '$uibModal', 'es', 'Member', '_t', 'membersPromise', 'statisticsPromise',
function ($scope, $state, $rootScope, $uibModal, es, Member, _t, membersPromise, statisticsPromise) {
/* PRIVATE STATIC CONSTANTS */
// search window size
const RESULTS_PER_PAGE = 20
const RESULTS_PER_PAGE = 20;
// keep search context for (delay in minutes) ...
const ES_SCROLL_TIME = 1
const ES_SCROLL_TIME = 1;
/* PUBLIC SCOPE */
// ui-view transitions optimization: if true, the stats will never be refreshed
$scope.preventRefresh = false
$scope.preventRefresh = false;
// statistics structure in elasticSearch
$scope.statistics = statisticsPromise
$scope.statistics = statisticsPromise;
// fablab users list
$scope.members = membersPromise
$scope.members = membersPromise;
// statistics data recovered from elasticSearch
$scope.data = null
$scope.data = null;
// when did the search was triggered
$scope.searchDate = null
$scope.searchDate = null;
// id of the elastic search context
$scope.scrollId = null
$scope.scrollId = null;
// total number of results for the current query
$scope.totalHits = null
$scope.totalHits = null;
// configuration of the widget allowing to pick the ages range
$scope.agePicker = {
show: false,
start: null,
end: null
}
};
// total CA for the current view
$scope.sumCA = 0
$scope.sumCA = 0;
// average users' age for the current view
$scope.averageAge = 0
$scope.averageAge = 0;
// total of the stat field for non simple types
$scope.sumStat = 0
$scope.sumStat = 0;
// Results of custom aggregations for the current type
$scope.customAggs = {}
$scope.customAggs = {};
// default: results are not sorted
$scope.sorting = {
ca: 'none',
date: 'desc'
}
};
// active tab will be set here
$scope.selectedIndex = null
$scope.selectedIndex = null;
// type filter binding
$scope.type = {
selected: null,
active: null
}
};
// selected custom filter
$scope.customFilter = {
@ -97,14 +97,14 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
startingDay: 1
}
} // France: the week starts on monday
}
};
// available custom filters
$scope.filters = []
$scope.filters = [];
// default: we do not open the datepicker menu
$scope.datePicker =
{ show: false }
{ show: false };
// datePicker parameters for interval beginning
$scope.datePickerStart = {
@ -116,7 +116,7 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
options: {
startingDay: Fablab.weekStartingDay
}
}
};
// datePicker parameters for interval ending
$scope.datePickerEnd = {
@ -128,25 +128,25 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
options: {
startingDay: Fablab.weekStartingDay
}
}
};
/**
* Callback to open the datepicker (interval start)
* @param $event {Object} jQuery event object
*/
$scope.toggleStartDatePicker = function ($event) { toggleDatePicker($event, $scope.datePickerStart) }
$scope.toggleStartDatePicker = function ($event) { toggleDatePicker($event, $scope.datePickerStart); };
/**
* Callback to open the datepicker (interval end)
* @param $event {Object} jQuery event object
*/
$scope.toggleEndDatePicker = function ($event) { toggleDatePicker($event, $scope.datePickerEnd) }
$scope.toggleEndDatePicker = function ($event) { toggleDatePicker($event, $scope.datePickerEnd); };
/**
* Callback to open the datepicker (custom filter)
* @param $event {Object} jQuery event object
*/
$scope.toggleCustomDatePicker = function ($event) { toggleDatePicker($event, $scope.customFilter.datePicker) }
$scope.toggleCustomDatePicker = function ($event) { toggleDatePicker($event, $scope.customFilter.datePicker); };
/**
* Callback called when the active tab is changed.
@ -154,17 +154,17 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
* @param tab {Object} elasticsearch statistic structure (from statistic_indices table)
*/
$scope.setActiveTab = function (tab) {
$scope.selectedIndex = tab
$scope.type.selected = tab.types[0]
$scope.type.active = $scope.type.selected
$scope.customFilter.criterion = {}
$scope.customFilter.value = null
$scope.customFilter.exclude = false
$scope.sorting.ca = 'none'
$scope.sorting.date = 'desc'
buildCustomFiltersList()
return refreshStats()
}
$scope.selectedIndex = tab;
$scope.type.selected = tab.types[0];
$scope.type.active = $scope.type.selected;
$scope.customFilter.criterion = {};
$scope.customFilter.value = null;
$scope.customFilter.exclude = false;
$scope.sorting.ca = 'none';
$scope.sorting.date = 'desc';
buildCustomFiltersList();
return refreshStats();
};
/**
* Returns true if the provided tab must be hidden due to some global or local configuration
@ -173,41 +173,41 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
$scope.hiddenTab = function (tab) {
if (tab.table) {
if ((tab.es_type_key === 'subscription') && $rootScope.fablabWithoutPlans) {
return true
return true;
} else if ((tab.es_type_key === 'space') && $rootScope.fablabWithoutSpaces) {
return true
return true;
} else {
return false
return false;
}
} else {
return true
return true;
}
}
};
/**
* Callback to validate the filters and send a new request to elastic
*/
$scope.validateFilterChange = function () {
$scope.agePicker.show = false
$scope.customFilter.show = false
$scope.type.active = $scope.type.selected
buildCustomFiltersList()
return refreshStats()
}
$scope.agePicker.show = false;
$scope.customFilter.show = false;
$scope.type.active = $scope.type.selected;
buildCustomFiltersList();
return refreshStats();
};
/**
* Callback to validate the dates range and refresh the data from elastic
*/
$scope.validateDateChange = function () {
$scope.datePicker.show = false
return refreshStats()
}
$scope.datePicker.show = false;
return refreshStats();
};
/**
* Parse the given date and return a user-friendly string
* @param date {Date} JS date or ant moment.js compatible date string
*/
$scope.formatDate = function (date) { return moment(date).format('LL') }
$scope.formatDate = function (date) { return moment(date).format('LL'); };
/**
* Parse the sex and return a user-friendly string
@ -215,26 +215,26 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
*/
$scope.formatSex = function (sex) {
if (sex === 'male') {
return _t('man')
return _t('man');
}
if (sex === 'female') {
return _t('woman')
return _t('woman');
}
}
};
/**
* Retrieve the label for the given subtype in the current type
* @param key {string} statistic subtype key
*/
$scope.formatSubtype = function (key) {
let label = ''
let label = '';
angular.forEach($scope.type.active.subtypes, function (subtype) {
if (subtype.key === key) {
return label = subtype.label
return label = subtype.label;
}
})
return label
}
});
return label;
};
/**
* Helper usable in ng-switch to determine the input type to display for custom filter value
@ -243,14 +243,14 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
$scope.getCustomValueInputType = function (filter) {
if (filter && filter.values) {
if (typeof (filter.values[0]) === 'string') {
return filter.values[0]
return filter.values[0];
} else if (typeof (filter.values[0] === 'object')) {
return 'input_select'
return 'input_select';
}
} else {
return 'input_text'
return 'input_text';
}
}
};
/**
* Change the sorting order and refresh the results to match the new order
@ -258,21 +258,21 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
*/
$scope.toggleSorting = function (filter) {
switch ($scope.sorting[filter]) {
case 'none': $scope.sorting[filter] = 'asc'; break
case 'asc': $scope.sorting[filter] = 'desc'; break
case 'desc': $scope.sorting[filter] = 'none'; break
case 'none': $scope.sorting[filter] = 'asc'; break;
case 'asc': $scope.sorting[filter] = 'desc'; break;
case 'desc': $scope.sorting[filter] = 'none'; break;
}
return refreshStats()
}
return refreshStats();
};
/**
* Return the user's name from his given ID
* @param id {number} user ID
*/
$scope.getUserNameFromId = function (id) {
const name = $scope.members[id]
return (name || `ID ${id}`)
}
const name = $scope.members[id];
return (name || `ID ${id}`);
};
/**
* Run a scroll query to elasticsearch to append the next packet of results to those displayed.
@ -281,12 +281,12 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
$scope.showMoreResults = function () {
// if all results were retrieved, do nothing
if ($scope.data.length >= $scope.totalHits) {
return
return;
}
if (moment($scope.searchDate).add(ES_SCROLL_TIME, 'minutes').isBefore(moment())) {
// elastic search context has expired, so we run again the whole query
return refreshStats()
return refreshStats();
} else {
return es.scroll({
'scroll': ES_SCROLL_TIME + 'm',
@ -294,14 +294,14 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
}
, function (error, response) {
if (error) {
return console.error(`Error: something unexpected occurred during elasticSearch scroll query: ${error}`)
return console.error(`Error: something unexpected occurred during elasticSearch scroll query: ${error}`);
} else {
$scope.scrollId = response._scroll_id
return $scope.data = $scope.data.concat(response.hits.hits)
$scope.scrollId = response._scroll_id;
return $scope.data = $scope.data.concat(response.hits.hits);
}
})
});
}
}
};
/**
* Open a modal dialog asking the user for details about exporting the statistics tables to an excel file
@ -316,24 +316,24 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
return {
start: $scope.datePickerStart.selected,
end: $scope.datePickerEnd.selected
}
};
},
query () {
const custom = buildCustomFilterQuery()
return buildElasticDataQuery($scope.type.active.key, custom, $scope.agePicker.start, $scope.agePicker.end, moment($scope.datePickerStart.selected), moment($scope.datePickerEnd.selected), $scope.sorting)
const custom = buildCustomFilterQuery();
return buildElasticDataQuery($scope.type.active.key, custom, $scope.agePicker.start, $scope.agePicker.end, moment($scope.datePickerStart.selected), moment($scope.datePickerEnd.selected), $scope.sorting);
},
index () {
return { key: $scope.selectedIndex.es_type_key }
return { key: $scope.selectedIndex.es_type_key };
},
type () {
return { key: $scope.type.active.key }
return { key: $scope.type.active.key };
}
}
}
};
return $uibModal.open(options)
.result['finally'](null).then(function (info) { console.log(info) })
}
.result['finally'](null).then(function (info) { console.log(info); });
};
/* PRIVATE SCOPE */
@ -345,10 +345,10 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
// which will cause every tabs to reload, one by one, when the view is closed
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
if ((fromState.name === 'app.admin.statistics') && (Object.keys(fromParams).length === 0)) {
return $scope.preventRefresh = true
return $scope.preventRefresh = true;
}
})
}
});
};
/**
* Generic function to toggle a bootstrap datePicker
@ -356,45 +356,45 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
* @param datePicker {Object} settings object of the concerned datepicker. Must have an 'opened' property
*/
var toggleDatePicker = function ($event, datePicker) {
$event.preventDefault()
$event.stopPropagation()
return datePicker.opened = !datePicker.opened
}
$event.preventDefault();
$event.stopPropagation();
return datePicker.opened = !datePicker.opened;
};
/**
* Force update the statistics table, querying elasticSearch according to the current config values
*/
var refreshStats = function () {
if ($scope.selectedIndex && !$scope.preventRefresh) {
$scope.data = []
$scope.sumCA = 0
$scope.averageAge = 0
$scope.sumStat = 0
$scope.customAggs = {}
$scope.totalHits = null
$scope.searchDate = new Date()
let custom = buildCustomFilterQuery()
$scope.data = [];
$scope.sumCA = 0;
$scope.averageAge = 0;
$scope.sumStat = 0;
$scope.customAggs = {};
$scope.totalHits = null;
$scope.searchDate = new Date();
let custom = buildCustomFilterQuery();
return queryElasticStats($scope.selectedIndex.es_type_key, $scope.type.active.key, custom, function (res, err) {
if (err) {
return console.error(`[statisticsController::refreshStats] Unable to refresh due to ${err}`)
return console.error(`[statisticsController::refreshStats] Unable to refresh due to ${err}`);
} else {
$scope.data = res.hits.hits
$scope.totalHits = res.hits.total
$scope.sumCA = res.aggregations.total_ca.value
$scope.averageAge = Math.round(res.aggregations.average_age.value * 100) / 100
$scope.sumStat = res.aggregations.total_stat.value
$scope.scrollId = res._scroll_id
$scope.data = res.hits.hits;
$scope.totalHits = res.hits.total;
$scope.sumCA = res.aggregations.total_ca.value;
$scope.averageAge = Math.round(res.aggregations.average_age.value * 100) / 100;
$scope.sumStat = res.aggregations.total_stat.value;
$scope.scrollId = res._scroll_id;
return (function () {
const result = []
const result = [];
for (custom of Array.from($scope.type.active.custom_aggregations)) {
result.push($scope.customAggs[custom.field] = res.aggregations[custom.field].value)
result.push($scope.customAggs[custom.field] = res.aggregations[custom.field].value);
}
return result
})()
return result;
})();
}
})
});
}
}
};
/**
* Run the elasticSearch query to retreive the /stats/type aggregations
@ -407,8 +407,8 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
var queryElasticStats = function (index, type, custom, callback) {
// handle invalid callback
if (typeof (callback) !== 'function') {
console.error('[statisticsController::queryElasticStats] Error: invalid callback provided')
return
console.error('[statisticsController::queryElasticStats] Error: invalid callback provided');
return;
}
// run query
@ -425,12 +425,12 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
}
, function (error, response) {
if (error) {
return callback({}, `Error: something unexpected occurred during elasticSearch query: ${error}`)
return callback({}, `Error: something unexpected occurred during elasticSearch query: ${error}`);
} else {
return callback(response)
return callback(response);
}
})
}
});
};
/**
* Build an object representing the content of the REST-JSON query to elasticSearch,
@ -464,7 +464,7 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
]
}
}
}
};
// optional date range
if ((typeof ageMin === 'number') && (typeof ageMax === 'number')) {
q.query.bool.must.push({
@ -474,22 +474,22 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
'lte': ageMax
}
}
})
});
}
// optional criterion
if (custom) {
const criterion = buildElasticCustomCriterion(custom)
const criterion = buildElasticCustomCriterion(custom);
if (custom.exclude) {
q.query.bool.must_not = [
{ 'term': criterion.match }
]
];
} else {
q.query.bool.must.push(criterion)
q.query.bool.must.push(criterion);
}
}
if (sortings) {
q['sort'] = buildElasticSortCriteria(sortings)
q['sort'] = buildElasticSortCriteria(sortings);
}
// aggregations (avg age & CA sum)
@ -509,9 +509,9 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
'field': 'stat'
}
}
}
return q
}
};
return q;
};
/**
* Build the elasticSearch query DSL to match the selected cutom filter
@ -522,34 +522,34 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
if (custom) {
const criterion = {
'match': {}
}
};
switch ($scope.getCustomValueInputType($scope.customFilter.criterion)) {
case 'input_date': criterion.match[custom.key] = moment(custom.value).format('YYYY-MM-DD'); break
case 'input_select': criterion.match[custom.key] = custom.value.key; break
case 'input_list': criterion.match[custom.key + '.name'] = custom.value; break
default: criterion.match[custom.key] = custom.value
case 'input_date': criterion.match[custom.key] = moment(custom.value).format('YYYY-MM-DD'); break;
case 'input_select': criterion.match[custom.key] = custom.value.key; break;
case 'input_list': criterion.match[custom.key + '.name'] = custom.value; break;
default: criterion.match[custom.key] = custom.value;
}
return criterion
return criterion;
} else {
return ''
return '';
}
}
};
/**
* Parse the provided criteria array and return the corresponding elasticSearch syntax
* @param criteria {Array} array of {key_to_sort:order}
*/
var buildElasticSortCriteria = function (criteria) {
const crits = []
const crits = [];
angular.forEach(criteria, function (value, key) {
if ((typeof value !== 'undefined') && (value !== null) && (value !== 'none')) {
const c = {}
c[key] = { 'order': value }
return crits.push(c)
const c = {};
c[key] = { 'order': value };
return crits.push(c);
}
})
return crits
}
});
return crits;
};
/**
* Fullfil the list of available options in the custom filter panel. The list will be based on common
@ -563,76 +563,76 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
{ key: 'age', label: _t('age'), values: ['input_number'] },
{ key: 'subType', label: _t('type'), values: $scope.type.active.subtypes },
{ key: 'ca', label: _t('revenue'), values: ['input_number'] }
]
];
if (!$scope.type.active.simple) {
const f = { key: 'stat', label: $scope.type.active.label, values: ['input_number'] }
$scope.filters.push(f)
const f = { key: 'stat', label: $scope.type.active.label, values: ['input_number'] };
$scope.filters.push(f);
}
return angular.forEach($scope.selectedIndex.additional_fields, function (field) {
const filter = { key: field.key, label: field.label, values: [] }
const filter = { key: field.key, label: field.label, values: [] };
switch (field.data_type) {
case 'index': filter.values.push('input_number'); break
case 'number': filter.values.push('input_number'); break
case 'date': filter.values.push('input_date'); break
case 'list': filter.values.push('input_list'); break
default: filter.values.push('input_text')
case 'index': filter.values.push('input_number'); break;
case 'number': filter.values.push('input_number'); break;
case 'date': filter.values.push('input_date'); break;
case 'list': filter.values.push('input_list'); break;
default: filter.values.push('input_text');
}
return $scope.filters.push(filter)
})
}
return $scope.filters.push(filter);
});
};
/**
* Build and return an object according to the custom filter set by the user, used to request elasticsearch
* @return {Object|null}
*/
var buildCustomFilterQuery = function () {
let custom = null
let custom = null;
if (!angular.isUndefinedOrNull($scope.customFilter.criterion) &&
!angular.isUndefinedOrNull($scope.customFilter.criterion.key) &&
!angular.isUndefinedOrNull($scope.customFilter.value)) {
custom = {}
custom.key = $scope.customFilter.criterion.key
custom.value = $scope.customFilter.value
custom.exclude = $scope.customFilter.exclude
custom = {};
custom.key = $scope.customFilter.criterion.key;
custom.value = $scope.customFilter.value;
custom.exclude = $scope.customFilter.exclude;
}
return custom
}
return custom;
};
// init the controller (call at the end !)
return initialize()
return initialize();
}
])
]);
Application.Controllers.controller('ExportStatisticsController', [ '$scope', '$uibModalInstance', 'Export', 'dates', 'query', 'index', 'type', 'CSRF', 'growl', '_t',
function ($scope, $uibModalInstance, Export, dates, query, index, type, CSRF, growl, _t) {
// Retrieve Anti-CSRF tokens from cookies
CSRF.setMetaTags()
CSRF.setMetaTags();
// Bindings for date range
$scope.dates = dates
$scope.dates = dates;
// Body of the query to export
$scope.query = JSON.stringify(query)
$scope.query = JSON.stringify(query);
// API URL where the form will be posted
$scope.actionUrl = `/stats/${index.key}/export`
$scope.actionUrl = `/stats/${index.key}/export`;
// Key of the current search' statistic type
$scope.typeKey = type.key
$scope.typeKey = type.key;
// Form action on the above URL
$scope.method = 'post'
$scope.method = 'post';
// Anti-CSRF token to inject into the download form
$scope.csrfToken = angular.element('meta[name="csrf-token"]')[0].content
$scope.csrfToken = angular.element('meta[name="csrf-token"]')[0].content;
// Binding of the export type (global / current)
$scope.export =
{ type: 'current' }
{ type: 'current' };
// datePicker parameters for interval beginning
$scope.exportStart = {
@ -643,7 +643,7 @@ Application.Controllers.controller('ExportStatisticsController', [ '$scope', '$u
options: {
startingDay: Fablab.weekStartingDay
}
}
};
// datePicker parameters for interval ending
$scope.exportEnd = {
@ -654,19 +654,19 @@ Application.Controllers.controller('ExportStatisticsController', [ '$scope', '$u
options: {
startingDay: Fablab.weekStartingDay
}
}
};
/**
* Callback to open the datepicker (interval start)
* @param $event {Object} jQuery event object
*/
$scope.toggleStartDatePicker = function ($event) { $scope.exportStart.opened = !$scope.exportStart.opened }
$scope.toggleStartDatePicker = function ($event) { $scope.exportStart.opened = !$scope.exportStart.opened; };
/**
* Callback to open the datepicker (interval end)
* @param $event {Object} jQuery event object
*/
$scope.toggleEndDatePicker = function ($event) { $scope.exportEnd.opened = !$scope.exportEnd.opened }
$scope.toggleEndDatePicker = function ($event) { $scope.exportEnd.opened = !$scope.exportEnd.opened; };
/**
* Callback when exchanging the export type between 'global' and 'current view'
@ -674,7 +674,7 @@ Application.Controllers.controller('ExportStatisticsController', [ '$scope', '$u
*/
$scope.setRequest = function () {
if ($scope.export.type === 'global') {
$scope.actionUrl = '/stats/global/export'
$scope.actionUrl = '/stats/global/export';
return $scope.query = JSON.stringify({
'query': {
'bool': {
@ -690,35 +690,35 @@ Application.Controllers.controller('ExportStatisticsController', [ '$scope', '$u
]
}
}
})
});
} else {
$scope.actionUrl = `/stats/${index.key}/export`
$scope.query = JSON.stringify(query)
$scope.actionUrl = `/stats/${index.key}/export`;
$scope.query = JSON.stringify(query);
}
}
};
/**
* Callback to close the modal, telling the caller what is exported
*/
$scope.exportData = function () {
const statusQry = { category: 'statistics', type: $scope.export.type, query: $scope.query }
const statusQry = { category: 'statistics', type: $scope.export.type, query: $scope.query };
if ($scope.export.type !== 'global') {
statusQry['type'] = index.key
statusQry['key'] = type.key
statusQry['type'] = index.key;
statusQry['key'] = type.key;
}
Export.status(statusQry).then(function (res) {
if (!res.data.exists) {
return growl.success(_t('export_is_running_you_ll_be_notified_when_its_ready'))
return growl.success(_t('export_is_running_you_ll_be_notified_when_its_ready'));
}
})
});
return $uibModalInstance.close(statusQry)
}
return $uibModalInstance.close(statusQry);
};
/**
* Callback to cancel the export and close the modal
*/
$scope.cancel = function () { $uibModalInstance.dismiss('cancel') }
$scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
}
])
]);

View File

@ -13,7 +13,7 @@
*/
Application.Controllers.controller('TagsController', ['$scope', 'tagsPromise', 'Tag', 'growl', '_t', function ($scope, tagsPromise, Tag, growl, _t) {
// List of users's tags
$scope.tags = tagsPromise
$scope.tags = tagsPromise;
/**
* Removes the newly inserted but not saved tag / Cancel the current tag modification
@ -22,20 +22,20 @@ Application.Controllers.controller('TagsController', ['$scope', 'tagsPromise', '
*/
$scope.cancelTag = function (rowform, index) {
if ($scope.tags[index].id != null) {
return rowform.$cancel()
return rowform.$cancel();
} else {
return $scope.tags.splice(index, 1)
return $scope.tags.splice(index, 1);
}
}
};
/**
* Creates a new empty entry in the $scope.tags array
*/
$scope.addTag = function () {
$scope.inserted =
{ name: '' }
return $scope.tags.push($scope.inserted)
}
{ name: '' };
return $scope.tags.push($scope.inserted);
};
/**
* Saves a new tag / Update an existing tag to the server (form validation callback)
@ -45,18 +45,18 @@ Application.Controllers.controller('TagsController', ['$scope', 'tagsPromise', '
$scope.saveTag = function (data, id) {
if (id != null) {
return Tag.update({ id }, { tag: data }, response => growl.success(_t('changes_successfully_saved'))
, error => growl.error(_t('an_error_occurred_while_saving_changes')))
, error => growl.error(_t('an_error_occurred_while_saving_changes')));
} else {
return Tag.save({ tag: data }, function (resp) {
growl.success(_t('new_tag_successfully_saved'))
return $scope.tags[$scope.tags.length - 1].id = resp.id
growl.success(_t('new_tag_successfully_saved'));
return $scope.tags[$scope.tags.length - 1].id = resp.id;
}
, function (error) {
growl.error(_t('an_error_occurred_while_saving_the_new_tag'))
return $scope.tags.splice($scope.tags.length - 1, 1)
})
growl.error(_t('an_error_occurred_while_saving_the_new_tag'));
return $scope.tags.splice($scope.tags.length - 1, 1);
});
}
}
};
/**
* Deletes the tag at the specified index
@ -65,10 +65,10 @@ Application.Controllers.controller('TagsController', ['$scope', 'tagsPromise', '
return $scope.removeTag = index =>
// TODO add confirmation : les utilisateurs seront déasociés
Tag.delete({ id: $scope.tags[index].id }, function (resp) {
growl.success(_t('tag_successfully_deleted'))
return $scope.tags.splice(index, 1)
growl.success(_t('tag_successfully_deleted'));
return $scope.tags.splice(index, 1);
}
, error => growl.error(_t('an_error_occurred_and_the_tag_deletion_failed')))
, error => growl.error(_t('an_error_occurred_and_the_tag_deletion_failed')));
}
])
]);

View File

@ -12,7 +12,7 @@
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
/* COMMON CODE */
@ -39,29 +39,29 @@ class TrainingsController {
*/
$scope.submited = function (content) {
if ((content.id == null)) {
$scope.alerts = []
$scope.alerts = [];
return angular.forEach(content, function (v, k) {
angular.forEach(v, function (err) {
$scope.alerts.push({
msg: k + ': ' + err,
type: 'danger'
})
})
})
});
});
});
} else {
return $state.go('app.admin.trainings')
return $state.go('app.admin.trainings');
}
}
};
/**
* Changes the current user's view, redirecting him to the machines list
*/
$scope.cancel = function () { $state.go('app.admin.trainings') }
$scope.cancel = function () { $state.go('app.admin.trainings'); };
/**
* Force the 'public_page' attribute to false when the current training is disabled
*/
$scope.onDisableToggled = function () { $scope.training.public_page = !$scope.training.disabled }
$scope.onDisableToggled = function () { $scope.training.public_page = !$scope.training.disabled; };
/**
* For use with 'ng-class', returns the CSS class name for the uploads previews.
@ -70,11 +70,11 @@ class TrainingsController {
*/
$scope.fileinputClass = function (v) {
if (v) {
return 'fileinput-exists'
return 'fileinput-exists';
} else {
return 'fileinput-new'
return 'fileinput-new';
}
}
};
}
}
@ -86,13 +86,13 @@ Application.Controllers.controller('NewTrainingController', [ '$scope', '$state'
/* PUBLIC SCOPE */
// Form action on the following URL
$scope.method = 'post'
$scope.method = 'post';
// API URL where the form will be posted
$scope.actionUrl = '/api/trainings/'
$scope.actionUrl = '/api/trainings/';
// list of machines
$scope.machines = machinesPromise
$scope.machines = machinesPromise;
/* PRIVATE SCOPE */
@ -100,16 +100,16 @@ Application.Controllers.controller('NewTrainingController', [ '$scope', '$state'
* Kind of constructor: these actions will be realized first when the controller is loaded
*/
const initialize = function () {
CSRF.setMetaTags()
CSRF.setMetaTags();
// Using the TrainingsController
return new TrainingsController($scope, $state)
}
return new TrainingsController($scope, $state);
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);
/**
* Controller used in the training edition page (admin)
@ -119,16 +119,16 @@ Application.Controllers.controller('EditTrainingController', [ '$scope', '$state
/* PUBLIC SCOPE */
// Form action on the following URL
$scope.method = 'patch'
$scope.method = 'patch';
// API URL where the form will be posted
$scope.actionUrl = `/api/trainings/${$stateParams.id}`
$scope.actionUrl = `/api/trainings/${$stateParams.id}`;
// Details of the training to edit (id in URL)
$scope.training = trainingPromise
$scope.training = trainingPromise;
// list of machines
$scope.machines = machinesPromise
$scope.machines = machinesPromise;
/* PRIVATE SCOPE */
@ -136,16 +136,16 @@ Application.Controllers.controller('EditTrainingController', [ '$scope', '$state
* Kind of constructor: these actions will be realized first when the controller is loaded
*/
const initialize = function () {
CSRF.setMetaTags()
CSRF.setMetaTags();
// Using the TrainingsController
return new TrainingsController($scope, $state)
}
return new TrainingsController($scope, $state);
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);
/**
* Controller used in the trainings management page, allowing admins users to see and manage the list of trainings and reservations.
@ -155,34 +155,34 @@ Application.Controllers.controller('TrainingsAdminController', ['$scope', '$stat
/* PUBLIC SCOPE */
// list of trainings
let groupAvailabilities
$scope.trainings = trainingsPromise
let groupAvailabilities;
$scope.trainings = trainingsPromise;
// simplified list of machines
$scope.machines = machinesPromise
$scope.machines = machinesPromise;
// Training to monitor, binded with drop-down selection
$scope.monitoring =
{ training: null }
{ training: null };
// list of training availabilies, grouped by date
$scope.groupedAvailabilities = {}
$scope.groupedAvailabilities = {};
// default: accordions are not open
$scope.accordions = {}
$scope.accordions = {};
// Binding for the parseInt function
$scope.parseInt = parseInt
$scope.parseInt = parseInt;
// Default: we show only enabled trainings
$scope.trainingFiltering = 'enabled'
$scope.trainingFiltering = 'enabled';
// Available options for filtering trainings by status
$scope.filterDisabled = [
'enabled',
'disabled',
'all'
]
];
/**
* In the trainings listing tab, return the stringified list of machines associated with the provided training
@ -190,14 +190,14 @@ Application.Controllers.controller('TrainingsAdminController', ['$scope', '$stat
* @returns {string}
*/
$scope.showMachines = function (training) {
const selected = []
const selected = [];
angular.forEach($scope.machines, function (m) {
if (training.machine_ids.indexOf(m.id) >= 0) {
return selected.push(m.name)
return selected.push(m.name);
}
})
if (selected.length) { return selected.join(', ') } else { return _t('none') }
}
});
if (selected.length) { return selected.join(', '); } else { return _t('none'); }
};
/**
* Removes the newly inserted but not saved training / Cancel the current training modification
@ -206,11 +206,11 @@ Application.Controllers.controller('TrainingsAdminController', ['$scope', '$stat
*/
$scope.cancelTraining = function (rowform, index) {
if ($scope.trainings[index].id != null) {
return rowform.$cancel()
return rowform.$cancel();
} else {
return $scope.trainings.splice(index, 1)
return $scope.trainings.splice(index, 1);
}
}
};
/**
* In the trainings monitoring tab, callback to open a modal window displaying the current bookings for the
@ -223,47 +223,47 @@ Application.Controllers.controller('TrainingsAdminController', ['$scope', '$stat
$uibModal.open({
templateUrl: '<%= asset_path "admin/trainings/validTrainingModal.html" %>',
controller: ['$scope', '$uibModalInstance', function ($scope, $uibModalInstance) {
$scope.availability = availability
$scope.availability = availability;
$scope.usersToValid = []
$scope.usersToValid = [];
/**
* Mark/unmark the provided user for training validation
* @param user {Object} from the availability.reservation_users list
*/
$scope.toggleSelection = function (user) {
const index = $scope.usersToValid.indexOf(user)
const index = $scope.usersToValid.indexOf(user);
if (index > -1) {
return $scope.usersToValid.splice(index, 1)
return $scope.usersToValid.splice(index, 1);
} else {
return $scope.usersToValid.push(user)
return $scope.usersToValid.push(user);
}
}
};
/**
* Validates the modifications (training validations) and save them to the server
*/
$scope.ok = function () {
const users = $scope.usersToValid.map(function (u) { return u.id })
const users = $scope.usersToValid.map(function (u) { return u.id; });
return Training.update({ id: training.id }, {
training: {
users
}
}
, function () { // success
angular.forEach($scope.usersToValid, function (u) { u.is_valid = true })
$scope.usersToValid = []
return $uibModalInstance.close(training)
})
}
angular.forEach($scope.usersToValid, function (u) { u.is_valid = true; });
$scope.usersToValid = [];
return $uibModalInstance.close(training);
});
};
/**
* Cancel the modifications and close the modal window
*/
return $scope.cancel = function () { $uibModalInstance.dismiss('cancel') }
return $scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
}
] })
}
] });
};
/**
* Delete the provided training and, in case of success, remove it from the trainings list afterwards
@ -278,22 +278,22 @@ Application.Controllers.controller('TrainingsAdminController', ['$scope', '$stat
return {
title: _t('confirmation_required'),
msg: _t('do_you_really_want_to_delete_this_training')
}
};
}
}
},
function () { // deletion confirmed
training.$delete(function () {
$scope.trainings.splice(index, 1)
growl.info(_t('training_successfully_deleted'))
$scope.trainings.splice(index, 1);
growl.info(_t('training_successfully_deleted'));
},
function (error) {
growl.warning(_t('unable_to_delete_the_training_because_some_users_alredy_booked_it'))
console.error(error)
})
growl.warning(_t('unable_to_delete_the_training_because_some_users_alredy_booked_it'));
console.error(error);
});
}
)
}
);
};
/**
* Takes a month number and return its localized literal name
@ -301,9 +301,9 @@ Application.Controllers.controller('TrainingsAdminController', ['$scope', '$stat
* @returns {String} eg. 'janvier'
*/
$scope.formatMonth = function (number) {
number = parseInt(number)
return moment().month(number).format('MMMM')
}
number = parseInt(number);
return moment().month(number).format('MMMM');
};
/**
* Given a day, month and year, return a localized literal name for the day
@ -313,12 +313,12 @@ Application.Controllers.controller('TrainingsAdminController', ['$scope', '$stat
* @returns {String} eg. 'mercredi 12'
*/
$scope.formatDay = function (day, month, year) {
day = parseInt(day)
month = parseInt(month)
year = parseInt(year)
day = parseInt(day);
month = parseInt(month);
year = parseInt(year);
return moment({ year, month, day }).format('dddd D')
}
return moment({ year, month, day }).format('dddd D');
};
/**
* Callback when the drop-down selection is changed.
@ -326,14 +326,14 @@ Application.Controllers.controller('TrainingsAdminController', ['$scope', '$stat
*/
$scope.selectTrainingToMonitor = function () {
Training.availabilities({ id: $scope.monitoring.training.id }, function (training) {
$scope.groupedAvailabilities = groupAvailabilities([training])
$scope.groupedAvailabilities = groupAvailabilities([training]);
// we open current year/month by default
const now = moment()
$scope.accordions[training.name] = {}
$scope.accordions[training.name][now.year()] = { isOpenFirst: true }
$scope.accordions[training.name][now.year()][now.month()] = { isOpenFirst: true }
})
}
const now = moment();
$scope.accordions[training.name] = {};
$scope.accordions[training.name][now.year()] = { isOpenFirst: true };
$scope.accordions[training.name][now.year()][now.month()] = { isOpenFirst: true };
});
};
/* PRIVATE SCOPE */
@ -343,30 +343,30 @@ Application.Controllers.controller('TrainingsAdminController', ['$scope', '$stat
* @returns {Object} Tree constructed as /training_name/year/month/day/[availabilities]
*/
return groupAvailabilities = function (trainings) {
const tree = {}
const tree = {};
for (let training of Array.from(trainings)) {
tree[training.name] = {}
tree[training.name].training = training
tree[training.name] = {};
tree[training.name].training = training;
for (let availability of Array.from(training.availabilities)) {
const start = moment(availability.start_at)
const start = moment(availability.start_at);
// init the tree structure
if (typeof tree[training.name][start.year()] === 'undefined') {
tree[training.name][start.year()] = {}
tree[training.name][start.year()] = {};
}
if (typeof tree[training.name][start.year()][start.month()] === 'undefined') {
tree[training.name][start.year()][start.month()] = {}
tree[training.name][start.year()][start.month()] = {};
}
if (typeof tree[training.name][start.year()][start.month()][start.date()] === 'undefined') {
tree[training.name][start.year()][start.month()][start.date()] = []
tree[training.name][start.year()][start.month()][start.date()] = [];
}
// add the availability at its right place
tree[training.name][start.year()][start.month()][start.date()].push(availability)
tree[training.name][start.year()][start.month()][start.date()].push(availability);
}
}
return tree
}
return tree;
};
}
])
]);

View File

@ -10,7 +10,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
/**
* Controller used in the public calendar global
@ -19,40 +19,40 @@
Application.Controllers.controller('CalendarController', ['$scope', '$state', '$aside', 'moment', 'Availability', 'Slot', 'Setting', 'growl', 'dialogs', 'bookingWindowStart', 'bookingWindowEnd', '_t', 'uiCalendarConfig', 'CalendarConfig', 'trainingsPromise', 'machinesPromise', 'spacesPromise',
function ($scope, $state, $aside, moment, Availability, Slot, Setting, growl, dialogs, bookingWindowStart, bookingWindowEnd, _t, uiCalendarConfig, CalendarConfig, trainingsPromise, machinesPromise, spacesPromise) {
/* PRIVATE STATIC CONSTANTS */
let currentMachineEvent = null
machinesPromise.forEach(m => m.checked = true)
trainingsPromise.forEach(t => t.checked = true)
spacesPromise.forEach(s => s.checked = true)
let currentMachineEvent = null;
machinesPromise.forEach(m => m.checked = true);
trainingsPromise.forEach(t => t.checked = true);
spacesPromise.forEach(s => s.checked = true);
// check all formation/machine is select in filter
const isSelectAll = (type, scope) => scope[type].length === scope[type].filter(t => t.checked).length
const isSelectAll = (type, scope) => scope[type].length === scope[type].filter(t => t.checked).length;
/* PUBLIC SCOPE */
// List of trainings
$scope.trainings = trainingsPromise.filter(t => !t.disabled)
$scope.trainings = trainingsPromise.filter(t => !t.disabled);
// List of machines
$scope.machines = machinesPromise.filter(t => !t.disabled)
$scope.machines = machinesPromise.filter(t => !t.disabled);
// List of spaces
$scope.spaces = spacesPromise.filter(t => !t.disabled)
$scope.spaces = spacesPromise.filter(t => !t.disabled);
// add availabilities source to event sources
$scope.eventSources = []
$scope.eventSources = [];
// filter availabilities if have change
$scope.filterAvailabilities = function (filter, scope) {
if (!scope) { scope = $scope }
if (!scope) { scope = $scope; }
scope.filter = ($scope.filter = {
trainings: isSelectAll('trainings', scope),
machines: isSelectAll('machines', scope),
spaces: isSelectAll('spaces', scope),
evt: filter.evt,
dispo: filter.dispo
})
return $scope.calendarConfig.events = availabilitySourceUrl()
}
});
return $scope.calendarConfig.events = availabilitySourceUrl();
};
// a variable for formation/machine/event/dispo checkbox is or not checked
$scope.filter = {
@ -61,13 +61,13 @@ Application.Controllers.controller('CalendarController', ['$scope', '$state', '$
spaces: isSelectAll('spaces', $scope),
evt: true,
dispo: true
}
};
// toggle to select all formation/machine
$scope.toggleFilter = function (type, filter) {
$scope[type].forEach(t => t.checked = filter[type])
return $scope.filterAvailabilities(filter, $scope)
}
$scope[type].forEach(t => t.checked = filter[type]);
return $scope.filterAvailabilities(filter, $scope);
};
$scope.openFilterAside = () =>
$aside.open({
@ -77,112 +77,112 @@ Application.Controllers.controller('CalendarController', ['$scope', '$state', '$
backdrop: false,
resolve: {
trainings () {
return $scope.trainings
return $scope.trainings;
},
machines () {
return $scope.machines
return $scope.machines;
},
spaces () {
return $scope.spaces
return $scope.spaces;
},
filter () {
return $scope.filter
return $scope.filter;
},
toggleFilter () {
return $scope.toggleFilter
return $scope.toggleFilter;
},
filterAvailabilities () {
return $scope.filterAvailabilities
return $scope.filterAvailabilities;
}
},
controller: ['$scope', '$uibModalInstance', 'trainings', 'machines', 'spaces', 'filter', 'toggleFilter', 'filterAvailabilities', function ($scope, $uibModalInstance, trainings, machines, spaces, filter, toggleFilter, filterAvailabilities) {
$scope.trainings = trainings
$scope.machines = machines
$scope.spaces = spaces
$scope.filter = filter
$scope.trainings = trainings;
$scope.machines = machines;
$scope.spaces = spaces;
$scope.filter = filter;
$scope.toggleFilter = (type, filter) => toggleFilter(type, filter)
$scope.toggleFilter = (type, filter) => toggleFilter(type, filter);
$scope.filterAvailabilities = filter => filterAvailabilities(filter, $scope)
$scope.filterAvailabilities = filter => filterAvailabilities(filter, $scope);
return $scope.close = function (e) {
$uibModalInstance.dismiss()
return e.stopPropagation()
}
$uibModalInstance.dismiss();
return e.stopPropagation();
};
}
] })
] });
/* PRIVATE SCOPE */
const calendarEventClickCb = function (event, jsEvent, view) {
// current calendar object
const { calendar } = uiCalendarConfig.calendars
const { calendar } = uiCalendarConfig.calendars;
if (event.available_type === 'machines') {
currentMachineEvent = event
calendar.fullCalendar('changeView', 'agendaDay')
return calendar.fullCalendar('gotoDate', event.start)
currentMachineEvent = event;
calendar.fullCalendar('changeView', 'agendaDay');
return calendar.fullCalendar('gotoDate', event.start);
} else if (event.available_type === 'space') {
calendar.fullCalendar('changeView', 'agendaDay')
return calendar.fullCalendar('gotoDate', event.start)
calendar.fullCalendar('changeView', 'agendaDay');
return calendar.fullCalendar('gotoDate', event.start);
} else if (event.available_type === 'event') {
return $state.go('app.public.events_show', { id: event.event_id })
return $state.go('app.public.events_show', { id: event.event_id });
} else if (event.available_type === 'training') {
return $state.go('app.public.training_show', { id: event.training_id })
return $state.go('app.public.training_show', { id: event.training_id });
} else {
if (event.machine_id) {
return $state.go('app.public.machines_show', { id: event.machine_id })
return $state.go('app.public.machines_show', { id: event.machine_id });
} else if (event.space_id) {
return $state.go('app.public.space_show', { id: event.space_id })
return $state.go('app.public.space_show', { id: event.space_id });
}
}
}
};
// agendaDay view: disable slotEventOverlap
// agendaWeek view: enable slotEventOverlap
const toggleSlotEventOverlap = function (view) {
// set defaultView, because when we change slotEventOverlap
// ui-calendar will trigger rerender calendar
$scope.calendarConfig.defaultView = view.type
const today = currentMachineEvent ? currentMachineEvent.start : moment().utc().startOf('day')
$scope.calendarConfig.defaultView = view.type;
const today = currentMachineEvent ? currentMachineEvent.start : moment().utc().startOf('day');
if ((today > view.intervalStart) && (today < view.intervalEnd) && (today !== view.intervalStart)) {
$scope.calendarConfig.defaultDate = today
$scope.calendarConfig.defaultDate = today;
} else {
$scope.calendarConfig.defaultDate = view.intervalStart
$scope.calendarConfig.defaultDate = view.intervalStart;
}
if (view.type === 'agendaDay') {
return $scope.calendarConfig.slotEventOverlap = false
return $scope.calendarConfig.slotEventOverlap = false;
} else {
return $scope.calendarConfig.slotEventOverlap = true
return $scope.calendarConfig.slotEventOverlap = true;
}
}
};
// function is called when calendar view is rendered or changed
const viewRenderCb = function (view, element) {
toggleSlotEventOverlap(view)
toggleSlotEventOverlap(view);
if (view.type === 'agendaDay') {
// get availabilties by 1 day for show machine slots
return uiCalendarConfig.calendars.calendar.fullCalendar('refetchEvents')
return uiCalendarConfig.calendars.calendar.fullCalendar('refetchEvents');
}
}
};
const eventRenderCb = function (event, element) {
if (event.tags.length > 0) {
let html = ''
let html = '';
for (let tag of Array.from(event.tags)) {
html += `<span class='label label-success text-white'>${tag.name}</span> `
html += `<span class='label label-success text-white'>${tag.name}</span> `;
}
element.find('.fc-title').append(`<br/>${html}`)
element.find('.fc-title').append(`<br/>${html}`);
}
}
};
const getFilter = function () {
const t = $scope.trainings.filter(t => t.checked).map(t => t.id)
const m = $scope.machines.filter(m => m.checked).map(m => m.id)
const s = $scope.spaces.filter(s => s.checked).map(s => s.id)
return { t, m, s, evt: $scope.filter.evt, dispo: $scope.filter.dispo }
}
const t = $scope.trainings.filter(t => t.checked).map(t => t.id);
const m = $scope.machines.filter(m => m.checked).map(m => m.id);
const s = $scope.spaces.filter(s => s.checked).map(s => s.id);
return { t, m, s, evt: $scope.filter.evt, dispo: $scope.filter.dispo };
};
var availabilitySourceUrl = () => `/api/availabilities/public?${$.param(getFilter())}`
var availabilitySourceUrl = () => `/api/availabilities/public?${$.param(getFilter())}`;
const initialize = () =>
// fullCalendar (v2) configuration
@ -198,17 +198,17 @@ Application.Controllers.controller('CalendarController', ['$scope', '$state', '$
maxTime: moment.duration(moment(bookingWindowEnd.setting.value).format('HH:mm:ss')),
defaultView: window.innerWidth <= 480 ? 'agendaDay' : 'agendaWeek',
eventClick (event, jsEvent, view) {
return calendarEventClickCb(event, jsEvent, view)
return calendarEventClickCb(event, jsEvent, view);
},
viewRender (view, element) {
return viewRenderCb(view, element)
return viewRenderCb(view, element);
},
eventRender (event, element, view) {
return eventRenderCb(event, element)
return eventRenderCb(event, element);
}
})
});
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);

View File

@ -10,24 +10,24 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Controllers.controller('DashboardController', ['$scope', 'memberPromise', 'SocialNetworks', function ($scope, memberPromise, SocialNetworks) {
// Current user's profile
$scope.user = memberPromise
$scope.user = memberPromise;
// List of social networks associated with this user and toggle 'show all' state
$scope.social = {
showAllLinks: false,
networks: SocialNetworks
}
};
/* PRIVATE SCOPE */
/**
* Kind of constructor: these actions will be realized first when the controller is loaded
*/
const initialize = () => $scope.social.networks = filterNetworks()
const initialize = () => $scope.social.networks = filterNetworks();
/**
* Filter social network or website that are associated with the profile of the user provided in promise
@ -35,17 +35,17 @@ Application.Controllers.controller('DashboardController', ['$scope', 'memberProm
* @return {Array}
*/
var filterNetworks = function () {
const networks = []
const networks = [];
for (let network of Array.from(SocialNetworks)) {
if ($scope.user.profile[network] && ($scope.user.profile[network].length > 0)) {
networks.push(network)
networks.push(network);
}
}
return networks
}
return networks;
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);

View File

@ -8,36 +8,36 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Controllers.controller('HomeController', ['$scope', '$stateParams', 'Twitter', 'lastMembersPromise', 'lastProjectsPromise', 'upcomingEventsPromise', 'homeBlogpostPromise', 'twitterNamePromise',
function ($scope, $stateParams, Twitter, lastMembersPromise, lastProjectsPromise, upcomingEventsPromise, homeBlogpostPromise, twitterNamePromise) {
/* PUBLIC SCOPE */
// The last registered members who confirmed their addresses
$scope.lastMembers = lastMembersPromise
$scope.lastMembers = lastMembersPromise;
// The last tweets from the Fablab official twitter account
$scope.lastTweets = []
$scope.lastTweets = [];
// The last projects published/documented on the plateform
$scope.lastProjects = lastProjectsPromise
$scope.lastProjects = lastProjectsPromise;
// The closest upcoming events
$scope.upcomingEvents = upcomingEventsPromise
$scope.upcomingEvents = upcomingEventsPromise;
// The admin blogpost
$scope.homeBlogpost = homeBlogpostPromise.setting.value
$scope.homeBlogpost = homeBlogpostPromise.setting.value;
// Twitter username
$scope.twitterName = twitterNamePromise.setting.value
$scope.twitterName = twitterNamePromise.setting.value;
/**
* Test if the provided event run on a single day or not
* @param event {Object} single event from the $scope.upcomingEvents array
* @returns {boolean} false if the event runs on more that 1 day
*/
$scope.isOneDayEvent = event => moment(event.start_date).isSame(event.end_date, 'day')
$scope.isOneDayEvent = event => moment(event.start_date).isSame(event.end_date, 'day');
/* PRIVATE SCOPE */
@ -47,16 +47,16 @@ Application.Controllers.controller('HomeController', ['$scope', '$stateParams',
const initialize = function () {
// we retrieve tweets from here instead of ui-router's promise because, if adblock stop the API request,
// this prevent the whole home page to be blocked
$scope.lastTweets = Twitter.query({ limit: 1 })
$scope.lastTweets = Twitter.query({ limit: 1 });
// if we recieve a token to reset the password as GET parameter, trigger the
// changePassword modal from the parent controller
if ($stateParams.reset_password_token) {
return $scope.$parent.editPassword($stateParams.reset_password_token)
return $scope.$parent.editPassword($stateParams.reset_password_token);
}
}
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);

View File

@ -12,7 +12,7 @@
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
/* COMMON CODE */
@ -41,24 +41,24 @@ class MachinesController {
*/
$scope.submited = function (content) {
if ((content.id == null)) {
$scope.alerts = []
$scope.alerts = [];
angular.forEach(content, function (v, k) {
angular.forEach(function (v, err) {
$scope.alerts.push({
msg: k + ': ' + err,
type: 'danger'
})
})
})
});
});
});
} else {
return $state.go('app.public.machines_list')
return $state.go('app.public.machines_list');
}
}
};
/**
* Changes the current user's view, redirecting him to the machines list
*/
$scope.cancel = function () { $state.go('app.public.machines_list') }
$scope.cancel = function () { $state.go('app.public.machines_list'); };
/**
* For use with 'ng-class', returns the CSS class name for the uploads previews.
@ -67,16 +67,16 @@ class MachinesController {
*/
$scope.fileinputClass = function (v) {
if (v) {
return 'fileinput-exists'
return 'fileinput-exists';
} else {
return 'fileinput-new'
return 'fileinput-new';
}
}
};
/**
* This will create a single new empty entry into the machine attachements list.
*/
$scope.addFile = function () { $scope.machine.machine_files_attributes.push({}) }
$scope.addFile = function () { $scope.machine.machine_files_attributes.push({}); };
/**
* This will remove the given file from the machine attachements list. If the file was previously uploaded
@ -85,13 +85,13 @@ class MachinesController {
* @param file {Object} the file to delete
*/
$scope.deleteFile = function (file) {
const index = $scope.machine.machine_files_attributes.indexOf(file)
const index = $scope.machine.machine_files_attributes.indexOf(file);
if (file.id != null) {
return file._destroy = true
return file._destroy = true;
} else {
return $scope.machine.machine_files_attributes.splice(index, 1)
return $scope.machine.machine_files_attributes.splice(index, 1);
}
}
};
}
}
@ -104,16 +104,16 @@ class MachinesController {
* @param e {Object} see https://docs.angularjs.org/guide/expression#-event-
*/
const _reserveMachine = function (machine, e) {
const _this = this
e.preventDefault()
e.stopPropagation()
const _this = this;
e.preventDefault();
e.stopPropagation();
// retrieve the full machine object
return machine = _this.Machine.get({ id: machine.id }, function () {
// if the currently logged'in user has completed the training for this machine, or this machine does not require
// a prior training, just redirect him to the machine's booking page
if (machine.current_user_is_training || (machine.trainings.length === 0)) {
return _this.$state.go('app.logged.machines_reserve', { id: machine.slug })
return _this.$state.go('app.logged.machines_reserve', { id: machine.slug });
} else {
// otherwise, if a user is authenticated ...
if (_this.$scope.isAuthenticated()) {
@ -123,59 +123,59 @@ const _reserveMachine = function (machine, e) {
return _this.$uibModal.open({
templateUrl: '<%= asset_path "machines/training_reservation_modal.html" %>',
controller: ['$scope', '$uibModalInstance', '$state', function ($scope, $uibModalInstance, $state) {
$scope.machine = machine
return $scope.cancel = function () { $uibModalInstance.dismiss('cancel') }
$scope.machine = machine;
return $scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
}
] })
] });
// ... but does not have booked the training, tell him to register for a training session first
// unless all associated trainings are disabled
} else {
// if all trainings are disabled, just redirect the user to the reservation calendar
if (machine.trainings.map(function (t) { return t.disabled }).reduce(function (acc, val) { return acc && val }, true)) {
return _this.$state.go('app.logged.machines_reserve', { id: machine.slug })
if (machine.trainings.map(function (t) { return t.disabled; }).reduce(function (acc, val) { return acc && val; }, true)) {
return _this.$state.go('app.logged.machines_reserve', { id: machine.slug });
// otherwise open the information modal
} else {
return _this.$uibModal.open({
templateUrl: '<%= asset_path "machines/request_training_modal.html" %>',
controller: ['$scope', '$uibModalInstance', '$state', function ($scope, $uibModalInstance, $state) {
$scope.machine = machine
$scope.member = _this.$scope.currentUser
$scope.machine = machine;
$scope.member = _this.$scope.currentUser;
// transform the name of the trainings associated with the machine to integrate them in a sentence
$scope.humanizeTrainings = function () {
let text = ''
let text = '';
angular.forEach($scope.machine.trainings, function (training) {
if (text.length > 0) {
text += _this._t('machines_list._or_the_')
text += _this._t('machines_list._or_the_');
}
return text += training.name.substr(0, 1).toLowerCase() + training.name.substr(1)
})
return text
}
return text += training.name.substr(0, 1).toLowerCase() + training.name.substr(1);
});
return text;
};
// modal is closed with validation
$scope.ok = function () {
$state.go('app.logged.trainings_reserve', { id: $scope.machine.trainings[0].id })
return $uibModalInstance.close(machine)
}
$state.go('app.logged.trainings_reserve', { id: $scope.machine.trainings[0].id });
return $uibModalInstance.close(machine);
};
// modal is closed with escaping
return $scope.cancel = function (e) {
e.preventDefault()
return $uibModalInstance.dismiss('cancel')
}
e.preventDefault();
return $uibModalInstance.dismiss('cancel');
};
}
] })
] });
}
}
// if the user is not logged, open the login modal window
} else {
return _this.$scope.login()
return _this.$scope.login();
}
}
})
}
});
};
/**
* Controller used in the public listing page, allowing everyone to see the list of machines
@ -183,12 +183,12 @@ const _reserveMachine = function (machine, e) {
Application.Controllers.controller('MachinesController', ['$scope', '$state', '_t', 'Machine', '$uibModal', 'machinesPromise',
function ($scope, $state, _t, Machine, $uibModal, machinesPromise) {
// Retrieve the list of machines
$scope.machines = machinesPromise
$scope.machines = machinesPromise;
/**
* Redirect the user to the machine details page
*/
$scope.showMachine = function (machine) { $state.go('app.public.machines_show', { id: machine.slug }) }
$scope.showMachine = function (machine) { $state.go('app.public.machines_show', { id: machine.slug }); };
/**
* Callback to book a reservation for the current machine
@ -199,40 +199,40 @@ Application.Controllers.controller('MachinesController', ['$scope', '$state', '_
_t,
$uibModal,
Machine
})
});
// Default: we show only enabled machines
$scope.machineFiltering = 'enabled'
$scope.machineFiltering = 'enabled';
// Available options for filtering machines by status
return $scope.filterDisabled = [
'enabled',
'disabled',
'all'
]
];
}
])
]);
/**
* Controller used in the machine creation page (admin)
*/
Application.Controllers.controller('NewMachineController', ['$scope', '$state', 'CSRF', function ($scope, $state, CSRF) {
CSRF.setMetaTags()
CSRF.setMetaTags();
// API URL where the form will be posted
$scope.actionUrl = '/api/machines/'
$scope.actionUrl = '/api/machines/';
// Form action on the above URL
$scope.method = 'post'
$scope.method = 'post';
// default machine parameters
$scope.machine =
{ machine_files_attributes: [] }
{ machine_files_attributes: [] };
// Using the MachinesController
return new MachinesController($scope, $state)
return new MachinesController($scope, $state);
}
])
]);
/**
* Controller used in the machine edition page (admin)
@ -242,13 +242,13 @@ Application.Controllers.controller('EditMachineController', ['$scope', '$state',
/* PUBLIC SCOPE */
// API URL where the form will be posted
$scope.actionUrl = `/api/machines/${$stateParams.id}`
$scope.actionUrl = `/api/machines/${$stateParams.id}`;
// Form action on the above URL
$scope.method = 'put'
$scope.method = 'put';
// Retrieve the details for the machine id in the URL, if an error occurs redirect the user to the machines list
$scope.machine = machinePromise
$scope.machine = machinePromise;
/* PRIVATE SCOPE */
@ -256,16 +256,16 @@ Application.Controllers.controller('EditMachineController', ['$scope', '$state',
* Kind of constructor: these actions will be realized first when the controller is loaded
*/
const initialize = function () {
CSRF.setMetaTags()
CSRF.setMetaTags();
// Using the MachinesController
return new MachinesController($scope, $state)
}
return new MachinesController($scope, $state);
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);
/**
* Controller used in the machine details page (public)
@ -273,7 +273,7 @@ Application.Controllers.controller('EditMachineController', ['$scope', '$state',
Application.Controllers.controller('ShowMachineController', ['$scope', '$state', '$uibModal', '$stateParams', '_t', 'Machine', 'growl', 'machinePromise', 'dialogs',
function ($scope, $state, $uibModal, $stateParams, _t, Machine, growl, machinePromise, dialogs) {
// Retrieve the details for the machine id in the URL, if an error occurs redirect the user to the machines list
$scope.machine = machinePromise
$scope.machine = machinePromise;
/**
* Callback to delete the current machine (admins only)
@ -281,7 +281,7 @@ Application.Controllers.controller('ShowMachineController', ['$scope', '$state',
$scope.delete = function (machine) {
// check the permissions
if ($scope.currentUser.role !== 'admin') {
console.error(_t('unauthorized_operation'))
console.error(_t('unauthorized_operation'));
} else {
dialogs.confirm({
resolve: {
@ -289,19 +289,19 @@ Application.Controllers.controller('ShowMachineController', ['$scope', '$state',
return {
title: _t('confirmation_required'),
msg: _t('do_you_really_want_to_delete_this_machine')
}
};
}
}
}
, function () { // deletion confirmed
// delete the machine then redirect to the machines listing
machine.$delete(
function () { $state.go('app.public.machines_list') },
function (error) { growl.warning(_t('the_machine_cant_be_deleted_because_it_is_already_reserved_by_some_users')); console.error(error) }
)
})
function () { $state.go('app.public.machines_list'); },
function (error) { growl.warning(_t('the_machine_cant_be_deleted_because_it_is_already_reserved_by_some_users')); console.error(error); }
);
});
}
}
};
/**
* Callback to book a reservation for the current machine
@ -312,9 +312,9 @@ Application.Controllers.controller('ShowMachineController', ['$scope', '$state',
_t,
$uibModal,
Machine
})
});
}
])
]);
/**
* Controller used in the machine reservation page (for logged users who have completed the training and admins).
@ -326,27 +326,27 @@ Application.Controllers.controller('ReserveMachineController', ['$scope', '$stat
/* PRIVATE STATIC CONSTANTS */
// Slot free to be booked
const FREE_SLOT_BORDER_COLOR = '<%= AvailabilityHelper::MACHINE_COLOR %>'
const FREE_SLOT_BORDER_COLOR = '<%= AvailabilityHelper::MACHINE_COLOR %>';
// Slot already booked by another user
const UNAVAILABLE_SLOT_BORDER_COLOR = '<%= AvailabilityHelper::MACHINE_IS_RESERVED_BY_USER %>'
const UNAVAILABLE_SLOT_BORDER_COLOR = '<%= AvailabilityHelper::MACHINE_IS_RESERVED_BY_USER %>';
// Slot already booked by the current user
const BOOKED_SLOT_BORDER_COLOR = '<%= AvailabilityHelper::IS_RESERVED_BY_CURRENT_USER %>'
const BOOKED_SLOT_BORDER_COLOR = '<%= AvailabilityHelper::IS_RESERVED_BY_CURRENT_USER %>';
/* PUBLIC SCOPE */
// bind the machine availabilities with full-Calendar events
$scope.eventSources = []
$scope.eventSources = [];
// indicates the state of the current view : calendar or plans information
$scope.plansAreShown = false
$scope.plansAreShown = false;
// will store the user's plan if he choosed to buy one
$scope.selectedPlan = null
$scope.selectedPlan = null;
// the moment when the plan selection changed for the last time, used to trigger changes in the cart
$scope.planSelectionTime = null
$scope.planSelectionTime = null;
// mapping of fullCalendar events.
$scope.events = {
@ -355,165 +355,165 @@ Application.Controllers.controller('ReserveMachineController', ['$scope', '$stat
placable: null, // Destination slot for the change
paid: [], // Slots that were just booked by the user (transaction ok)
moved: null // Slots that were just moved by the user (change done) -> {newSlot:* oldSlot: *}
}
};
// the moment when the slot selection changed for the last time, used to trigger changes in the cart
$scope.selectionTime = null
$scope.selectionTime = null;
// the last clicked event in the calender
$scope.selectedEvent = null
$scope.selectedEvent = null;
// the application global settings
$scope.settings = settingsPromise
$scope.settings = settingsPromise;
// list of plans, classified by group
$scope.plansClassifiedByGroup = []
$scope.plansClassifiedByGroup = [];
for (let group of Array.from(groupsPromise)) {
const groupObj = { id: group.id, name: group.name, plans: [] }
const groupObj = { id: group.id, name: group.name, plans: [] };
for (let plan of Array.from(plansPromise)) {
if (plan.group_id === group.id) { groupObj.plans.push(plan) }
if (plan.group_id === group.id) { groupObj.plans.push(plan); }
}
$scope.plansClassifiedByGroup.push(groupObj)
$scope.plansClassifiedByGroup.push(groupObj);
}
// the user to deal with, ie. the current user for non-admins
$scope.ctrl =
{ member: {} }
{ member: {} };
// current machine to reserve
$scope.machine = machinePromise
$scope.machine = machinePromise;
// fullCalendar (v2) configuration
$scope.calendarConfig = CalendarConfig({
minTime: moment.duration(moment(settingsPromise.booking_window_start).format('HH:mm:ss')),
maxTime: moment.duration(moment(settingsPromise.booking_window_end).format('HH:mm:ss')),
eventClick (event, jsEvent, view) {
return calendarEventClickCb(event, jsEvent, view)
return calendarEventClickCb(event, jsEvent, view);
},
eventRender (event, element, view) {
return eventRenderCb(event, element)
return eventRenderCb(event, element);
}
})
});
// Global config: message to the end user concerning the subscriptions rules
$scope.subscriptionExplicationsAlert = settingsPromise.subscription_explications_alert
$scope.subscriptionExplicationsAlert = settingsPromise.subscription_explications_alert;
// Global config: message to the end user concerning the machine bookings
$scope.machineExplicationsAlert = settingsPromise.machine_explications_alert
$scope.machineExplicationsAlert = settingsPromise.machine_explications_alert;
/**
* Change the last selected slot's appearence to looks like 'added to cart'
*/
$scope.markSlotAsAdded = function () {
$scope.selectedEvent.backgroundColor = FREE_SLOT_BORDER_COLOR
$scope.selectedEvent.title = _t('i_reserve')
return updateCalendar()
}
$scope.selectedEvent.backgroundColor = FREE_SLOT_BORDER_COLOR;
$scope.selectedEvent.title = _t('i_reserve');
return updateCalendar();
};
/**
* Change the last selected slot's appearence to looks like 'never added to cart'
*/
$scope.markSlotAsRemoved = function (slot) {
slot.backgroundColor = 'white'
slot.borderColor = FREE_SLOT_BORDER_COLOR
slot.title = ''
slot.isValid = false
slot.id = null
slot.is_reserved = false
slot.can_modify = false
slot.offered = false
return updateCalendar()
}
slot.backgroundColor = 'white';
slot.borderColor = FREE_SLOT_BORDER_COLOR;
slot.title = '';
slot.isValid = false;
slot.id = null;
slot.is_reserved = false;
slot.can_modify = false;
slot.offered = false;
return updateCalendar();
};
/**
* Callback when a slot was successfully cancelled. Reset the slot style as 'ready to book'
*/
$scope.slotCancelled = function () { $scope.markSlotAsRemoved($scope.selectedEvent) }
$scope.slotCancelled = function () { $scope.markSlotAsRemoved($scope.selectedEvent); };
/**
* Change the last selected slot's appearence to looks like 'currently looking for a new destination to exchange'
*/
$scope.markSlotAsModifying = function () {
$scope.selectedEvent.backgroundColor = '#eee'
$scope.selectedEvent.title = _t('i_change')
return updateCalendar()
}
$scope.selectedEvent.backgroundColor = '#eee';
$scope.selectedEvent.title = _t('i_change');
return updateCalendar();
};
/**
* Change the last selected slot's appearence to looks like 'the slot being exchanged will take this place'
*/
$scope.changeModifyMachineSlot = function () {
if ($scope.events.placable) {
$scope.events.placable.backgroundColor = 'white'
$scope.events.placable.title = ''
$scope.events.placable.backgroundColor = 'white';
$scope.events.placable.title = '';
}
if (!$scope.events.placable || ($scope.events.placable._id !== $scope.selectedEvent._id)) {
$scope.selectedEvent.backgroundColor = '#bbb'
$scope.selectedEvent.title = _t('i_shift')
$scope.selectedEvent.backgroundColor = '#bbb';
$scope.selectedEvent.title = _t('i_shift');
}
return updateCalendar()
}
return updateCalendar();
};
/**
* When modifying an already booked reservation, callback when the modification was successfully done.
*/
$scope.modifyMachineSlot = function () {
$scope.events.placable.title = $scope.currentUser.role !== 'admin' ? _t('i_ve_reserved') : _t('not_available')
$scope.events.placable.backgroundColor = 'white'
$scope.events.placable.borderColor = $scope.events.modifiable.borderColor
$scope.events.placable.id = $scope.events.modifiable.id
$scope.events.placable.is_reserved = true
$scope.events.placable.can_modify = true
$scope.events.placable.title = $scope.currentUser.role !== 'admin' ? _t('i_ve_reserved') : _t('not_available');
$scope.events.placable.backgroundColor = 'white';
$scope.events.placable.borderColor = $scope.events.modifiable.borderColor;
$scope.events.placable.id = $scope.events.modifiable.id;
$scope.events.placable.is_reserved = true;
$scope.events.placable.can_modify = true;
$scope.events.modifiable.backgroundColor = 'white'
$scope.events.modifiable.title = ''
$scope.events.modifiable.borderColor = FREE_SLOT_BORDER_COLOR
$scope.events.modifiable.id = null
$scope.events.modifiable.is_reserved = false
$scope.events.modifiable.can_modify = false
$scope.events.modifiable.backgroundColor = 'white';
$scope.events.modifiable.title = '';
$scope.events.modifiable.borderColor = FREE_SLOT_BORDER_COLOR;
$scope.events.modifiable.id = null;
$scope.events.modifiable.is_reserved = false;
$scope.events.modifiable.can_modify = false;
return updateCalendar()
}
return updateCalendar();
};
/**
* Cancel the current booking modification, reseting the whole process
*/
$scope.cancelModifyMachineSlot = function () {
if ($scope.events.placable) {
$scope.events.placable.backgroundColor = 'white'
$scope.events.placable.title = ''
$scope.events.placable.backgroundColor = 'white';
$scope.events.placable.title = '';
}
$scope.events.modifiable.title = $scope.currentUser.role !== 'admin' ? _t('i_ve_reserved') : _t('not_available')
$scope.events.modifiable.backgroundColor = 'white'
$scope.events.modifiable.title = $scope.currentUser.role !== 'admin' ? _t('i_ve_reserved') : _t('not_available');
$scope.events.modifiable.backgroundColor = 'white';
return updateCalendar()
}
return updateCalendar();
};
/**
* 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 () {
$scope.plansAreShown = false
$scope.selectedPlan = null
Member.get({ id: $scope.ctrl.member.id }, function (member) { $scope.ctrl.member = member })
}
$scope.plansAreShown = false;
$scope.selectedPlan = null;
Member.get({ id: $scope.ctrl.member.id }, function (member) { $scope.ctrl.member = member; });
};
/**
* Changes the user current view from the plan subsription screen to the machine reservation agenda
* @param e {Object} see https://docs.angularjs.org/guide/expression#-event-
*/
$scope.doNotSubscribePlan = function (e) {
e.preventDefault()
$scope.plansAreShown = false
$scope.selectPlan($scope.selectedPlan)
return $scope.planSelectionTime = new Date()
}
e.preventDefault();
$scope.plansAreShown = false;
$scope.selectPlan($scope.selectedPlan);
return $scope.planSelectionTime = new Date();
};
/**
* Switch the user's view from the reservation agenda to the plan subscription
*/
$scope.showPlans = function () { $scope.plansAreShown = true }
$scope.showPlans = function () { $scope.plansAreShown = true; };
/**
* Add the provided plan to the current shopping cart
@ -522,12 +522,12 @@ Application.Controllers.controller('ReserveMachineController', ['$scope', '$stat
$scope.selectPlan = function (plan) {
// toggle selected plan
if ($scope.selectedPlan !== plan) {
$scope.selectedPlan = plan
$scope.selectedPlan = plan;
} else {
$scope.selectedPlan = null
$scope.selectedPlan = null;
}
return $scope.planSelectionTime = new Date()
}
return $scope.planSelectionTime = new Date();
};
/**
* Once the reservation is booked (payment process successfully completed), change the event style
@ -536,34 +536,34 @@ Application.Controllers.controller('ReserveMachineController', ['$scope', '$stat
*/
$scope.afterPayment = function (reservation) {
angular.forEach($scope.events.reserved, function (machineSlot, key) {
machineSlot.is_reserved = true
machineSlot.can_modify = true
machineSlot.is_reserved = true;
machineSlot.can_modify = true;
if ($scope.currentUser.role !== 'admin') {
machineSlot.title = _t('i_ve_reserved')
machineSlot.borderColor = BOOKED_SLOT_BORDER_COLOR
updateMachineSlot(machineSlot, reservation, $scope.currentUser)
machineSlot.title = _t('i_ve_reserved');
machineSlot.borderColor = BOOKED_SLOT_BORDER_COLOR;
updateMachineSlot(machineSlot, reservation, $scope.currentUser);
} else {
machineSlot.title = _t('not_available')
machineSlot.borderColor = UNAVAILABLE_SLOT_BORDER_COLOR
updateMachineSlot(machineSlot, reservation, $scope.ctrl.member)
machineSlot.title = _t('not_available');
machineSlot.borderColor = UNAVAILABLE_SLOT_BORDER_COLOR;
updateMachineSlot(machineSlot, reservation, $scope.ctrl.member);
}
return machineSlot.backgroundColor = 'white'
})
return machineSlot.backgroundColor = 'white';
});
if ($scope.selectedPlan) {
$scope.ctrl.member.subscribed_plan = angular.copy($scope.selectedPlan)
Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan)
$scope.plansAreShown = false
$scope.selectedPlan = null
$scope.ctrl.member.subscribed_plan = angular.copy($scope.selectedPlan);
Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan);
$scope.plansAreShown = false;
$scope.selectedPlan = null;
}
return refetchCalendar()
}
return refetchCalendar();
};
/**
* To use as callback in Array.prototype.filter to get only enabled plans
*/
$scope.filterDisabledPlans = function (plan) { return !plan.disabled }
$scope.filterDisabledPlans = function (plan) { return !plan.disabled; };
/* PRIVATE SCOPE */
@ -575,13 +575,13 @@ Application.Controllers.controller('ReserveMachineController', ['$scope', '$stat
$scope.eventSources.push({
events: availabilities,
textColor: 'black'
})
})
});
});
if ($scope.currentUser.role !== 'admin') {
return $scope.ctrl.member = $scope.currentUser
return $scope.ctrl.member = $scope.currentUser;
}
}
};
/**
* Triggered when the user click on a reservation slot in the agenda.
@ -590,9 +590,9 @@ Application.Controllers.controller('ReserveMachineController', ['$scope', '$stat
* if it's too late).
*/
var calendarEventClickCb = function (event, jsEvent, view) {
$scope.selectedEvent = event
return $scope.selectionTime = new Date()
}
$scope.selectedEvent = event;
return $scope.selectionTime = new Date();
};
/**
* Triggered when fullCalendar tries to graphicaly render an event block.
@ -601,13 +601,13 @@ Application.Controllers.controller('ReserveMachineController', ['$scope', '$stat
*/
var eventRenderCb = function (event, element) {
if (($scope.currentUser.role === 'admin') && (event.tags.length > 0)) {
let html = ''
let html = '';
for (let tag of Array.from(event.tags)) {
html += `<span class='label label-success text-white' title='${tag.name}'>${tag.name}</span>`
html += `<span class='label label-success text-white' title='${tag.name}'>${tag.name}</span>`;
}
element.find('.fc-time').append(html)
element.find('.fc-time').append(html);
}
}
};
/**
* After payment, update the id of the newly reserved slot with the id returned by the server.
@ -620,28 +620,28 @@ Application.Controllers.controller('ReserveMachineController', ['$scope', '$stat
var updateMachineSlot = function (slot, reservation, user) {
angular.forEach(reservation.slots, function (s) {
if (slot.start.isSame(s.start_at)) {
slot.id = s.id
return slot.user = user
slot.id = s.id;
return slot.user = user;
}
})
}
});
};
/**
* Update the calendar's display to render the new attributes of the events
*/
var updateCalendar = function () { uiCalendarConfig.calendars.calendar.fullCalendar('rerenderEvents') }
var updateCalendar = function () { uiCalendarConfig.calendars.calendar.fullCalendar('rerenderEvents'); };
/**
* Asynchronously fetch the events from the API and refresh the calendar's view with these new events
*/
var refetchCalendar = function () {
$timeout(function () {
uiCalendarConfig.calendars.calendar.fullCalendar('refetchEvents')
return uiCalendarConfig.calendars.calendar.fullCalendar('rerenderEvents')
})
}
uiCalendarConfig.calendars.calendar.fullCalendar('refetchEvents');
return uiCalendarConfig.calendars.calendar.fullCalendar('rerenderEvents');
});
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
/**
* Navigation controller. List the links availables in the left navigation pane and their icon.
@ -48,14 +48,14 @@ Application.Controllers.controller('MainNavController', ['$scope', '$location',
linkIcon: 'th'
}
]
];
if (!Fablab.withoutPlans) {
$scope.navLinks.push({
state: 'app.public.plans',
linkText: 'subscriptions',
linkIcon: 'credit-card'
})
});
}
if (!Fablab.withoutSpaces) {
@ -63,10 +63,10 @@ Application.Controllers.controller('MainNavController', ['$scope', '$location',
state: 'app.public.spaces_list',
linkText: 'reserve_a_space',
linkIcon: 'rocket'
})
});
}
Fablab.adminNavLinks = Fablab.adminNavLinks || []
Fablab.adminNavLinks = Fablab.adminNavLinks || [];
const adminNavLinks = [
{
state: 'app.admin.trainings',
@ -123,16 +123,16 @@ Application.Controllers.controller('MainNavController', ['$scope', '$location',
linkText: 'open_api_clients',
linkIcon: 'cloud'
}
].concat(Fablab.adminNavLinks)
].concat(Fablab.adminNavLinks);
$scope.adminNavLinks = adminNavLinks
$scope.adminNavLinks = adminNavLinks;
if (!Fablab.withoutSpaces) {
return $scope.adminNavLinks.splice(7, 0, {
state: 'app.public.spaces_list',
linkText: 'manage_the_spaces',
linkIcon: 'rocket'
})
});
}
}
])
]);

View File

@ -11,7 +11,7 @@
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
/**
* Controller used in the members listing page
@ -20,37 +20,37 @@ Application.Controllers.controller('MembersController', ['$scope', 'Member', 'me
/* PRIVATE STATIC CONSTANTS */
// number of invoices loaded each time we click on 'load more...'
const MEMBERS_PER_PAGE = 10
const MEMBERS_PER_PAGE = 10;
/* PUBLIC SCOPE */
// currently displayed page of members
$scope.page = 1
$scope.page = 1;
// members list
$scope.members = membersPromise
$scope.members = membersPromise;
// true when all members are loaded
$scope.noMoreResults = false
$scope.noMoreResults = false;
/**
* Callback for the 'load more' button.
* Will load the next results of the current search, if any
*/
$scope.showNextMembers = function () {
$scope.page += 1
$scope.page += 1;
return Member.query({
requested_attributes: '[profile]',
page: $scope.page,
size: MEMBERS_PER_PAGE
}, function (members) {
$scope.members = $scope.members.concat(members)
$scope.members = $scope.members.concat(members);
if (!members[0] || (members[0].maxMembers <= $scope.members.length)) {
return $scope.noMoreResults = true
return $scope.noMoreResults = true;
}
})
}
});
};
/* PRIVATE SCOPE */
@ -59,15 +59,15 @@ Application.Controllers.controller('MembersController', ['$scope', 'Member', 'me
*/
const initialize = function () {
if (!membersPromise[0] || (membersPromise[0].maxMembers <= $scope.members.length)) {
return $scope.noMoreResults = true
return $scope.noMoreResults = true;
}
}
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);
/**
* Controller used when editing the current user's profile
@ -77,36 +77,36 @@ Application.Controllers.controller('EditProfileController', ['$scope', '$rootSco
/* PUBLIC SCOPE */
// API URL where the form will be posted
$scope.actionUrl = `/api/members/${$scope.currentUser.id}`
$scope.actionUrl = `/api/members/${$scope.currentUser.id}`;
// list of groups
$scope.groups = groups.filter(g => !g.disabled)
$scope.groups = groups.filter(g => !g.disabled);
// Form action on the above URL
$scope.method = 'patch'
$scope.method = 'patch';
// Current user's profile
$scope.user = memberPromise
$scope.user = memberPromise;
// default : do not show the group changing form
$scope.group =
{ change: false }
{ change: false };
// group ID of the current/selected user
$scope.userGroup = memberPromise.group_id
$scope.userGroup = memberPromise.group_id;
// active authentication provider parameters
$scope.activeProvider = activeProviderPromise
$scope.activeProvider = activeProviderPromise;
// allow the user to change his password except if he connect from an SSO
$scope.preventPassword = false
$scope.preventPassword = false;
// mapping of fields to disable
$scope.preventField = {}
$scope.preventField = {};
// Should the passord be modified?
$scope.password =
{ change: false }
{ change: false };
// Angular-Bootstrap datepicker configuration for birthday
$scope.datePicker = {
@ -115,7 +115,7 @@ Application.Controllers.controller('EditProfileController', ['$scope', '$rootSco
options: {
startingDay: Fablab.weekStartingDay
}
}
};
/**
* Return the group object, identified by the ID set in $scope.userGroup
@ -123,36 +123,36 @@ Application.Controllers.controller('EditProfileController', ['$scope', '$rootSco
$scope.getUserGroup = function () {
for (let group of Array.from($scope.groups)) {
if (group.id === $scope.userGroup) {
return group
return group;
}
}
}
};
/**
* Change the group of the current user to the one set in $scope.userGroup
*/
$scope.selectGroup = () =>
Member.update({ id: $scope.user.id }, { user: { group_id: $scope.userGroup } }, function (user) {
$scope.user = user
$rootScope.currentUser = user
Auth._currentUser.group_id = user.group_id
$scope.group.change = false
return growl.success(_t('your_group_has_been_successfully_changed'))
$scope.user = user;
$rootScope.currentUser = user;
Auth._currentUser.group_id = user.group_id;
$scope.group.change = false;
return growl.success(_t('your_group_has_been_successfully_changed'));
}
, function (err) {
growl.error(_t('an_unexpected_error_prevented_your_group_from_being_changed'))
return console.error(err)
})
growl.error(_t('an_unexpected_error_prevented_your_group_from_being_changed'));
return console.error(err);
});
/**
* Callback to diplay the datepicker as a dropdown when clicking on the input field
* @param $event {Object} jQuery event object
*/
$scope.openDatePicker = function ($event) {
$event.preventDefault()
$event.stopPropagation()
return $scope.datePicker.opened = true
}
$event.preventDefault();
$event.stopPropagation();
return $scope.datePicker.opened = true;
};
/**
* For use with ngUpload (https://github.com/twilson63/ngUpload).
@ -163,7 +163,7 @@ Application.Controllers.controller('EditProfileController', ['$scope', '$rootSco
*/
$scope.submited = function (content) {
if ((content.id == null)) {
$scope.alerts = []
$scope.alerts = [];
return angular.forEach(content, (v, k) =>
angular.forEach(v, err =>
$scope.alerts.push({
@ -171,18 +171,18 @@ Application.Controllers.controller('EditProfileController', ['$scope', '$rootSco
type: 'danger'
})
)
)
);
} else {
$scope.currentUser.profile.user_avatar = content.profile.user_avatar
Auth._currentUser.profile.user_avatar = content.profile.user_avatar
$scope.currentUser.name = content.name
Auth._currentUser.name = content.name
$scope.currentUser = content
Auth._currentUser = content
$rootScope.currentUser = content
return $state.go('app.public.home')
$scope.currentUser.profile.user_avatar = content.profile.user_avatar;
Auth._currentUser.profile.user_avatar = content.profile.user_avatar;
$scope.currentUser.name = content.name;
Auth._currentUser.name = content.name;
$scope.currentUser = content;
Auth._currentUser = content;
$rootScope.currentUser = content;
return $state.go('app.public.home');
}
}
};
/**
* Ask for confirmation then delete the current user's account
@ -195,22 +195,22 @@ Application.Controllers.controller('EditProfileController', ['$scope', '$rootSco
return {
title: _t('confirmation_required'),
msg: _t('do_you_really_want_to_delete_your_account') + ' ' + _t('all_data_relative_to_your_projects_will_be_lost')
}
};
}
}
}
, () => // cancel confirmed
Member.remove({ id: user.id }, () =>
Auth.logout().then(function () {
$state.go('app.public.home')
return growl.success(_t('your_user_account_has_been_successfully_deleted_goodbye'))
$state.go('app.public.home');
return growl.success(_t('your_user_account_has_been_successfully_deleted_goodbye'));
})
, function (error) {
console.log(error)
return growl.error(_t('an_error_occured_preventing_your_account_from_being_deleted'))
console.log(error);
return growl.error(_t('an_error_occured_preventing_your_account_from_being_deleted'));
})
)
);
/**
* For use with 'ng-class', returns the CSS class name for the uploads previews.
@ -219,11 +219,11 @@ Application.Controllers.controller('EditProfileController', ['$scope', '$rootSco
*/
$scope.fileinputClass = function (v) {
if (v) {
return 'fileinput-exists'
return 'fileinput-exists';
} else {
return 'fileinput-new'
return 'fileinput-new';
}
}
};
/**
* Check if the of the properties editable by the user are linked to the SSO
@ -232,22 +232,22 @@ Application.Controllers.controller('EditProfileController', ['$scope', '$rootSco
$scope.hasSsoFields = () =>
// if check if keys > 1 because there's a minimum of 1 mapping (id <-> provider-uid)
// so the user may want to edit his profile on the SSO if at least 2 mappings exists
Object.keys($scope.preventField).length > 1
Object.keys($scope.preventField).length > 1;
/**
* Disconnect and re-connect the user to the SSO to force the synchronisation of the profile's data
*/
$scope.syncProfile = () =>
Auth.logout().then(function (oldUser) {
Session.destroy()
$rootScope.currentUser = null
$rootScope.toCheckNotifications = false
Session.destroy();
$rootScope.currentUser = null;
$rootScope.toCheckNotifications = false;
$scope.notifications = {
total: 0,
unread: 0
}
return $window.location.href = $scope.activeProvider.link_to_sso_connect
})
};
return $window.location.href = $scope.activeProvider.link_to_sso_connect;
});
/* PRIVATE SCOPE */
@ -255,42 +255,42 @@ Application.Controllers.controller('EditProfileController', ['$scope', '$rootSco
* Kind of constructor: these actions will be realized first when the controller is loaded
*/
const initialize = function () {
CSRF.setMetaTags()
CSRF.setMetaTags();
// init the birth date to JS object
$scope.user.profile.birthday = moment($scope.user.profile.birthday).toDate()
$scope.user.profile.birthday = moment($scope.user.profile.birthday).toDate();
if ($scope.activeProvider.providable_type !== 'DatabaseProvider') {
$scope.preventPassword = true
$scope.preventPassword = true;
}
// bind fields protection with sso fields
return angular.forEach(activeProviderPromise.mapping, map => $scope.preventField[map] = true)
}
return angular.forEach(activeProviderPromise.mapping, map => $scope.preventField[map] = true);
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);
/**
* Controller used on the public user's profile page (seeing another user's profile)
*/
Application.Controllers.controller('ShowProfileController', ['$scope', 'memberPromise', 'SocialNetworks', function ($scope, memberPromise, SocialNetworks) {
// Selected user's information
$scope.user = memberPromise // DEPENDENCY WITH NAVINUM GAMIFICATION PLUGIN !!!!
$scope.user = memberPromise; // DEPENDENCY WITH NAVINUM GAMIFICATION PLUGIN !!!!
// List of social networks associated with this user and toggle 'show all' state
$scope.social = {
showAllLinks: false,
networks: SocialNetworks
}
};
/* PRIVATE SCOPE */
/**
* Kind of constructor: these actions will be realized first when the controller is loaded
*/
const initialize = () => $scope.social.networks = filterNetworks()
const initialize = () => $scope.social.networks = filterNetworks();
/**
* Filter social network or website that are associated with the profile of the user provided in promise
@ -298,17 +298,17 @@ Application.Controllers.controller('ShowProfileController', ['$scope', 'memberPr
* @return {Array}
*/
var filterNetworks = function () {
const networks = []
const networks = [];
for (let network of Array.from(SocialNetworks)) {
if ($scope.user.profile[network] && ($scope.user.profile[network].length > 0)) {
networks.push(network)
networks.push(network);
}
}
return networks
}
return networks;
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);

View File

@ -10,7 +10,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
/**
* Controller used in notifications page
@ -20,27 +20,27 @@ Application.Controllers.controller('NotificationsController', ['$scope', 'Notifi
/* PRIVATE STATIC CONSTANTS */
// Number of notifications added to the page when the user clicks on 'load next notifications'
const NOTIFICATIONS_PER_PAGE = 15
const NOTIFICATIONS_PER_PAGE = 15;
/* PUBLIC SCOPE */
// Array containg the archived notifications (already read)
$scope.notificationsRead = []
$scope.notificationsRead = [];
// Array containg the new notifications (not read)
$scope.notificationsUnread = []
$scope.notificationsUnread = [];
// Total number of notifications for the current user
$scope.total = 0
$scope.total = 0;
// Total number of unread notifications for the current user
$scope.totalUnread = 0
$scope.totalUnread = 0;
// By default, the pagination mode is activated to limit the page size
$scope.paginateActive = true
$scope.paginateActive = true;
// The currently displayed page number
$scope.page = 1
$scope.page = 1;
/**
* Mark the provided notification as read, updating its status on the server and moving it
@ -49,22 +49,22 @@ Application.Controllers.controller('NotificationsController', ['$scope', 'Notifi
* @param e {Object} see https://docs.angularjs.org/guide/expression#-event-
*/
$scope.markAsRead = function (notification, e) {
e.preventDefault()
e.preventDefault();
return Notification.update({ id: notification.id }, {
id: notification.id,
is_read: true
}
, function (updatedNotif) {
// remove notif from unreads
const index = $scope.notificationsUnread.indexOf(notification)
$scope.notificationsUnread.splice(index, 1)
const index = $scope.notificationsUnread.indexOf(notification);
$scope.notificationsUnread.splice(index, 1);
// add update notif to read
$scope.notificationsRead.push(updatedNotif)
$scope.notificationsRead.push(updatedNotif);
// update counters
$scope.$parent.notifications.unread -= 1
return $scope.totalUnread -= 1
})
}
$scope.$parent.notifications.unread -= 1;
return $scope.totalUnread -= 1;
});
};
/**
* Mark every unread notifications as read and move them for the unread list to to read array.
@ -74,15 +74,15 @@ Application.Controllers.controller('NotificationsController', ['$scope', 'Notifi
, function () { // success
// add notifs to read
angular.forEach($scope.notificationsUnread, function (n) {
n.is_read = true
return $scope.notificationsRead.push(n)
})
n.is_read = true;
return $scope.notificationsRead.push(n);
});
// clear unread
$scope.notificationsUnread = []
$scope.notificationsUnread = [];
// update counters
$scope.$parent.notifications.unread = 0
return $scope.totalUnread = 0
})
$scope.$parent.notifications.unread = 0;
return $scope.totalUnread = 0;
});
/**
* Request the server to retrieve the next notifications and add them
@ -90,29 +90,29 @@ Application.Controllers.controller('NotificationsController', ['$scope', 'Notifi
*/
$scope.addMoreNotifications = function () {
Notification.query({ page: $scope.page }, function (notifications) {
$scope.total = notifications.totals.total
$scope.totalUnread = notifications.totals.unread
$scope.total = notifications.totals.total;
$scope.totalUnread = notifications.totals.unread;
angular.forEach(notifications.notifications, function (notif) {
if (notif.is_read) {
return $scope.notificationsRead.push(notif)
return $scope.notificationsRead.push(notif);
} else {
return $scope.notificationsUnread.push(notif)
return $scope.notificationsUnread.push(notif);
}
})
return $scope.paginateActive = (notifications.totals.total > ($scope.notificationsRead.length + $scope.notificationsUnread.length))
})
});
return $scope.paginateActive = (notifications.totals.total > ($scope.notificationsRead.length + $scope.notificationsUnread.length));
});
return $scope.page += 1
}
return $scope.page += 1;
};
/* PRIVATE SCOPE */
/**
* Kind of constructor: these actions will be realized first when the controller is loaded
*/
const initialize = () => $scope.addMoreNotifications()
const initialize = () => $scope.addMoreNotifications();
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);

View File

@ -10,69 +10,69 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScope', '$state', '$uibModal', 'Auth', 'dialogs', 'growl', 'plansPromise', 'groupsPromise', 'Subscription', 'Member', 'subscriptionExplicationsPromise', '_t', 'Wallet', 'helpers',
function ($scope, $rootScope, $state, $uibModal, Auth, dialogs, growl, plansPromise, groupsPromise, Subscription, Member, subscriptionExplicationsPromise, _t, Wallet, helpers) {
/* PUBLIC SCOPE */
// list of groups
$scope.groups = groupsPromise.filter(function (g) { return (g.slug !== 'admins') & !g.disabled })
$scope.groups = groupsPromise.filter(function (g) { return (g.slug !== 'admins') & !g.disabled; });
// default : do not show the group changing form
// group ID of the current/selected user
$scope.group = {
change: false,
id: null
}
};
// list of plans, classified by group
$scope.plansClassifiedByGroup = []
$scope.plansClassifiedByGroup = [];
for (var group of Array.from($scope.groups)) {
const groupObj = { id: group.id, name: group.name, plans: [] }
const groupObj = { id: group.id, name: group.name, plans: [] };
for (let plan of Array.from(plansPromise)) {
if (plan.group_id === group.id) { groupObj.plans.push(plan) }
if (plan.group_id === group.id) { groupObj.plans.push(plan); }
}
$scope.plansClassifiedByGroup.push(groupObj)
$scope.plansClassifiedByGroup.push(groupObj);
}
// user to deal with
$scope.ctrl = {
member: null,
member_id: null
}
};
// already subscribed plan of the current user
$scope.paid =
{ plan: null }
{ plan: null };
// plan to subscribe (shopping cart)
$scope.selectedPlan = null
$scope.selectedPlan = null;
// Discount coupon to apply to the basket, if any
$scope.coupon =
{ applied: null }
{ applied: null };
// Storage for the total price (plan price + coupon, if any)
$scope.cart =
{ total: null }
{ total: null };
// text that appears in the bottom-right box of the page (subscriptions rules details)
$scope.subscriptionExplicationsAlert = subscriptionExplicationsPromise.setting.value
$scope.subscriptionExplicationsAlert = subscriptionExplicationsPromise.setting.value;
/**
* Callback to deal with the subscription of the user selected in the dropdown list instead of the current user's
* subscription. (admins only)
*/
$scope.updateMember = function () {
$scope.selectedPlan = null
$scope.paid.plan = null
$scope.group.change = false
$scope.selectedPlan = null;
$scope.paid.plan = null;
$scope.group.change = false;
return Member.get({ id: $scope.ctrl.member.id }, function (member) {
$scope.ctrl.member = member
return $scope.group.id = $scope.ctrl.member.group_id
})
}
$scope.ctrl.member = member;
return $scope.group.id = $scope.ctrl.member.group_id;
});
};
/**
* Add the provided plan to the shopping basket
@ -81,31 +81,31 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
$scope.selectPlan = function (plan) {
if ($scope.isAuthenticated()) {
if ($scope.selectedPlan !== plan) {
$scope.selectedPlan = plan
return updateCartPrice()
$scope.selectedPlan = plan;
return updateCartPrice();
} else {
return $scope.selectedPlan = null
return $scope.selectedPlan = null;
}
} else {
return $scope.login()
return $scope.login();
}
}
};
/**
* Callback to trigger the payment process of the subscription
*/
$scope.openSubscribePlanModal = function () {
Wallet.getWalletByUser({ user_id: $scope.ctrl.member.id }, function (wallet) {
const amountToPay = helpers.getAmountToPay($scope.cart.total, wallet.amount)
const amountToPay = helpers.getAmountToPay($scope.cart.total, wallet.amount);
if (($scope.currentUser.role !== 'admin') && (amountToPay > 0)) {
return payByStripe()
return payByStripe();
} else {
if (($scope.currentUser.role === 'admin') || (amountToPay === 0)) {
return payOnSite()
return payOnSite();
}
}
})
}
});
};
/**
* Return the group object, identified by the ID set in $scope.group.id
@ -113,35 +113,35 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
$scope.getUserGroup = function () {
for (group of Array.from($scope.groups)) {
if (group.id === $scope.group.id) {
return group
return group;
}
}
}
};
/**
* Change the group of the current/selected user to the one set in $scope.group.id
*/
$scope.selectGroup = function () {
Member.update({ id: $scope.ctrl.member.id }, { user: { group_id: $scope.group.id } }, function (user) {
$scope.ctrl.member = user
$scope.group.change = false
$scope.ctrl.member = user;
$scope.group.change = false;
if ($scope.currentUser.role !== 'admin') {
$rootScope.currentUser = user
Auth._currentUser.group_id = user.group_id
growl.success(_t('your_group_was_successfully_changed'))
$rootScope.currentUser = user;
Auth._currentUser.group_id = user.group_id;
growl.success(_t('your_group_was_successfully_changed'));
} else {
growl.success(_t('the_user_s_group_was_successfully_changed'))
growl.success(_t('the_user_s_group_was_successfully_changed'));
}
}
, function (err) {
if ($scope.currentUser.role !== 'admin') {
growl.error(_t('an_error_prevented_your_group_from_being_changed'))
growl.error(_t('an_error_prevented_your_group_from_being_changed'));
} else {
growl.error(_t('an_error_prevented_to_change_the_user_s_group'))
growl.error(_t('an_error_prevented_to_change_the_user_s_group'));
}
console.error(err)
})
}
console.error(err);
});
};
/**
* Return an enumerable meaninful string for the gender of the provider user
@ -150,9 +150,9 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
*/
$scope.getGender = function (user) {
if (user && user.profile) {
if (user.profile.gender === 'true') { return 'male' } else { return 'female' }
} else { return 'other' }
}
if (user.profile.gender === 'true') { return 'male'; } else { return 'female'; }
} else { return 'other'; }
};
/**
* Test if the provided date is in the future
@ -160,13 +160,13 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
* @return {boolean}
*/
$scope.isInFuture = function (dateTime) {
return (moment().diff(moment(dateTime)) < 0)
}
return (moment().diff(moment(dateTime)) < 0);
};
/**
* To use as callback in Array.prototype.filter to get only enabled plans
*/
$scope.filterDisabledPlans = function (plan) { return !plan.disabled }
$scope.filterDisabledPlans = function (plan) { return !plan.disabled; };
/* PRIVATE SCOPE */
@ -176,21 +176,21 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
const initialize = function () {
if ($scope.currentUser) {
if ($scope.currentUser.role !== 'admin') {
$scope.ctrl.member = $scope.currentUser
$scope.paid.plan = $scope.currentUser.subscribed_plan
$scope.group.id = $scope.currentUser.group_id
$scope.ctrl.member = $scope.currentUser;
$scope.paid.plan = $scope.currentUser.subscribed_plan;
$scope.group.id = $scope.currentUser.group_id;
}
}
$scope.$on('devise:new-session', function (event, user) { $scope.ctrl.member = user })
$scope.$on('devise:new-session', function (event, user) { $scope.ctrl.member = user; });
// 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 updateCartPrice()
return updateCartPrice();
}
})
}
});
};
/**
* Compute the total amount for the current reservation according to the previously set parameters
@ -199,21 +199,21 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
var updateCartPrice = function () {
// first we check that a user was selected
if (Object.keys($scope.ctrl.member).length > 0) {
$scope.cart.total = $scope.selectedPlan.amount
$scope.cart.total = $scope.selectedPlan.amount;
// apply the coupon if any
if ($scope.coupon.applied) {
let discount
let discount;
if ($scope.coupon.applied.type === 'percent_off') {
discount = ($scope.cart.total * $scope.coupon.applied.percent_off) / 100
discount = ($scope.cart.total * $scope.coupon.applied.percent_off) / 100;
} else if ($scope.coupon.applied.type === 'amount_off') {
discount = $scope.coupon.applied.amount_off
discount = $scope.coupon.applied.amount_off;
}
return $scope.cart.total -= discount
return $scope.cart.total -= discount;
}
} else {
return $scope.reserve.amountTotal = null
return $scope.reserve.amountTotal = null;
}
}
};
/**
* Open a modal window which trigger the stripe payment process
@ -223,30 +223,30 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
templateUrl: '<%= asset_path "stripe/payment_modal.html" %>',
size: 'md',
resolve: {
selectedPlan () { return $scope.selectedPlan },
member () { return $scope.ctrl.member },
price () { return $scope.cart.total },
selectedPlan () { return $scope.selectedPlan; },
member () { return $scope.ctrl.member; },
price () { return $scope.cart.total; },
wallet () {
return Wallet.getWalletByUser({ user_id: $scope.ctrl.member.id }).$promise
return Wallet.getWalletByUser({ user_id: $scope.ctrl.member.id }).$promise;
},
coupon () { return $scope.coupon.applied }
coupon () { return $scope.coupon.applied; }
},
controller: ['$scope', '$uibModalInstance', '$state', 'selectedPlan', 'member', 'price', 'Subscription', 'CustomAsset', 'wallet', 'helpers', '$filter', 'coupon',
function ($scope, $uibModalInstance, $state, selectedPlan, member, price, Subscription, CustomAsset, wallet, helpers, $filter, coupon) {
// User's wallet amount
$scope.walletAmount = wallet.amount
$scope.walletAmount = wallet.amount;
// Final price to pay by the user
$scope.amount = helpers.getAmountToPay(price, wallet.amount)
$scope.amount = helpers.getAmountToPay(price, wallet.amount);
// The plan that the user is about to subscribe
$scope.selectedPlan = selectedPlan
$scope.selectedPlan = selectedPlan;
// Used in wallet info template to interpolate some translations
$scope.numberFilter = $filter('number')
$scope.numberFilter = $filter('number');
// retrieve the CGV
CustomAsset.get({ name: 'cgv-file' }, function (cgv) { $scope.cgv = cgv.custom_asset })
CustomAsset.get({ name: 'cgv-file' }, function (cgv) { $scope.cgv = cgv.custom_asset; });
/**
* Callback for click on the 'proceed' button.
@ -255,9 +255,9 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
*/
$scope.payment = function (status, response) {
if (response.error) {
growl.error(response.error.message)
growl.error(response.error.message);
} else {
$scope.attempting = true
$scope.attempting = true;
Subscription.save({
coupon_code: ((coupon ? coupon.code : undefined)),
subscription: {
@ -267,26 +267,26 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
}
}
, function (data) { // success
$uibModalInstance.close(data)
$uibModalInstance.close(data);
}
, function (data, status) { // failed
$scope.alerts = []
$scope.alerts.push({ msg: _t('an_error_occured_during_the_payment_process_please_try_again_later'), type: 'danger' })
$scope.attempting = false
$scope.alerts = [];
$scope.alerts.push({ msg: _t('an_error_occured_during_the_payment_process_please_try_again_later'), type: 'danger' });
$scope.attempting = false;
}
)
);
}
}
};
}
]
}).result['finally'](null).then(function (subscription) {
$scope.ctrl.member.subscribed_plan = angular.copy($scope.selectedPlan)
Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan)
$scope.paid.plan = angular.copy($scope.selectedPlan)
$scope.selectedPlan = null
$scope.coupon.applied = null
})
}
$scope.ctrl.member.subscribed_plan = angular.copy($scope.selectedPlan);
Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan);
$scope.paid.plan = angular.copy($scope.selectedPlan);
$scope.selectedPlan = null;
$scope.coupon.applied = null;
});
};
/**
* Open a modal window which trigger the local payment process
@ -296,42 +296,42 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
templateUrl: '<%= asset_path "plans/payment_modal.html" %>',
size: 'sm',
resolve: {
selectedPlan () { return $scope.selectedPlan },
member () { return $scope.ctrl.member },
price () { return $scope.cart.total },
selectedPlan () { return $scope.selectedPlan; },
member () { return $scope.ctrl.member; },
price () { return $scope.cart.total; },
wallet () {
return Wallet.getWalletByUser({ user_id: $scope.ctrl.member.id }).$promise
return Wallet.getWalletByUser({ user_id: $scope.ctrl.member.id }).$promise;
},
coupon () { return $scope.coupon.applied }
coupon () { return $scope.coupon.applied; }
},
controller: ['$scope', '$uibModalInstance', '$state', 'selectedPlan', 'member', 'price', 'Subscription', 'wallet', 'helpers', '$filter', 'coupon',
function ($scope, $uibModalInstance, $state, selectedPlan, member, price, Subscription, wallet, helpers, $filter, coupon) {
// user wallet amount
$scope.walletAmount = wallet.amount
$scope.walletAmount = wallet.amount;
// subcription price, coupon subtracted if any
$scope.price = price
$scope.price = price;
// price to pay
$scope.amount = helpers.getAmountToPay($scope.price, wallet.amount)
$scope.amount = helpers.getAmountToPay($scope.price, wallet.amount);
// Used in wallet info template to interpolate some translations
$scope.numberFilter = $filter('number')
$scope.numberFilter = $filter('number');
// The plan that the user is about to subscribe
$scope.plan = selectedPlan
$scope.plan = selectedPlan;
// The member who is subscribing a plan
$scope.member = member
$scope.member = member;
// 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');
}
}
@ -340,7 +340,7 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
* Save the subscription to the API
*/
$scope.ok = function () {
$scope.attempting = true
$scope.attempting = true;
Subscription.save({
coupon_code: ((coupon ? coupon.code : undefined)),
subscription: {
@ -349,34 +349,34 @@ Application.Controllers.controller('PlansIndexController', ['$scope', '$rootScop
}
}
, function (data) { // success
$uibModalInstance.close(data)
$uibModalInstance.close(data);
}
, function (data, status) { // failed
$scope.alerts = []
$scope.alerts.push({ msg: _t('an_error_occured_during_the_payment_process_please_try_again_later'), type: 'danger' })
$scope.attempting = false
$scope.alerts = [];
$scope.alerts.push({ msg: _t('an_error_occured_during_the_payment_process_please_try_again_later'), type: 'danger' });
$scope.attempting = false;
}
)
}
);
};
/**
* Callback for the 'cancel' button.
* Close the modal box.
*/
$scope.cancel = function () { $uibModalInstance.dismiss('cancel') }
$scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
}
]
}).result['finally'](null).then(function (reservation) {
$scope.ctrl.member.subscribed_plan = angular.copy($scope.selectedPlan)
Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan)
$scope.ctrl.member = null
$scope.paid.plan = angular.copy($scope.selectedPlan)
$scope.selectedPlan = null
return $scope.coupon.applied = null
})
}
$scope.ctrl.member.subscribed_plan = angular.copy($scope.selectedPlan);
Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan);
$scope.ctrl.member = null;
$scope.paid.plan = angular.copy($scope.selectedPlan);
$scope.selectedPlan = null;
return $scope.coupon.applied = null;
});
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);

View File

@ -11,41 +11,41 @@
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Controllers.controller('CompleteProfileController', ['$scope', '$rootScope', '$state', '$window', '_t', 'growl', 'CSRF', 'Auth', 'Member', 'settingsPromise', 'activeProviderPromise', 'groupsPromise', 'cguFile', 'memberPromise', 'Session', 'dialogs', 'AuthProvider',
function ($scope, $rootScope, $state, $window, _t, growl, CSRF, Auth, Member, settingsPromise, activeProviderPromise, groupsPromise, cguFile, memberPromise, Session, dialogs, AuthProvider) {
/* PUBLIC SCOPE */
// API URL where the form will be posted
$scope.actionUrl = `/api/members/${memberPromise.id}`
$scope.actionUrl = `/api/members/${memberPromise.id}`;
// Form action on the above URL
$scope.method = 'patch'
$scope.method = 'patch';
// genre of the application name (eg. "_le_ Fablab" or "_la_ Fabrique")
$scope.nameGenre = settingsPromise.name_genre
$scope.nameGenre = settingsPromise.name_genre;
// name of the current fablab application (eg. "Fablab de la Casemate")
$scope.fablabName = settingsPromise.fablab_name
$scope.fablabName = settingsPromise.fablab_name;
// information from the current SSO provider
$scope.activeProvider = activeProviderPromise
$scope.activeProvider = activeProviderPromise;
// list of user's groups (student/standard/...)
$scope.groups = groupsPromise
$scope.groups = groupsPromise;
// current user, contains information retrieved from the SSO
$scope.user = memberPromise
$scope.user = memberPromise;
// disallow the user to change his password as he connect from SSO
$scope.preventPassword = true
$scope.preventPassword = true;
// mapping of fields to disable
$scope.preventField = {}
$scope.preventField = {};
// CGU
$scope.cgu = cguFile.custom_asset
$scope.cgu = cguFile.custom_asset;
// Angular-Bootstrap datepicker configuration for birthday
$scope.datePicker = {
@ -54,17 +54,17 @@ Application.Controllers.controller('CompleteProfileController', ['$scope', '$roo
options: {
startingDay: Fablab.weekStartingDay
}
}
};
/**
* Callback to diplay the datepicker as a dropdown when clicking on the input field
* @param $event {Object} jQuery event object
*/
$scope.openDatePicker = function ($event) {
$event.preventDefault()
$event.stopPropagation()
return $scope.datePicker.opened = true
}
$event.preventDefault();
$event.stopPropagation();
return $scope.datePicker.opened = true;
};
/**
* For use with ngUpload (https://github.com/twilson63/ngUpload).
@ -75,26 +75,26 @@ Application.Controllers.controller('CompleteProfileController', ['$scope', '$roo
*/
$scope.submited = function (content) {
if ((content.id == null)) {
$scope.alerts = []
$scope.alerts = [];
angular.forEach(content, function (v, k) {
angular.forEach(v, function (err) {
$scope.alerts.push({
msg: k + ': ' + err,
type: 'danger'
})
})
})
});
});
});
} else {
$scope.user.profile.user_avatar = content.profile.user_avatar
Auth._currentUser.profile.user_avatar = content.profile.user_avatar
$scope.user.name = content.name
Auth._currentUser.name = content.name
$scope.user = content
Auth._currentUser = content
$rootScope.currentUser = content
return $state.go('app.public.home')
$scope.user.profile.user_avatar = content.profile.user_avatar;
Auth._currentUser.profile.user_avatar = content.profile.user_avatar;
$scope.user.name = content.name;
Auth._currentUser.name = content.name;
$scope.user = content;
Auth._currentUser = content;
$rootScope.currentUser = content;
return $state.go('app.public.home');
}
}
};
/**
* For use with 'ng-class', returns the CSS class name for the uploads previews.
@ -103,99 +103,99 @@ Application.Controllers.controller('CompleteProfileController', ['$scope', '$roo
*/
$scope.fileinputClass = function (v) {
if (v) {
return 'fileinput-exists'
return 'fileinput-exists';
} else {
return 'fileinput-new'
return 'fileinput-new';
}
}
};
/**
* Merge the current user into the account with the given auth_token
*/
$scope.registerAuthToken = function () {
Member.merge({ id: $rootScope.currentUser.id }, { user: { auth_token: $scope.user.auth_token } }, function (user) {
$scope.user = user
Auth._currentUser = user
$rootScope.currentUser = user
$state.go('app.public.home')
$scope.user = user;
Auth._currentUser = user;
$rootScope.currentUser = user;
$state.go('app.public.home');
}
, function (err) {
if (err.data.error) {
growl.error(err.data.error)
growl.error(err.data.error);
} else {
growl.error(_t('an_unexpected_error_occurred_check_your_authentication_code'))
console.error(err)
growl.error(_t('an_unexpected_error_occurred_check_your_authentication_code'));
console.error(err);
}
})
}
});
};
/**
* Return the email given by the SSO provider, parsed if needed
* @return {String} E-mail of the current user
*/
$scope.ssoEmail = function () {
const { email } = memberPromise
const { email } = memberPromise;
if (email) {
const duplicate = email.match(/^<([^>]+)>.{20}-duplicate$/)
const duplicate = email.match(/^<([^>]+)>.{20}-duplicate$/);
if (duplicate) {
return duplicate[1]
return duplicate[1];
}
}
return email
}
return email;
};
/**
* Test if the user's mail is marked as duplicate
* @return {boolean}
*/
$scope.hasDuplicate = function () {
const { email } = memberPromise
const { email } = memberPromise;
if (email) {
return !(email.match(/^<([^>]+)>.{20}-duplicate$/) === null)
return !(email.match(/^<([^>]+)>.{20}-duplicate$/) === null);
}
}
};
/**
* Ask for email confirmation and send the SSO merging token again
* @param event {Object} jQuery event object
*/
$scope.resendCode = function (event) {
event.preventDefault()
event.stopPropagation()
event.preventDefault();
event.stopPropagation();
dialogs.confirm(
{
templateUrl: '<%= asset_path "profile/resend_code_modal.html" %>',
resolve: {
object () {
return { email: memberPromise.email }
return { email: memberPromise.email };
}
}
},
function (email) {
// Request the server to send an auth-migration email to the current user
AuthProvider.send_code({ email },
function (res) { growl.info(_t('code_successfully_sent_again')) },
function (err) { growl.error(err.data.error) }
)
function (res) { growl.info(_t('code_successfully_sent_again')); },
function (err) { growl.error(err.data.error); }
);
}
)
}
);
};
/**
* Disconnect and re-connect the user to the SSO to force the synchronisation of the profile's data
*/
$scope.syncProfile = function () {
Auth.logout().then(function (oldUser) {
Session.destroy()
$rootScope.currentUser = null
$rootScope.toCheckNotifications = false
Session.destroy();
$rootScope.currentUser = null;
$rootScope.toCheckNotifications = false;
$scope.notifications = {
total: 0,
unread: 0
}
$window.location.href = activeProviderPromise.link_to_sso_connect
})
}
};
$window.location.href = activeProviderPromise.link_to_sso_connect;
});
};
/* PRIVATE SCOPE */
@ -203,17 +203,17 @@ Application.Controllers.controller('CompleteProfileController', ['$scope', '$roo
* Kind of constructor: these actions will be realized first when the controller is loaded
*/
const initialize = function () {
CSRF.setMetaTags()
CSRF.setMetaTags();
// init the birth date to JS object
$scope.user.profile.birthday = moment($scope.user.profile.birthday).toDate()
$scope.user.profile.birthday = moment($scope.user.profile.birthday).toDate();
// bind fields protection with sso fields
angular.forEach(activeProviderPromise.mapping, function (map) { $scope.preventField[map] = true })
}
angular.forEach(activeProviderPromise.mapping, function (map) { $scope.preventField[map] = true; });
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);

View File

@ -13,7 +13,7 @@
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
/* COMMON CODE */
@ -49,9 +49,9 @@ class ProjectsController {
return ({
id: d.id,
name: d.name
})
})
})
});
});
});
// Retrieve the list of components from the server
Component.query().$promise.then(function (data) {
@ -59,9 +59,9 @@ class ProjectsController {
return ({
id: d.id,
name: d.name
})
})
})
});
});
});
// Retrieve the list of themes from the server
Theme.query().$promise.then(function (data) {
@ -69,9 +69,9 @@ class ProjectsController {
return ({
id: d.id,
name: d.name
})
})
})
});
});
});
// Retrieve the list of licences from the server
Licence.query().$promise.then(function (data) {
@ -79,15 +79,15 @@ class ProjectsController {
return ({
id: d.id,
name: d.name
})
})
})
});
});
});
// Total number of documentation steps for the current project
$scope.totalSteps = $scope.project.project_steps_attributes.length
$scope.totalSteps = $scope.project.project_steps_attributes.length;
// List of extensions allowed for CAD attachements upload
$scope.allowedExtensions = allowedExtensions
$scope.allowedExtensions = allowedExtensions;
/**
* For use with ngUpload (https://github.com/twilson63/ngUpload).
@ -97,21 +97,21 @@ class ProjectsController {
*/
$scope.submited = function (content) {
if ((content.id == null)) {
$scope.alerts = []
$scope.alerts = [];
angular.forEach(content, function (v, k) {
angular.forEach(v, function (err) {
$scope.alerts.push({
msg: k + ': ' + err,
type: 'danger'
})
})
})
});
});
});
// using https://github.com/oblador/angular-scroll
$('section[ui-view=main]').scrollTop(0, 200)
$('section[ui-view=main]').scrollTop(0, 200);
} else {
return $state.go('app.public.projects_show', { id: content.slug })
return $state.go('app.public.projects_show', { id: content.slug });
}
}
};
/**
* For use with 'ng-class', returns the CSS class name for the uploads previews.
@ -120,16 +120,16 @@ class ProjectsController {
*/
$scope.fileinputClass = function (v) {
if (v) {
return 'fileinput-exists'
return 'fileinput-exists';
} else {
return 'fileinput-new'
return 'fileinput-new';
}
}
};
/**
* This will create a single new empty entry into the project's CAO attachements list.
*/
$scope.addFile = function () { $scope.project.project_caos_attributes.push({}) }
$scope.addFile = function () { $scope.project.project_caos_attributes.push({}); };
/**
* This will remove the given file from the project's CAO attachements list. If the file was previously uploaded
@ -138,21 +138,21 @@ class ProjectsController {
* @param file {Object} the file to delete
*/
$scope.deleteFile = function (file) {
const index = $scope.project.project_caos_attributes.indexOf(file)
const index = $scope.project.project_caos_attributes.indexOf(file);
if (file.id != null) {
return file._destroy = true
return file._destroy = true;
} else {
return $scope.project.project_caos_attributes.splice(index, 1)
return $scope.project.project_caos_attributes.splice(index, 1);
}
}
};
/**
* This will create a single new empty entry into the project's steps list.
*/
$scope.addStep = function () {
$scope.totalSteps += 1
return $scope.project.project_steps_attributes.push({ step_nb: $scope.totalSteps, project_step_images_attributes: [] })
}
$scope.totalSteps += 1;
return $scope.project.project_steps_attributes.push({ step_nb: $scope.totalSteps, project_step_images_attributes: [] });
};
/**
* This will remove the given step from the project's steps list. If the step was previously saved
@ -167,34 +167,34 @@ class ProjectsController {
return {
title: _t('confirmation_required'),
msg: _t('do_you_really_want_to_delete_this_step')
}
};
}
}
}
, function () { // deletion confirmed
const index = $scope.project.project_steps_attributes.indexOf(step)
const index = $scope.project.project_steps_attributes.indexOf(step);
if (step.id != null) {
step._destroy = true
step._destroy = true;
} else {
$scope.project.project_steps_attributes.splice(index, 1)
$scope.project.project_steps_attributes.splice(index, 1);
}
// update the new total number of steps
$scope.totalSteps -= 1
$scope.totalSteps -= 1;
// reindex the remaining steps
return (function () {
const result = []
const result = [];
for (let s of Array.from($scope.project.project_steps_attributes)) {
if (s.step_nb > step.step_nb) {
result.push(s.step_nb -= 1)
result.push(s.step_nb -= 1);
} else {
result.push(undefined)
result.push(undefined);
}
}
return result
})()
})
}
return result;
})();
});
};
/**
* Change the step_nb property of the given step to the new value provided. The step that was previously at this
@ -204,34 +204,34 @@ class ProjectsController {
* @param newIdx {number} the new index to assign to the step
*/
$scope.changeStepIndex = function (event, step, newIdx) {
if (event) { event.preventDefault() }
if (event) { event.preventDefault(); }
for (let s of Array.from($scope.project.project_steps_attributes)) {
if (s.step_nb === newIdx) {
s.step_nb = step.step_nb
step.step_nb = newIdx
break
s.step_nb = step.step_nb;
step.step_nb = newIdx;
break;
}
}
return false
}
return false;
};
$scope.autoCompleteName = function (nameLookup) {
if (!nameLookup) {
return
return;
}
const asciiName = Diacritics.remove(nameLookup)
const asciiName = Diacritics.remove(nameLookup);
Member.search(
{ query: asciiName },
function (users) { $scope.matchingMembers = users },
function (error) { console.error(error) }
)
}
function (users) { $scope.matchingMembers = users; },
function (error) { console.error(error); }
);
};
/**
* This will create a single new empty entry into the project's step image list.
*/
$scope.addProjectStepImage = function (step) { step.project_step_images_attributes.push({}) }
$scope.addProjectStepImage = function (step) { step.project_step_images_attributes.push({}); };
/**
* This will remove the given image from the project's step image list.
@ -239,13 +239,13 @@ class ProjectsController {
* @param image {Object} the image to delete
*/
$scope.deleteProjectStepImage = function (step, image) {
const index = step.project_step_images_attributes.indexOf(image)
const index = step.project_step_images_attributes.indexOf(image);
if (image.id != null) {
return image._destroy = true
return image._destroy = true;
} else {
return step.project_step_images_attributes.splice(index, 1)
return step.project_step_images_attributes.splice(index, 1);
}
}
};
}
}
@ -257,18 +257,18 @@ Application.Controllers.controller('ProjectsController', ['$scope', '$state', 'P
/* PRIVATE STATIC CONSTANTS */
// Number of projects added to the page when the user clicks on 'load more projects'
const PROJECTS_PER_PAGE = 16
const PROJECTS_PER_PAGE = 16;
/* PUBLIC SCOPE */
// Fab-manager's instance ID in the openLab network
$scope.openlabAppId = Fablab.openlabAppId
$scope.openlabAppId = Fablab.openlabAppId;
// Is openLab enabled on the instance?
$scope.openlab = {
projectsActive: Fablab.openlabProjectsActive,
searchOverWholeNetwork: false
}
};
// default search parameters
$scope.search = {
@ -277,69 +277,69 @@ Application.Controllers.controller('ProjectsController', ['$scope', '$state', 'P
machine_id: (parseInt($location.$$search.machine_id) || undefined),
component_id: (parseInt($location.$$search.component_id) || undefined),
theme_id: (parseInt($location.$$search.theme_id) || undefined)
}
};
// list of projects to display
$scope.projects = []
$scope.projects = [];
// list of machines / used for filtering
$scope.machines = machinesPromise
$scope.machines = machinesPromise;
// list of themes / used for filtering
$scope.themes = themesPromise
$scope.themes = themesPromise;
// list of components / used for filtering
$scope.components = componentsPromise
$scope.components = componentsPromise;
$scope.searchOverWholeNetworkChanged = function () {
setTimeout(
function () { $scope.resetFiltersAndTriggerSearch() },
function () { $scope.resetFiltersAndTriggerSearch(); },
150
)
}
);
};
$scope.loadMore = function () {
if ($scope.openlab.searchOverWholeNetwork === true) {
return $scope.projectsPagination.loadMore({ q: $scope.search.q })
return $scope.projectsPagination.loadMore({ q: $scope.search.q });
} else {
return $scope.projectsPagination.loadMore({ search: $scope.search })
return $scope.projectsPagination.loadMore({ search: $scope.search });
}
}
};
$scope.resetFiltersAndTriggerSearch = function () {
$scope.search.q = ''
$scope.search.from = undefined
$scope.search.machine_id = undefined
$scope.search.component_id = undefined
$scope.search.theme_id = undefined
$scope.setUrlQueryParams($scope.search)
return $scope.triggerSearch()
}
$scope.search.q = '';
$scope.search.from = undefined;
$scope.search.machine_id = undefined;
$scope.search.component_id = undefined;
$scope.search.theme_id = undefined;
$scope.setUrlQueryParams($scope.search);
return $scope.triggerSearch();
};
$scope.triggerSearch = function () {
const currentPage = parseInt($location.$$search.page) || 1
const currentPage = parseInt($location.$$search.page) || 1;
if ($scope.openlab.searchOverWholeNetwork === true) {
updateUrlParam('whole_network', 't')
$scope.projectsPagination = new paginationService.Instance(OpenlabProject, currentPage, PROJECTS_PER_PAGE, null, { }, loadMoreOpenlabCallback)
updateUrlParam('whole_network', 't');
$scope.projectsPagination = new paginationService.Instance(OpenlabProject, currentPage, PROJECTS_PER_PAGE, null, { }, loadMoreOpenlabCallback);
return OpenlabProject.query({ q: $scope.search.q, page: currentPage, per_page: PROJECTS_PER_PAGE }, function (projectsPromise) {
if (projectsPromise.errors != null) {
growl.error(_t('openlab_search_not_available_at_the_moment'))
$scope.openlab.searchOverWholeNetwork = false
return $scope.triggerSearch()
growl.error(_t('openlab_search_not_available_at_the_moment'));
$scope.openlab.searchOverWholeNetwork = false;
return $scope.triggerSearch();
} else {
$scope.projectsPagination.totalCount = projectsPromise.meta.total
return $scope.projects = normalizeProjectsAttrs(projectsPromise.projects)
$scope.projectsPagination.totalCount = projectsPromise.meta.total;
return $scope.projects = normalizeProjectsAttrs(projectsPromise.projects);
}
})
});
} else {
updateUrlParam('whole_network', 'f')
$scope.projectsPagination = new paginationService.Instance(Project, currentPage, PROJECTS_PER_PAGE, null, { }, loadMoreCallback, 'search')
updateUrlParam('whole_network', 'f');
$scope.projectsPagination = new paginationService.Instance(Project, currentPage, PROJECTS_PER_PAGE, null, { }, loadMoreCallback, 'search');
return Project.search({ search: $scope.search, page: currentPage, per_page: PROJECTS_PER_PAGE }, function (projectsPromise) {
$scope.projectsPagination.totalCount = projectsPromise.meta.total
return $scope.projects = projectsPromise.projects
})
$scope.projectsPagination.totalCount = projectsPromise.meta.total;
return $scope.projects = projectsPromise.projects;
});
}
}
};
/**
* Callback to switch the user's view to the detailled project page
@ -347,24 +347,24 @@ Application.Controllers.controller('ProjectsController', ['$scope', '$state', 'P
*/
$scope.showProject = function (project) {
if (($scope.openlab.searchOverWholeNetwork === true) && (project.app_id !== Fablab.openlabAppId)) {
$window.open(project.project_url, '_blank')
return true
$window.open(project.project_url, '_blank');
return true;
} else {
return $state.go('app.public.projects_show', { id: project.slug })
return $state.go('app.public.projects_show', { id: project.slug });
}
}
};
/**
* function to set all url query search parameters from search object
*/
$scope.setUrlQueryParams = function (search) {
updateUrlParam('page', 1)
updateUrlParam('q', search.q)
updateUrlParam('from', search.from)
updateUrlParam('theme_id', search.theme_id)
updateUrlParam('component_id', search.component_id)
return updateUrlParam('machine_id', search.machine_id)
}
updateUrlParam('page', 1);
updateUrlParam('q', search.q);
updateUrlParam('from', search.from);
updateUrlParam('theme_id', search.theme_id);
updateUrlParam('component_id', search.component_id);
return updateUrlParam('machine_id', search.machine_id);
};
/* PRIVATE SCOPE */
@ -373,98 +373,98 @@ Application.Controllers.controller('ProjectsController', ['$scope', '$state', 'P
*/
const initialize = function () {
if ($location.$$search.whole_network === 'f') {
$scope.openlab.searchOverWholeNetwork = false
$scope.openlab.searchOverWholeNetwork = false;
} else {
$scope.openlab.searchOverWholeNetwork = $scope.openlab.projectsActive || false
$scope.openlab.searchOverWholeNetwork = $scope.openlab.projectsActive || false;
}
return $scope.triggerSearch()
}
return $scope.triggerSearch();
};
/**
* function to update url query param, little hack to turn off reloadOnSearch and re-enable it after setting the params
* params example: 'q' , 'presse-purée'
*/
var updateUrlParam = function (name, value) {
$state.current.reloadOnSearch = false
$location.search(name, value)
return $timeout(function () { $state.current.reloadOnSearch = undefined })
}
$state.current.reloadOnSearch = false;
$location.search(name, value);
return $timeout(function () { $state.current.reloadOnSearch = undefined; });
};
var loadMoreCallback = function (projectsPromise) {
$scope.projects = $scope.projects.concat(projectsPromise.projects)
return updateUrlParam('page', $scope.projectsPagination.currentPage)
}
$scope.projects = $scope.projects.concat(projectsPromise.projects);
return updateUrlParam('page', $scope.projectsPagination.currentPage);
};
var loadMoreOpenlabCallback = function (projectsPromise) {
$scope.projects = $scope.projects.concat(normalizeProjectsAttrs(projectsPromise.projects))
return updateUrlParam('page', $scope.projectsPagination.currentPage)
}
$scope.projects = $scope.projects.concat(normalizeProjectsAttrs(projectsPromise.projects));
return updateUrlParam('page', $scope.projectsPagination.currentPage);
};
var normalizeProjectsAttrs = function (projects) {
projects.map(function (project) {
project.project_image = project.image_url
return project
})
}
project.project_image = project.image_url;
return project;
});
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);
/**
* Controller used in the project creation page
*/
Application.Controllers.controller('NewProjectController', ['$scope', '$state', 'Project', 'Machine', 'Member', 'Component', 'Theme', 'Licence', '$document', 'CSRF', 'Diacritics', 'dialogs', 'allowedExtensions', '_t',
function ($scope, $state, Project, Machine, Member, Component, Theme, Licence, $document, CSRF, Diacritics, dialogs, allowedExtensions, _t) {
CSRF.setMetaTags()
CSRF.setMetaTags();
// API URL where the form will be posted
$scope.actionUrl = '/api/projects/'
$scope.actionUrl = '/api/projects/';
// Form action on the above URL
$scope.method = 'post'
$scope.method = 'post';
// Default project parameters
$scope.project = {
project_steps_attributes: [],
project_caos_attributes: []
}
};
$scope.matchingMembers = []
$scope.matchingMembers = [];
// Using the ProjectsController
return new ProjectsController($scope, $state, Project, Machine, Member, Component, Theme, Licence, $document, Diacritics, dialogs, allowedExtensions, _t)
return new ProjectsController($scope, $state, Project, Machine, Member, Component, Theme, Licence, $document, Diacritics, dialogs, allowedExtensions, _t);
}
])
]);
/**
* Controller used in the project edition page
*/
Application.Controllers.controller('EditProjectController', ['$scope', '$state', '$stateParams', 'Project', 'Machine', 'Member', 'Component', 'Theme', 'Licence', '$document', 'CSRF', 'projectPromise', 'Diacritics', 'dialogs', 'allowedExtensions', '_t',
function ($scope, $state, $stateParams, Project, Machine, Member, Component, Theme, Licence, $document, CSRF, projectPromise, Diacritics, dialogs, allowedExtensions, _t) {
CSRF.setMetaTags()
CSRF.setMetaTags();
// API URL where the form will be posted
$scope.actionUrl = `/api/projects/${$stateParams.id}`
$scope.actionUrl = `/api/projects/${$stateParams.id}`;
// Form action on the above URL
$scope.method = 'put'
$scope.method = 'put';
// Retrieve the project's details, if an error occured, redirect the user to the projects list page
$scope.project = projectPromise
$scope.project = projectPromise;
$scope.matchingMembers = $scope.project.project_users.map(function (u) {
return ({
id: u.id,
name: u.full_name
})
})
});
});
// Using the ProjectsController
return new ProjectsController($scope, $state, Project, Machine, Member, Component, Theme, Licence, $document, Diacritics, dialogs, allowedExtensions, _t)
return new ProjectsController($scope, $state, Project, Machine, Member, Component, Theme, Licence, $document, Diacritics, dialogs, allowedExtensions, _t);
}
])
]);
/**
* Controller used in the public project's details page
@ -474,9 +474,9 @@ Application.Controllers.controller('ShowProjectController', ['$scope', '$state',
/* PUBLIC SCOPE */
// Store the project's details
$scope.project = projectPromise
$scope.projectUrl = $location.absUrl()
$scope.disqusShortname = Fablab.disqusShortname
$scope.project = projectPromise;
$scope.projectUrl = $location.absUrl();
$scope.disqusShortname = Fablab.disqusShortname;
/**
* Test if the provided user has the edition rights on the current project
@ -484,14 +484,14 @@ Application.Controllers.controller('ShowProjectController', ['$scope', '$state',
* @returns boolean
*/
$scope.projectEditableBy = function (user) {
if ((user == null)) { return false }
if ($scope.project.author_id === user.id) { return true }
let canEdit = false
if ((user == null)) { return false; }
if ($scope.project.author_id === user.id) { return true; }
let canEdit = false;
angular.forEach($scope.project.project_users, function (u) {
if ((u.id === user.id) && u.is_valid) { return canEdit = true }
})
return canEdit
}
if ((u.id === user.id) && u.is_valid) { return canEdit = true; }
});
return canEdit;
};
/**
* Test if the provided user has the deletion rights on the current project
@ -499,9 +499,9 @@ Application.Controllers.controller('ShowProjectController', ['$scope', '$state',
* @returns boolean
*/
$scope.projectDeletableBy = function (user) {
if ((user == null)) { return false }
if ($scope.project.author_id === user.id) { return true }
}
if ((user == null)) { return false; }
if ($scope.project.author_id === user.id) { return true; }
};
/**
* Callback to delete the current project. Then, the user is redirected to the projects list page,
@ -517,40 +517,40 @@ Application.Controllers.controller('ShowProjectController', ['$scope', '$state',
return {
title: _t('confirmation_required'),
msg: _t('do_you_really_want_to_delete_this_project')
}
};
}
}
}
, function () { // cancel confirmed
$scope.project.$delete(function () { $state.go('app.public.projects_list', {}, { reload: true }) })
})
$scope.project.$delete(function () { $state.go('app.public.projects_list', {}, { reload: true }); });
});
} else {
return console.error(_t('unauthorized_operation'))
return console.error(_t('unauthorized_operation'));
}
}
};
/**
* Open a modal box containg a form that allow the end-user to signal an abusive content
* @param e {Object} jQuery event
*/
$scope.signalAbuse = function (e) {
if (e) { e.preventDefault() }
if (e) { e.preventDefault(); }
$uibModal.open({
templateUrl: '<%= asset_path "shared/signalAbuseModal.html" %>',
size: 'md',
resolve: {
project () { return $scope.project }
project () { return $scope.project; }
},
controller: ['$scope', '$uibModalInstance', '_t', 'growl', 'Abuse', 'project', function ($scope, $uibModalInstance, _t, growl, Abuse, project) {
// signaler's profile & signalement infos
$scope.signaler = {
signaled_type: 'Project',
signaled_id: project.id
}
};
// callback for signaling cancellation
$scope.cancel = function () { $uibModalInstance.dismiss('cancel') }
$scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
// callback for form validation
return $scope.ok = function () {
@ -559,27 +559,27 @@ Application.Controllers.controller('ShowProjectController', ['$scope', '$state',
{ abuse: $scope.signaler },
function (res) {
// creation successful
growl.success(_t('your_report_was_successful_thanks'))
return $uibModalInstance.close(res)
growl.success(_t('your_report_was_successful_thanks'));
return $uibModalInstance.close(res);
}
, function (error) {
// creation failed...
growl.error(_t('an_error_occured_while_sending_your_report'))
growl.error(_t('an_error_occured_while_sending_your_report'));
}
)
}
);
};
}]
})
}
});
};
/**
* 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.projects_show', { id: $scope.project.slug }, { absolute: true }).replace('#', '%23')}` }
$scope.shareOnFacebook = function () { return `https://www.facebook.com/share.php?u=${$state.href('app.public.projects_show', { id: $scope.project.slug }, { 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.projects_show', { id: $scope.project.slug }, { absolute: true }))}&text=${encodeURIComponent($scope.project.name)}` }
$scope.shareOnTwitter = function () { return `https://twitter.com/intent/tweet?url=${encodeURIComponent($state.href('app.public.projects_show', { id: $scope.project.slug }, { absolute: true }))}&text=${encodeURIComponent($scope.project.name)}`; };
}
])
]);

View File

@ -41,24 +41,24 @@ class SpacesController {
*/
$scope.submited = function (content) {
if ((content.id == null)) {
$scope.alerts = []
$scope.alerts = [];
angular.forEach(content, function (v, k) {
angular.forEach(v, function (err) {
$scope.alerts.push({
msg: k + ': ' + err,
type: 'danger'
})
})
})
});
});
});
} else {
$state.go('app.public.spaces_list')
$state.go('app.public.spaces_list');
}
}
};
/**
* Changes the current user's view, redirecting him to the spaces list
*/
$scope.cancel = function () { $state.go('app.public.spaces_list') }
$scope.cancel = function () { $state.go('app.public.spaces_list'); };
/**
* For use with 'ng-class', returns the CSS class name for the uploads previews.
@ -67,16 +67,16 @@ class SpacesController {
*/
$scope.fileinputClass = function (v) {
if (v) {
return 'fileinput-exists'
return 'fileinput-exists';
} else {
return 'fileinput-new'
return 'fileinput-new';
}
}
};
/**
* This will create a single new empty entry into the space attachments list.
*/
$scope.addFile = function () { $scope.space.space_files_attributes.push({}) }
$scope.addFile = function () { $scope.space.space_files_attributes.push({}); };
/**
* This will remove the given file from the space attachments list. If the file was previously uploaded
@ -85,13 +85,13 @@ class SpacesController {
* @param file {Object} the file to delete
*/
$scope.deleteFile = function (file) {
const index = $scope.space.space_files_attributes.indexOf(file)
const index = $scope.space.space_files_attributes.indexOf(file);
if (file.id != null) {
return file._destroy = true
return file._destroy = true;
} else {
return $scope.space.space_files_attributes.splice(index, 1)
return $scope.space.space_files_attributes.splice(index, 1);
}
}
};
}
}
@ -100,92 +100,92 @@ class SpacesController {
*/
Application.Controllers.controller('SpacesController', ['$scope', '$state', 'spacesPromise', function ($scope, $state, spacesPromise) {
// Retrieve the list of spaces
$scope.spaces = spacesPromise
$scope.spaces = spacesPromise;
/**
* Redirect the user to the space details page
*/
$scope.showSpace = function (space) { $state.go('app.public.space_show', { id: space.slug }) }
$scope.showSpace = function (space) { $state.go('app.public.space_show', { id: space.slug }); };
/**
* Callback to book a reservation for the current space
*/
$scope.reserveSpace = function (space) { $state.go('app.logged.space_reserve', { id: space.slug }) }
$scope.reserveSpace = function (space) { $state.go('app.logged.space_reserve', { id: space.slug }); };
// Default: we show only enabled spaces
$scope.spaceFiltering = 'enabled'
$scope.spaceFiltering = 'enabled';
// Available options for filtering spaces by status
$scope.filterDisabled = [
'enabled',
'disabled',
'all'
]
}])
];
}]);
/**
* Controller used in the space creation page (admin)
*/
Application.Controllers.controller('NewSpaceController', ['$scope', '$state', 'CSRF', function ($scope, $state, CSRF) {
CSRF.setMetaTags()
CSRF.setMetaTags();
// API URL where the form will be posted
$scope.actionUrl = '/api/spaces/'
$scope.actionUrl = '/api/spaces/';
// Form action on the above URL
$scope.method = 'post'
$scope.method = 'post';
// default space parameters
$scope.space =
{ space_files_attributes: [] }
{ space_files_attributes: [] };
// Using the SpacesController
return new SpacesController($scope, $state)
}])
return new SpacesController($scope, $state);
}]);
/**
* Controller used in the space edition page (admin)
*/
Application.Controllers.controller('EditSpaceController', ['$scope', '$state', '$stateParams', 'spacePromise', 'CSRF',
function ($scope, $state, $stateParams, spacePromise, CSRF) {
CSRF.setMetaTags()
CSRF.setMetaTags();
// API URL where the form will be posted
$scope.actionUrl = `/api/spaces/${$stateParams.id}`
$scope.actionUrl = `/api/spaces/${$stateParams.id}`;
// Form action on the above URL
$scope.method = 'put'
$scope.method = 'put';
// space to modify
$scope.space = spacePromise
$scope.space = spacePromise;
// Using the SpacesController
return new SpacesController($scope, $state)
}])
return new SpacesController($scope, $state);
}]);
Application.Controllers.controller('ShowSpaceController', ['$scope', '$state', 'spacePromise', '_t', 'dialogs', 'growl',
function ($scope, $state, spacePromise, _t, dialogs, growl) {
// Details of the space witch id/slug is provided in the URL
$scope.space = spacePromise
$scope.space = spacePromise;
/**
* Callback to book a reservation for the current space
* @param event {Object} see https://docs.angularjs.org/guide/expression#-event-
*/
$scope.reserveSpace = function (event) {
event.preventDefault()
return $state.go('app.logged.space_reserve', { id: $scope.space.slug })
}
event.preventDefault();
return $state.go('app.logged.space_reserve', { id: $scope.space.slug });
};
/**
* Callback to book a reservation for the current space
* @param event {Object} see https://docs.angularjs.org/guide/expression#-event-
*/
$scope.deleteSpace = function (event) {
event.preventDefault()
event.preventDefault();
// check the permissions
if ($scope.currentUser.role !== 'admin') {
return console.error(_t('space_show.unauthorized_operation'))
return console.error(_t('space_show.unauthorized_operation'));
} else {
return dialogs.confirm({
resolve: {
@ -193,7 +193,7 @@ Application.Controllers.controller('ShowSpaceController', ['$scope', '$state', '
return {
title: _t('space_show.confirmation_required'),
msg: _t('space_show.do_you_really_want_to_delete_this_space')
}
};
}
}
}
@ -201,17 +201,17 @@ Application.Controllers.controller('ShowSpaceController', ['$scope', '$state', '
// delete the machine then redirect to the machines listing
$scope.space.$delete(
function () {
$state.go('app.public.spaces_list')
$state.go('app.public.spaces_list');
},
function (error) {
growl.warning(_t('space_show.the_space_cant_be_deleted_because_it_is_already_reserved_by_some_users'))
console.error(error)
growl.warning(_t('space_show.the_space_cant_be_deleted_because_it_is_already_reserved_by_some_users'));
console.error(error);
}
)
})
);
});
}
}
}])
};
}]);
/**
* Controller used in the spaces reservation agenda page.
@ -224,31 +224,31 @@ Application.Controllers.controller('ReserveSpaceController', ['$scope', '$stateP
/* PRIVATE STATIC CONSTANTS */
// Color of the selected event backgound
const SELECTED_EVENT_BG_COLOR = '#ffdd00'
const SELECTED_EVENT_BG_COLOR = '#ffdd00';
// Slot free to be booked
const FREE_SLOT_BORDER_COLOR = '<%= AvailabilityHelper::SPACE_COLOR %>'
const FREE_SLOT_BORDER_COLOR = '<%= AvailabilityHelper::SPACE_COLOR %>';
// Slot with reservation from current user
const RESERVED_SLOT_BORDER_COLOR = '<%= AvailabilityHelper::IS_RESERVED_BY_CURRENT_USER %>'
const RESERVED_SLOT_BORDER_COLOR = '<%= AvailabilityHelper::IS_RESERVED_BY_CURRENT_USER %>';
/* PUBLIC SCOPE */
// bind the spaces availabilities with full-Calendar events
$scope.eventSources = [ { events: availabilitySpacesPromise, textColor: 'black' } ]
$scope.eventSources = [ { events: availabilitySpacesPromise, textColor: 'black' } ];
// the user to deal with, ie. the current user for non-admins
$scope.ctrl =
{ member: {} }
{ member: {} };
// list of plans, classified by group
$scope.plansClassifiedByGroup = []
$scope.plansClassifiedByGroup = [];
for (let group of Array.from(groupsPromise)) {
const groupObj = { id: group.id, name: group.name, plans: [] }
const groupObj = { id: group.id, name: group.name, plans: [] };
for (let plan of Array.from(plansPromise)) {
if (plan.group_id === group.id) { groupObj.plans.push(plan) }
if (plan.group_id === group.id) { groupObj.plans.push(plan); }
}
$scope.plansClassifiedByGroup.push(groupObj)
$scope.plansClassifiedByGroup.push(groupObj);
}
// mapping of fullCalendar events.
@ -258,135 +258,135 @@ Application.Controllers.controller('ReserveSpaceController', ['$scope', '$stateP
placable: null, // Destination slot for the change
paid: [], // Slots that were just booked by the user (transaction ok)
moved: null // Slots that were just moved by the user (change done) -> {newSlot:* oldSlot: *}
}
};
// the moment when the slot selection changed for the last time, used to trigger changes in the cart
$scope.selectionTime = null
$scope.selectionTime = null;
// the last clicked event in the calender
$scope.selectedEvent = null
$scope.selectedEvent = null;
// indicates the state of the current view : calendar or plans information
$scope.plansAreShown = false
$scope.plansAreShown = false;
// will store the user's plan if he choosed to buy one
$scope.selectedPlan = null
$scope.selectedPlan = null;
// the moment when the plan selection changed for the last time, used to trigger changes in the cart
$scope.planSelectionTime = null
$scope.planSelectionTime = null;
// Selected space
$scope.space = spacePromise
$scope.space = spacePromise;
// fullCalendar (v2) configuration
$scope.calendarConfig = CalendarConfig({
minTime: moment.duration(moment(settingsPromise.booking_window_start).format('HH:mm:ss')),
maxTime: moment.duration(moment(settingsPromise.booking_window_end).format('HH:mm:ss')),
eventClick (event, jsEvent, view) {
return calendarEventClickCb(event, jsEvent, view)
return calendarEventClickCb(event, jsEvent, view);
},
eventRender (event, element, view) {
return eventRenderCb(event, element, view)
return eventRenderCb(event, element, view);
}
})
});
// Application global settings
$scope.settings = settingsPromise
$scope.settings = settingsPromise;
// Global config: message to the end user concerning the subscriptions rules
$scope.subscriptionExplicationsAlert = settingsPromise.subscription_explications_alert
$scope.subscriptionExplicationsAlert = settingsPromise.subscription_explications_alert;
// Global config: message to the end user concerning the space reservation
$scope.spaceExplicationsAlert = settingsPromise.space_explications_alert
$scope.spaceExplicationsAlert = settingsPromise.space_explications_alert;
/**
* Change the last selected slot's appearence to looks like 'added to cart'
*/
$scope.markSlotAsAdded = function () {
$scope.selectedEvent.backgroundColor = SELECTED_EVENT_BG_COLOR
return updateCalendar()
}
$scope.selectedEvent.backgroundColor = SELECTED_EVENT_BG_COLOR;
return updateCalendar();
};
/**
* Change the last selected slot's appearence to looks like 'never added to cart'
*/
$scope.markSlotAsRemoved = function (slot) {
slot.backgroundColor = 'white'
slot.title = ''
slot.borderColor = FREE_SLOT_BORDER_COLOR
slot.id = null
slot.isValid = false
slot.is_reserved = false
slot.can_modify = false
slot.offered = false
if (slot.is_completed) { slot.is_completed = false }
return updateCalendar()
}
slot.backgroundColor = 'white';
slot.title = '';
slot.borderColor = FREE_SLOT_BORDER_COLOR;
slot.id = null;
slot.isValid = false;
slot.is_reserved = false;
slot.can_modify = false;
slot.offered = false;
if (slot.is_completed) { slot.is_completed = false; }
return updateCalendar();
};
/**
* Callback when a slot was successfully cancelled. Reset the slot style as 'ready to book'
*/
$scope.slotCancelled = function () { $scope.markSlotAsRemoved($scope.selectedEvent) }
$scope.slotCancelled = function () { $scope.markSlotAsRemoved($scope.selectedEvent); };
/**
* Change the last selected slot's appearence to looks like 'currently looking for a new destination to exchange'
*/
$scope.markSlotAsModifying = function () {
$scope.selectedEvent.backgroundColor = '#eee'
$scope.selectedEvent.title = _t('space_reserve.i_change')
return updateCalendar()
}
$scope.selectedEvent.backgroundColor = '#eee';
$scope.selectedEvent.title = _t('space_reserve.i_change');
return updateCalendar();
};
/**
* Change the last selected slot's appearence to looks like 'the slot being exchanged will take this place'
*/
$scope.changeModifyTrainingSlot = function () {
if ($scope.events.placable) {
$scope.events.placable.backgroundColor = 'white'
$scope.events.placable.title = ''
$scope.events.placable.backgroundColor = 'white';
$scope.events.placable.title = '';
}
if (!$scope.events.placable || ($scope.events.placable._id !== $scope.selectedEvent._id)) {
$scope.selectedEvent.backgroundColor = '#bbb'
$scope.selectedEvent.title = _t('space_reserve.i_shift')
$scope.selectedEvent.backgroundColor = '#bbb';
$scope.selectedEvent.title = _t('space_reserve.i_shift');
}
return updateCalendar()
}
return updateCalendar();
};
/**
* When modifying an already booked reservation, callback when the modification was successfully done.
*/
$scope.modifyTrainingSlot = function () {
$scope.events.placable.title = _t('space_reserve.i_ve_reserved')
$scope.events.placable.backgroundColor = 'white'
$scope.events.placable.borderColor = $scope.events.modifiable.borderColor
$scope.events.placable.id = $scope.events.modifiable.id
$scope.events.placable.is_reserved = true
$scope.events.placable.can_modify = true
$scope.events.placable.title = _t('space_reserve.i_ve_reserved');
$scope.events.placable.backgroundColor = 'white';
$scope.events.placable.borderColor = $scope.events.modifiable.borderColor;
$scope.events.placable.id = $scope.events.modifiable.id;
$scope.events.placable.is_reserved = true;
$scope.events.placable.can_modify = true;
$scope.events.modifiable.backgroundColor = 'white'
$scope.events.modifiable.title = ''
$scope.events.modifiable.borderColor = FREE_SLOT_BORDER_COLOR
$scope.events.modifiable.id = null
$scope.events.modifiable.is_reserved = false
$scope.events.modifiable.can_modify = false
if ($scope.events.modifiable.is_completed) { $scope.events.modifiable.is_completed = false }
$scope.events.modifiable.backgroundColor = 'white';
$scope.events.modifiable.title = '';
$scope.events.modifiable.borderColor = FREE_SLOT_BORDER_COLOR;
$scope.events.modifiable.id = null;
$scope.events.modifiable.is_reserved = false;
$scope.events.modifiable.can_modify = false;
if ($scope.events.modifiable.is_completed) { $scope.events.modifiable.is_completed = false; }
return updateCalendar()
}
return updateCalendar();
};
/**
* Cancel the current booking modification, reseting the whole process
*/
$scope.cancelModifyTrainingSlot = function () {
if ($scope.events.placable) {
$scope.events.placable.backgroundColor = 'white'
$scope.events.placable.title = ''
$scope.events.placable.backgroundColor = 'white';
$scope.events.placable.title = '';
}
$scope.events.modifiable.title = _t('space_reserve.i_ve_reserved')
$scope.events.modifiable.backgroundColor = 'white'
$scope.events.modifiable.title = _t('space_reserve.i_ve_reserved');
$scope.events.modifiable.backgroundColor = 'white';
return updateCalendar()
}
return updateCalendar();
};
/**
* Callback to deal with the reservations of the user selected in the dropdown list instead of the current user's
@ -395,22 +395,22 @@ Application.Controllers.controller('ReserveSpaceController', ['$scope', '$stateP
$scope.updateMember = function () {
if ($scope.ctrl.member) {
Member.get({ id: $scope.ctrl.member.id }, function (member) {
$scope.ctrl.member = member
$scope.ctrl.member = member;
return Availability.spaces({ spaceId: $scope.space.id, member_id: $scope.ctrl.member.id }, function (spaces) {
uiCalendarConfig.calendars.calendar.fullCalendar('removeEvents')
uiCalendarConfig.calendars.calendar.fullCalendar('removeEvents');
return $scope.eventSources.splice(0, 1, {
events: spaces,
textColor: 'black'
}
)
})
})
);
});
});
}
// as the events are re-fetched for the new user, we must re-init the cart
$scope.events.reserved = []
$scope.selectedPlan = null
return $scope.plansAreShown = false
}
$scope.events.reserved = [];
$scope.selectedPlan = null;
return $scope.plansAreShown = false;
};
/**
* Add the provided plan to the current shopping cart
@ -419,28 +419,28 @@ Application.Controllers.controller('ReserveSpaceController', ['$scope', '$stateP
$scope.selectPlan = function (plan) {
// toggle selected plan
if ($scope.selectedPlan !== plan) {
$scope.selectedPlan = plan
$scope.selectedPlan = plan;
} else {
$scope.selectedPlan = null
$scope.selectedPlan = null;
}
return $scope.planSelectionTime = new Date()
}
return $scope.planSelectionTime = new Date();
};
/**
* Changes the user current view from the plan subsription screen to the machine reservation agenda
* @param e {Object} see https://docs.angularjs.org/guide/expression#-event-
*/
$scope.doNotSubscribePlan = function (e) {
e.preventDefault()
$scope.plansAreShown = false
$scope.selectedPlan = null
return $scope.planSelectionTime = new Date()
}
e.preventDefault();
$scope.plansAreShown = false;
$scope.selectedPlan = null;
return $scope.planSelectionTime = new Date();
};
/**
* Switch the user's view from the reservation agenda to the plan subscription
*/
$scope.showPlans = function () { $scope.plansAreShown = true }
$scope.showPlans = function () { $scope.plansAreShown = true; };
/**
* Once the reservation is booked (payment process successfully completed), change the event style
@ -449,32 +449,32 @@ Application.Controllers.controller('ReserveSpaceController', ['$scope', '$stateP
*/
$scope.afterPayment = function (reservation) {
angular.forEach($scope.events.paid, function (spaceSlot, key) {
spaceSlot.is_reserved = true
spaceSlot.can_modify = true
spaceSlot.title = _t('space_reserve.i_ve_reserved')
spaceSlot.backgroundColor = 'white'
spaceSlot.borderColor = RESERVED_SLOT_BORDER_COLOR
return updateSpaceSlotId(spaceSlot, reservation)
})
spaceSlot.is_reserved = true;
spaceSlot.can_modify = true;
spaceSlot.title = _t('space_reserve.i_ve_reserved');
spaceSlot.backgroundColor = 'white';
spaceSlot.borderColor = RESERVED_SLOT_BORDER_COLOR;
return updateSpaceSlotId(spaceSlot, reservation);
});
if ($scope.selectedPlan) {
$scope.ctrl.member.subscribed_plan = angular.copy($scope.selectedPlan)
Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan)
$scope.plansAreShown = false
$scope.selectedPlan = null
$scope.ctrl.member.subscribed_plan = angular.copy($scope.selectedPlan);
Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan);
$scope.plansAreShown = false;
$scope.selectedPlan = null;
}
$scope.ctrl.member.training_credits = angular.copy(reservation.user.training_credits)
$scope.ctrl.member.machine_credits = angular.copy(reservation.user.machine_credits)
Auth._currentUser.training_credits = angular.copy(reservation.user.training_credits)
Auth._currentUser.machine_credits = angular.copy(reservation.user.machine_credits)
$scope.ctrl.member.training_credits = angular.copy(reservation.user.training_credits);
$scope.ctrl.member.machine_credits = angular.copy(reservation.user.machine_credits);
Auth._currentUser.training_credits = angular.copy(reservation.user.training_credits);
Auth._currentUser.machine_credits = angular.copy(reservation.user.machine_credits);
return refetchCalendar()
}
return refetchCalendar();
};
/**
* To use as callback in Array.prototype.filter to get only enabled plans
*/
$scope.filterDisabledPlans = function (plan) { return !plan.disabled }
$scope.filterDisabledPlans = function (plan) { return !plan.disabled; };
/* PRIVATE SCOPE */
@ -483,9 +483,9 @@ Application.Controllers.controller('ReserveSpaceController', ['$scope', '$stateP
*/
const initialize = function () {
if ($scope.currentUser.role !== 'admin') {
return Member.get({ id: $scope.currentUser.id }, function (member) { $scope.ctrl.member = member })
return Member.get({ id: $scope.currentUser.id }, function (member) { $scope.ctrl.member = member; });
}
}
};
/**
* Triggered when the user clicks on a reservation slot in the agenda.
@ -495,12 +495,12 @@ Application.Controllers.controller('ReserveSpaceController', ['$scope', '$stateP
* @see http://fullcalendar.io/docs/mouse/eventClick/
*/
var calendarEventClickCb = function (event, jsEvent, view) {
$scope.selectedEvent = event
$scope.selectedEvent = event;
if ($stateParams.id === 'all') {
$scope.training = event.training
$scope.training = event.training;
}
return $scope.selectionTime = new Date()
}
return $scope.selectionTime = new Date();
};
/**
* Triggered when fullCalendar tries to graphicaly render an event block.
@ -509,13 +509,13 @@ Application.Controllers.controller('ReserveSpaceController', ['$scope', '$stateP
*/
var eventRenderCb = function (event, element, view) {
if (($scope.currentUser.role === 'admin') && (event.tags.length > 0)) {
let html = ''
let html = '';
for (let tag of Array.from(event.tags)) {
html += `<span class='label label-success text-white' title='${tag.name}'>${tag.name}</span>`
html += `<span class='label label-success text-white' title='${tag.name}'>${tag.name}</span>`;
}
element.find('.fc-time').append(html)
element.find('.fc-time').append(html);
}
}
};
/**
* After payment, update the id of the newly reserved slot with the id returned by the server.
@ -526,28 +526,28 @@ Application.Controllers.controller('ReserveSpaceController', ['$scope', '$stateP
var updateSpaceSlotId = function (slot, reservation) {
angular.forEach(reservation.slots, function (s) {
if (slot.start_at === slot.start_at) {
return slot.id = s.id
return slot.id = s.id;
}
})
}
});
};
/**
* Update the calendar's display to render the new attributes of the events
*/
var updateCalendar = function () { uiCalendarConfig.calendars.calendar.fullCalendar('rerenderEvents') }
var updateCalendar = function () { uiCalendarConfig.calendars.calendar.fullCalendar('rerenderEvents'); };
/**
* Asynchronously fetch the events from the API and refresh the calendar's view with these new events
*/
var refetchCalendar = function () {
$timeout(function () {
uiCalendarConfig.calendars.calendar.fullCalendar('refetchEvents')
return uiCalendarConfig.calendars.calendar.fullCalendar('rerenderEvents')
})
}
uiCalendarConfig.calendars.calendar.fullCalendar('refetchEvents');
return uiCalendarConfig.calendars.calendar.fullCalendar('rerenderEvents');
});
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);

View File

@ -12,7 +12,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
/**
* Public listing of the trainings
@ -20,18 +20,18 @@
Application.Controllers.controller('TrainingsController', ['$scope', '$state', 'trainingsPromise',
function ($scope, $state, trainingsPromise) {
// List of trainings
$scope.trainings = trainingsPromise
$scope.trainings = trainingsPromise;
/**
* Callback for the 'reserve' button
*/
$scope.reserveTraining = function (training, event) { $state.go('app.logged.trainings_reserve', { id: training.slug }) }
$scope.reserveTraining = function (training, event) { $state.go('app.logged.trainings_reserve', { id: training.slug }); };
/**
* Callback for the 'show' button
*/
$scope.showTraining = function (training) { $state.go('app.public.training_show', { id: training.slug }) }
}])
$scope.showTraining = function (training) { $state.go('app.public.training_show', { id: training.slug }); };
}]);
/**
* Public view of a specific training
@ -39,7 +39,7 @@ Application.Controllers.controller('TrainingsController', ['$scope', '$state', '
Application.Controllers.controller('ShowTrainingController', ['$scope', '$state', 'trainingPromise', 'growl', '_t', 'dialogs',
function ($scope, $state, trainingPromise, growl, _t, dialogs) {
// Current training
$scope.training = trainingPromise
$scope.training = trainingPromise;
/**
* Callback to delete the current training (admins only)
@ -47,7 +47,7 @@ Application.Controllers.controller('ShowTrainingController', ['$scope', '$state'
$scope.delete = function (training) {
// check the permissions
if ($scope.currentUser.role !== 'admin') {
console.error(_t('unauthorized_operation'))
console.error(_t('unauthorized_operation'));
} else {
dialogs.confirm(
{
@ -56,34 +56,34 @@ Application.Controllers.controller('ShowTrainingController', ['$scope', '$state'
return {
title: _t('confirmation_required'),
msg: _t('do_you_really_want_to_delete_this_training')
}
};
}
}
},
function () { // deletion confirmed
// delete the training then redirect to the trainings listing
training.$delete(
function () { $state.go('app.public.trainings_list') },
function () { $state.go('app.public.trainings_list'); },
function (error) {
growl.warning(_t('the_training_cant_be_deleted_because_it_is_already_reserved_by_some_users'))
console.error(error)
growl.warning(_t('the_training_cant_be_deleted_because_it_is_already_reserved_by_some_users'));
console.error(error);
}
)
);
}
)
);
}
}
};
/**
* Callback for the 'reserve' button
*/
$scope.reserveTraining = function (training, event) { $state.go('app.logged.trainings_reserve', { id: training.id }) }
$scope.reserveTraining = function (training, event) { $state.go('app.logged.trainings_reserve', { id: training.id }); };
/**
* Revert view to the full list of trainings ("<-" button)
*/
$scope.cancel = function (event) { $state.go('app.public.trainings_list') }
}])
$scope.cancel = function (event) { $state.go('app.public.trainings_list'); };
}]);
/**
* Controller used in the training reservation agenda page.
@ -96,28 +96,28 @@ Application.Controllers.controller('ReserveTrainingController', ['$scope', '$sta
/* PRIVATE STATIC CONSTANTS */
// Color of the selected event backgound
const SELECTED_EVENT_BG_COLOR = '#ffdd00'
const SELECTED_EVENT_BG_COLOR = '#ffdd00';
// Slot free to be booked
const FREE_SLOT_BORDER_COLOR = '<%= AvailabilityHelper::TRAINING_COLOR %>'
const FREE_SLOT_BORDER_COLOR = '<%= AvailabilityHelper::TRAINING_COLOR %>';
/* PUBLIC SCOPE */
// bind the trainings availabilities with full-Calendar events
$scope.eventSources = [ { events: availabilityTrainingsPromise, textColor: 'black' } ]
$scope.eventSources = [ { events: availabilityTrainingsPromise, textColor: 'black' } ];
// the user to deal with, ie. the current user for non-admins
$scope.ctrl =
{ member: {} }
{ member: {} };
// list of plans, classified by group
$scope.plansClassifiedByGroup = []
$scope.plansClassifiedByGroup = [];
for (let group of Array.from(groupsPromise)) {
const groupObj = { id: group.id, name: group.name, plans: [] }
const groupObj = { id: group.id, name: group.name, plans: [] };
for (let plan of Array.from(plansPromise)) {
if (plan.group_id === group.id) { groupObj.plans.push(plan) }
if (plan.group_id === group.id) { groupObj.plans.push(plan); }
}
$scope.plansClassifiedByGroup.push(groupObj)
$scope.plansClassifiedByGroup.push(groupObj);
}
// mapping of fullCalendar events.
@ -127,141 +127,141 @@ Application.Controllers.controller('ReserveTrainingController', ['$scope', '$sta
placable: null, // Destination slot for the change
paid: [], // Slots that were just booked by the user (transaction ok)
moved: null // Slots that were just moved by the user (change done) -> {newSlot:* oldSlot: *}
}
};
// the moment when the slot selection changed for the last time, used to trigger changes in the cart
$scope.selectionTime = null
$scope.selectionTime = null;
// the last clicked event in the calender
$scope.selectedEvent = null
$scope.selectedEvent = null;
// indicates the state of the current view : calendar or plans information
$scope.plansAreShown = false
$scope.plansAreShown = false;
// will store the user's plan if he choosed to buy one
$scope.selectedPlan = null
$scope.selectedPlan = null;
// the moment when the plan selection changed for the last time, used to trigger changes in the cart
$scope.planSelectionTime = null
$scope.planSelectionTime = null;
// Selected training
$scope.training = trainingPromise
$scope.training = trainingPromise;
// 'all' OR training's slug
$scope.mode = $stateParams.id
$scope.mode = $stateParams.id;
// fullCalendar (v2) configuration
$scope.calendarConfig = CalendarConfig({
minTime: moment.duration(moment(settingsPromise.booking_window_start).format('HH:mm:ss')),
maxTime: moment.duration(moment(settingsPromise.booking_window_end).format('HH:mm:ss')),
eventClick (event, jsEvent, view) {
return calendarEventClickCb(event, jsEvent, view)
return calendarEventClickCb(event, jsEvent, view);
},
eventRender (event, element, view) {
return eventRenderCb(event, element, view)
return eventRenderCb(event, element, view);
}
})
});
// Application global settings
$scope.settings = settingsPromise
$scope.settings = settingsPromise;
// Global config: message to the end user concerning the subscriptions rules
$scope.subscriptionExplicationsAlert = settingsPromise.subscription_explications_alert
$scope.subscriptionExplicationsAlert = settingsPromise.subscription_explications_alert;
// Global config: message to the end user concerning the training reservation
$scope.trainingExplicationsAlert = settingsPromise.training_explications_alert
$scope.trainingExplicationsAlert = settingsPromise.training_explications_alert;
// Global config: message to the end user giving advice about the training reservation
$scope.trainingInformationMessage = settingsPromise.training_information_message
$scope.trainingInformationMessage = settingsPromise.training_information_message;
/**
* Change the last selected slot's appearence to looks like 'added to cart'
*/
$scope.markSlotAsAdded = function () {
$scope.selectedEvent.backgroundColor = SELECTED_EVENT_BG_COLOR
return updateCalendar()
}
$scope.selectedEvent.backgroundColor = SELECTED_EVENT_BG_COLOR;
return updateCalendar();
};
/**
* Change the last selected slot's appearence to looks like 'never added to cart'
*/
$scope.markSlotAsRemoved = function (slot) {
slot.backgroundColor = 'white'
slot.title = slot.training.name
slot.borderColor = FREE_SLOT_BORDER_COLOR
slot.id = null
slot.isValid = false
slot.is_reserved = false
slot.can_modify = false
slot.offered = false
if (slot.is_completed) { slot.is_completed = false }
return updateCalendar()
}
slot.backgroundColor = 'white';
slot.title = slot.training.name;
slot.borderColor = FREE_SLOT_BORDER_COLOR;
slot.id = null;
slot.isValid = false;
slot.is_reserved = false;
slot.can_modify = false;
slot.offered = false;
if (slot.is_completed) { slot.is_completed = false; }
return updateCalendar();
};
/**
* Callback when a slot was successfully cancelled. Reset the slot style as 'ready to book'
*/
$scope.slotCancelled = function () { $scope.markSlotAsRemoved($scope.selectedEvent) }
$scope.slotCancelled = function () { $scope.markSlotAsRemoved($scope.selectedEvent); };
/**
* Change the last selected slot's appearence to looks like 'currently looking for a new destination to exchange'
*/
$scope.markSlotAsModifying = function () {
$scope.selectedEvent.backgroundColor = '#eee'
$scope.selectedEvent.title = $scope.selectedEvent.training.name + ' - ' + _t('i_change')
return updateCalendar()
}
$scope.selectedEvent.backgroundColor = '#eee';
$scope.selectedEvent.title = $scope.selectedEvent.training.name + ' - ' + _t('i_change');
return updateCalendar();
};
/**
* Change the last selected slot's appearence to looks like 'the slot being exchanged will take this place'
*/
$scope.changeModifyTrainingSlot = function () {
if ($scope.events.placable) {
$scope.events.placable.backgroundColor = 'white'
$scope.events.placable.title = $scope.events.placable.training.name
$scope.events.placable.backgroundColor = 'white';
$scope.events.placable.title = $scope.events.placable.training.name;
}
if (!$scope.events.placable || ($scope.events.placable._id !== $scope.selectedEvent._id)) {
$scope.selectedEvent.backgroundColor = '#bbb'
$scope.selectedEvent.title = $scope.selectedEvent.training.name + ' - ' + _t('i_shift')
$scope.selectedEvent.backgroundColor = '#bbb';
$scope.selectedEvent.title = $scope.selectedEvent.training.name + ' - ' + _t('i_shift');
}
return updateCalendar()
}
return updateCalendar();
};
/**
* When modifying an already booked reservation, callback when the modification was successfully done.
*/
$scope.modifyTrainingSlot = function () {
$scope.events.placable.title = $scope.currentUser.role !== 'admin' ? $scope.events.placable.training.name + ' - ' + _t('i_ve_reserved') : $scope.events.placable.training.name
$scope.events.placable.backgroundColor = 'white'
$scope.events.placable.borderColor = $scope.events.modifiable.borderColor
$scope.events.placable.id = $scope.events.modifiable.id
$scope.events.placable.is_reserved = true
$scope.events.placable.can_modify = true
$scope.events.placable.title = $scope.currentUser.role !== 'admin' ? $scope.events.placable.training.name + ' - ' + _t('i_ve_reserved') : $scope.events.placable.training.name;
$scope.events.placable.backgroundColor = 'white';
$scope.events.placable.borderColor = $scope.events.modifiable.borderColor;
$scope.events.placable.id = $scope.events.modifiable.id;
$scope.events.placable.is_reserved = true;
$scope.events.placable.can_modify = true;
$scope.events.modifiable.backgroundColor = 'white'
$scope.events.modifiable.title = $scope.events.modifiable.training.name
$scope.events.modifiable.borderColor = FREE_SLOT_BORDER_COLOR
$scope.events.modifiable.id = null
$scope.events.modifiable.is_reserved = false
$scope.events.modifiable.can_modify = false
if ($scope.events.modifiable.is_completed) { $scope.events.modifiable.is_completed = false }
$scope.events.modifiable.backgroundColor = 'white';
$scope.events.modifiable.title = $scope.events.modifiable.training.name;
$scope.events.modifiable.borderColor = FREE_SLOT_BORDER_COLOR;
$scope.events.modifiable.id = null;
$scope.events.modifiable.is_reserved = false;
$scope.events.modifiable.can_modify = false;
if ($scope.events.modifiable.is_completed) { $scope.events.modifiable.is_completed = false; }
return updateCalendar()
}
return updateCalendar();
};
/**
* Cancel the current booking modification, reseting the whole process
*/
$scope.cancelModifyTrainingSlot = function () {
if ($scope.events.placable) {
$scope.events.placable.backgroundColor = 'white'
$scope.events.placable.title = $scope.events.placable.training.name
$scope.events.placable.backgroundColor = 'white';
$scope.events.placable.title = $scope.events.placable.training.name;
}
$scope.events.modifiable.title = $scope.currentUser.role !== 'admin' ? $scope.events.modifiable.training.name + ' - ' + _t('i_ve_reserved') : $scope.events.modifiable.training.name
$scope.events.modifiable.backgroundColor = 'white'
$scope.events.modifiable.title = $scope.currentUser.role !== 'admin' ? $scope.events.modifiable.training.name + ' - ' + _t('i_ve_reserved') : $scope.events.modifiable.training.name;
$scope.events.modifiable.backgroundColor = 'white';
return updateCalendar()
}
return updateCalendar();
};
/**
* Callback to deal with the reservations of the user selected in the dropdown list instead of the current user's
@ -270,23 +270,23 @@ Application.Controllers.controller('ReserveTrainingController', ['$scope', '$sta
$scope.updateMember = function () {
if ($scope.ctrl.member) {
Member.get({ id: $scope.ctrl.member.id }, function (member) {
$scope.ctrl.member = member
const id = $stateParams.id === 'all' ? $stateParams.id : $scope.training.id
$scope.ctrl.member = member;
const id = $stateParams.id === 'all' ? $stateParams.id : $scope.training.id;
return Availability.trainings({ trainingId: id, member_id: $scope.ctrl.member.id }, function (trainings) {
uiCalendarConfig.calendars.calendar.fullCalendar('removeEvents')
uiCalendarConfig.calendars.calendar.fullCalendar('removeEvents');
return $scope.eventSources.splice(0, 1, {
events: trainings,
textColor: 'black'
}
)
})
})
);
});
});
}
// as the events are re-fetched for the new user, we must re-init the cart
$scope.events.reserved = []
$scope.selectedPlan = null
return $scope.plansAreShown = false
}
$scope.events.reserved = [];
$scope.selectedPlan = null;
return $scope.plansAreShown = false;
};
/**
* Add the provided plan to the current shopping cart
@ -295,28 +295,28 @@ Application.Controllers.controller('ReserveTrainingController', ['$scope', '$sta
$scope.selectPlan = function (plan) {
// toggle selected plan
if ($scope.selectedPlan !== plan) {
$scope.selectedPlan = plan
$scope.selectedPlan = plan;
} else {
$scope.selectedPlan = null
$scope.selectedPlan = null;
}
return $scope.planSelectionTime = new Date()
}
return $scope.planSelectionTime = new Date();
};
/**
* Changes the user current view from the plan subsription screen to the machine reservation agenda
* @param e {Object} see https://docs.angularjs.org/guide/expression#-event-
*/
$scope.doNotSubscribePlan = function (e) {
e.preventDefault()
$scope.plansAreShown = false
$scope.selectedPlan = null
return $scope.planSelectionTime = new Date()
}
e.preventDefault();
$scope.plansAreShown = false;
$scope.selectedPlan = null;
return $scope.planSelectionTime = new Date();
};
/**
* Switch the user's view from the reservation agenda to the plan subscription
*/
$scope.showPlans = function () { $scope.plansAreShown = true }
$scope.showPlans = function () { $scope.plansAreShown = true; };
/**
* Once the reservation is booked (payment process successfully completed), change the event style
@ -324,31 +324,31 @@ Application.Controllers.controller('ReserveTrainingController', ['$scope', '$sta
* @param reservation {Object}
*/
$scope.afterPayment = function (reservation) {
$scope.events.paid[0].backgroundColor = 'white'
$scope.events.paid[0].is_reserved = true
$scope.events.paid[0].can_modify = true
updateTrainingSlotId($scope.events.paid[0], reservation)
$scope.events.paid[0].borderColor = '#b2e774'
$scope.events.paid[0].title = $scope.events.paid[0].training.name + ' - ' + _t('i_ve_reserved')
$scope.events.paid[0].backgroundColor = 'white';
$scope.events.paid[0].is_reserved = true;
$scope.events.paid[0].can_modify = true;
updateTrainingSlotId($scope.events.paid[0], reservation);
$scope.events.paid[0].borderColor = '#b2e774';
$scope.events.paid[0].title = $scope.events.paid[0].training.name + ' - ' + _t('i_ve_reserved');
if ($scope.selectedPlan) {
$scope.ctrl.member.subscribed_plan = angular.copy($scope.selectedPlan)
Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan)
$scope.plansAreShown = false
$scope.selectedPlan = null
$scope.ctrl.member.subscribed_plan = angular.copy($scope.selectedPlan);
Auth._currentUser.subscribed_plan = angular.copy($scope.selectedPlan);
$scope.plansAreShown = false;
$scope.selectedPlan = null;
}
$scope.ctrl.member.training_credits = angular.copy(reservation.user.training_credits)
$scope.ctrl.member.machine_credits = angular.copy(reservation.user.machine_credits)
Auth._currentUser.training_credits = angular.copy(reservation.user.training_credits)
Auth._currentUser.machine_credits = angular.copy(reservation.user.machine_credits)
$scope.ctrl.member.training_credits = angular.copy(reservation.user.training_credits);
$scope.ctrl.member.machine_credits = angular.copy(reservation.user.machine_credits);
Auth._currentUser.training_credits = angular.copy(reservation.user.training_credits);
Auth._currentUser.machine_credits = angular.copy(reservation.user.machine_credits);
return refetchCalendar()
}
return refetchCalendar();
};
/**
* To use as callback in Array.prototype.filter to get only enabled plans
*/
$scope.filterDisabledPlans = function (plan) { return !plan.disabled }
$scope.filterDisabledPlans = function (plan) { return !plan.disabled; };
/* PRIVATE SCOPE */
@ -357,9 +357,9 @@ Application.Controllers.controller('ReserveTrainingController', ['$scope', '$sta
*/
const initialize = function () {
if ($scope.currentUser.role !== 'admin') {
return Member.get({ id: $scope.currentUser.id }, function (member) { $scope.ctrl.member = member })
return Member.get({ id: $scope.currentUser.id }, function (member) { $scope.ctrl.member = member; });
}
}
};
/**
* Triggered when the user clicks on a reservation slot in the agenda.
@ -369,12 +369,12 @@ Application.Controllers.controller('ReserveTrainingController', ['$scope', '$sta
* @see http://fullcalendar.io/docs/mouse/eventClick/
*/
var calendarEventClickCb = function (event, jsEvent, view) {
$scope.selectedEvent = event
$scope.selectedEvent = event;
if ($stateParams.id === 'all') {
$scope.training = event.training
$scope.training = event.training;
}
return $scope.selectionTime = new Date()
}
return $scope.selectionTime = new Date();
};
/**
* Triggered when fullCalendar tries to graphicaly render an event block.
@ -383,13 +383,13 @@ Application.Controllers.controller('ReserveTrainingController', ['$scope', '$sta
*/
var eventRenderCb = function (event, element, view) {
if (($scope.currentUser.role === 'admin') && (event.tags.length > 0)) {
let html = ''
let html = '';
for (let tag of Array.from(event.tags)) {
html += `<span class='label label-success text-white' title='${tag.name}'>${tag.name}</span>`
html += `<span class='label label-success text-white' title='${tag.name}'>${tag.name}</span>`;
}
element.find('.fc-time').append(html)
element.find('.fc-time').append(html);
}
}
};
/**
* After payment, update the id of the newly reserved slot with the id returned by the server.
@ -400,28 +400,28 @@ Application.Controllers.controller('ReserveTrainingController', ['$scope', '$sta
var updateTrainingSlotId = function (slot, reservation) {
angular.forEach(reservation.slots, function (s) {
if (slot.start_at === slot.start_at) {
return slot.id = s.id
return slot.id = s.id;
}
})
}
});
};
/**
* Update the calendar's display to render the new attributes of the events
*/
var updateCalendar = function () { uiCalendarConfig.calendars.calendar.fullCalendar('rerenderEvents') }
var updateCalendar = function () { uiCalendarConfig.calendars.calendar.fullCalendar('rerenderEvents'); };
/**
* Asynchronously fetch the events from the API and refresh the calendar's view with these new events
*/
var refetchCalendar = function () {
$timeout(function () {
uiCalendarConfig.calendars.calendar.fullCalendar('refetchEvents')
return uiCalendarConfig.calendars.calendar.fullCalendar('rerenderEvents')
})
}
uiCalendarConfig.calendars.calendar.fullCalendar('refetchEvents');
return uiCalendarConfig.calendars.calendar.fullCalendar('rerenderEvents');
});
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize()
return initialize();
}
])
]);

View File

@ -9,16 +9,16 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Controllers.controller('WalletController', ['$scope', 'walletPromise', 'transactionsPromise',
function ($scope, walletPromise, transactionsPromise) {
/* PUBLIC SCOPE */
// current user wallet
$scope.wallet = walletPromise
$scope.wallet = walletPromise;
// current wallet transactions
return $scope.transactions = transactionsPromise
return $scope.transactions = transactionsPromise;
}
])
]);

View File

@ -1,34 +1,34 @@
'use strict'
'use strict';
Application.Directives.directive('bsJasnyFileinput', [function () {
return {
require: ['ngModel'],
link: function ($scope, elm, attrs, requiredCtrls) {
var ngModelCtrl = requiredCtrls[0]
var fileinput = elm.parents('[data-provides=fileinput]')
var filetypeRegex = attrs.bsJasnyFileinput
var ngModelCtrl = requiredCtrls[0];
var fileinput = elm.parents('[data-provides=fileinput]');
var filetypeRegex = attrs.bsJasnyFileinput;
fileinput.on('clear.bs.fileinput', function (e) {
if (ngModelCtrl) {
ngModelCtrl.$setViewValue(null)
ngModelCtrl.$setPristine()
$scope.$apply()
ngModelCtrl.$setViewValue(null);
ngModelCtrl.$setPristine();
$scope.$apply();
}
})
});
fileinput.on('change.bs.fileinput', function (e, files) {
if (ngModelCtrl) {
if (files) {
ngModelCtrl.$setViewValue(files.result)
ngModelCtrl.$setViewValue(files.result);
} else {
ngModelCtrl.$setPristine()
ngModelCtrl.$setPristine();
}
// TODO: ne marche pas pour filetype
if (filetypeRegex) {
if (files && typeof files.type !== 'undefined' && files.type.match(new RegExp(filetypeRegex))) { ngModelCtrl.$setValidity('filetype', true) } else { ngModelCtrl.$setValidity('filetype', false) }
if (files && typeof files.type !== 'undefined' && files.type.match(new RegExp(filetypeRegex))) { ngModelCtrl.$setValidity('filetype', true); } else { ngModelCtrl.$setValidity('filetype', false); }
};
}
$scope.$apply()
})
$scope.$apply();
});
}
}
}])
};
}]);

View File

@ -40,28 +40,28 @@ Application.Directives.directive('cart', [ '$rootScope', '$uibModal', 'dialogs',
templateUrl: '<%= asset_path "shared/_cart.html" %>',
link ($scope, element, attributes) {
// will store the user's plan if he choosed to buy one
$scope.selectedPlan = null
$scope.selectedPlan = null;
// total amount of the bill to pay
$scope.amountTotal = 0
$scope.amountTotal = 0;
// total amount of the elements in the cart, without considering any coupon
$scope.totalNoCoupon = 0
$scope.totalNoCoupon = 0;
// Discount coupon to apply to the basket, if any
$scope.coupon = { applied: null }
$scope.coupon = { applied: null };
// Global config: is the user authorized to change his bookings slots?
$scope.enableBookingMove = ($scope.settings.booking_move_enable === 'true')
$scope.enableBookingMove = ($scope.settings.booking_move_enable === 'true');
// Global config: delay in hours before a booking while changing the booking slot is forbidden
$scope.moveBookingDelay = parseInt($scope.settings.booking_move_delay)
$scope.moveBookingDelay = parseInt($scope.settings.booking_move_delay);
// Global config: is the user authorized to cancel his bookings?
$scope.enableBookingCancel = ($scope.settings.booking_cancel_enable === 'true')
$scope.enableBookingCancel = ($scope.settings.booking_cancel_enable === 'true');
// Global config: delay in hours before a booking while the cancellation is forbidden
$scope.cancelBookingDelay = parseInt($scope.settings.booking_cancel_delay)
$scope.cancelBookingDelay = parseInt($scope.settings.booking_cancel_delay);
/**
* Add the provided slot to the shopping cart (state transition from free to 'about to be reserved')
@ -69,9 +69,9 @@ Application.Directives.directive('cart', [ '$rootScope', '$uibModal', 'dialogs',
* @param slot {Object} fullCalendar event object
*/
$scope.validateSlot = function (slot) {
slot.isValid = true
return updateCartPrice()
}
slot.isValid = true;
return updateCartPrice();
};
/**
* Remove the provided slot from the shopping cart (state transition from 'about to be reserved' to free)
@ -81,29 +81,29 @@ Application.Directives.directive('cart', [ '$rootScope', '$uibModal', 'dialogs',
* @param [event] {Object} see https://docs.angularjs.org/guide/expression#-event-
*/
$scope.removeSlot = function (slot, index, event) {
if (event) { event.preventDefault() }
$scope.events.reserved.splice(index, 1)
if (event) { event.preventDefault(); }
$scope.events.reserved.splice(index, 1);
// if is was the last slot, we remove any plan from the cart
if ($scope.events.reserved.length === 0) {
$scope.selectedPlan = null
$scope.plan = null
$scope.modePlans = false
$scope.selectedPlan = null;
$scope.plan = null;
$scope.modePlans = false;
}
if (typeof $scope.onSlotRemovedFromCart === 'function') { $scope.onSlotRemovedFromCart(slot) }
return updateCartPrice()
}
if (typeof $scope.onSlotRemovedFromCart === 'function') { $scope.onSlotRemovedFromCart(slot); }
return updateCartPrice();
};
/**
* Checks that every selected slots were added to the shopping cart. Ie. will return false if
* any checked slot was not validated by the user.
*/
$scope.isSlotsValid = function () {
let isValid = true
let isValid = true;
angular.forEach($scope.events.reserved, function (m) {
if (!m.isValid) { return isValid = false }
})
return isValid
}
if (!m.isValid) { return isValid = false; }
});
return isValid;
};
/**
* Switch the user's view from the reservation agenda to the plan subscription
@ -111,12 +111,12 @@ Application.Directives.directive('cart', [ '$rootScope', '$uibModal', 'dialogs',
$scope.showPlans = function () {
// first, we ensure that a user was selected (admin) or logged (member)
if (Object.keys($scope.user).length > 0) {
return $scope.modePlans = true
return $scope.modePlans = true;
} else {
// otherwise we alert, this error musn't occur when the current user hasn't the admin role
return growl.error(_t('cart.please_select_a_member_first'))
return growl.error(_t('cart.please_select_a_member_first'));
}
}
};
/**
* Validates the shopping chart and redirect the user to the payment step
@ -124,23 +124,23 @@ Application.Directives.directive('cart', [ '$rootScope', '$uibModal', 'dialogs',
$scope.payCart = function () {
// first, we check that a user was selected
if (Object.keys($scope.user).length > 0) {
const reservation = mkReservation($scope.user, $scope.events.reserved, $scope.selectedPlan)
const reservation = mkReservation($scope.user, $scope.events.reserved, $scope.selectedPlan);
return Wallet.getWalletByUser({ user_id: $scope.user.id }, function (wallet) {
const amountToPay = helpers.getAmountToPay($scope.amountTotal, wallet.amount)
const amountToPay = helpers.getAmountToPay($scope.amountTotal, wallet.amount);
if (!$scope.isAdmin() && (amountToPay > 0)) {
return payByStripe(reservation)
return payByStripe(reservation);
} else {
if ($scope.isAdmin() || (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('cart.please_select_a_member_first'))
return growl.error(_t('cart.please_select_a_member_first'));
}
}
};
/**
* When modifying an already booked reservation, confirm the modification.
@ -155,62 +155,62 @@ Application.Directives.directive('cart', [ '$rootScope', '$uibModal', 'dialogs',
}
, function () { // success
// -> run the callback
if (typeof $scope.onSlotModifySuccess === 'function') { $scope.onSlotModifySuccess() }
if (typeof $scope.onSlotModifySuccess === 'function') { $scope.onSlotModifySuccess(); }
// -> set the events as successfully moved (to display a summary)
$scope.events.moved = {
newSlot: $scope.events.placable,
oldSlot: $scope.events.modifiable
}
};
// -> reset the 'moving' status
$scope.events.placable = null
return $scope.events.modifiable = null
$scope.events.placable = null;
return $scope.events.modifiable = null;
}
, function (err) { // failure
growl.error(_t('cart.unable_to_change_the_reservation'))
return console.error(err)
})
}
growl.error(_t('cart.unable_to_change_the_reservation'));
return console.error(err);
});
};
/**
* Cancel the current booking modification, reseting the whole process
* @param event {Object} see https://docs.angularjs.org/guide/expression#-event-
*/
$scope.cancelModifySlot = function (event) {
if (event) { event.preventDefault() }
if (typeof $scope.onSlotModifyCancel === 'function') { $scope.onSlotModifyCancel() }
$scope.events.placable = null
return $scope.events.modifiable = null
}
if (event) { event.preventDefault(); }
if (typeof $scope.onSlotModifyCancel === 'function') { $scope.onSlotModifyCancel(); }
$scope.events.placable = null;
return $scope.events.modifiable = null;
};
/**
* When modifying an already booked reservation, cancel the choice of the new slot
* @param e {Object} see https://docs.angularjs.org/guide/expression#-event-
*/
$scope.removeSlotToPlace = function (e) {
e.preventDefault()
if (typeof $scope.onSlotModifyUnselect === 'function') { $scope.onSlotModifyUnselect() }
return $scope.events.placable = null
}
e.preventDefault();
if (typeof $scope.onSlotModifyUnselect === 'function') { $scope.onSlotModifyUnselect(); }
return $scope.events.placable = null;
};
/**
* Checks if $scope.events.modifiable and $scope.events.placable have tag incompatibilities
* @returns {boolean} true in case of incompatibility
*/
$scope.tagMissmatch = function () {
if ($scope.events.placable.tag_ids.length === 0) { return false }
if ($scope.events.placable.tag_ids.length === 0) { return false; }
for (let tag of Array.from($scope.events.modifiable.tags)) {
if (!Array.from($scope.events.placable.tag_ids).includes(tag.id)) {
return true
return true;
}
}
return false
}
return false;
};
/**
* Check if the currently logged user has teh 'admin' role?
* @returns {boolean}
*/
$scope.isAdmin = function () { return $rootScope.currentUser && ($rootScope.currentUser.role === 'admin') }
$scope.isAdmin = function () { return $rootScope.currentUser && ($rootScope.currentUser.role === 'admin'); };
/* PRIVATE SCOPE */
@ -221,27 +221,27 @@ Application.Directives.directive('cart', [ '$rootScope', '$uibModal', 'dialogs',
// What the bound slot
$scope.$watch('slotSelectionTime', function (newValue, oldValue) {
if (newValue !== oldValue) {
return slotSelectionChanged()
return slotSelectionChanged();
}
})
});
$scope.$watch('user', function (newValue, oldValue) {
if (newValue !== oldValue) {
resetCartState()
return updateCartPrice()
resetCartState();
return updateCartPrice();
}
})
});
$scope.$watch('planSelectionTime', function (newValue, oldValue) {
if (newValue !== oldValue) {
return planSelectionChanged()
return planSelectionChanged();
}
})
});
// 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 updateCartPrice()
return updateCartPrice();
}
})
}
});
};
/**
* Callback triggered when the selected slot changed
@ -251,57 +251,57 @@ Application.Directives.directive('cart', [ '$rootScope', '$uibModal', 'dialogs',
if (!$scope.slot.is_reserved && !$scope.events.modifiable && !$scope.slot.is_completed) {
// slot is not reserved and we are not currently modifying a slot
// -> can be added to cart or removed if already present
const index = $scope.events.reserved.indexOf($scope.slot)
const index = $scope.events.reserved.indexOf($scope.slot);
if (index === -1) {
if (($scope.limitToOneSlot === 'true') && $scope.events.reserved[0]) {
// if we limit the number of slots in the cart to 1, and there is already
// a slot in the cart, we remove it before adding the new one
$scope.removeSlot($scope.events.reserved[0], 0)
$scope.removeSlot($scope.events.reserved[0], 0);
}
// slot is not in the cart, so we add it
$scope.events.reserved.push($scope.slot)
if (typeof $scope.onSlotAddedToCart === 'function') { $scope.onSlotAddedToCart() }
$scope.events.reserved.push($scope.slot);
if (typeof $scope.onSlotAddedToCart === 'function') { $scope.onSlotAddedToCart(); }
} else {
// slot is in the cart, remove it
$scope.removeSlot($scope.slot, index)
$scope.removeSlot($scope.slot, index);
}
// in every cases, because a new reservation has started, we reset the cart content
resetCartState()
resetCartState();
// finally, we update the prices
return updateCartPrice()
return updateCartPrice();
} else if (!$scope.slot.is_reserved && !$scope.slot.is_completed && $scope.events.modifiable) {
// slot is not reserved but we are currently modifying a slot
// -> we request the calender to change the rendering
if (typeof $scope.onSlotModifyUnselect === 'function') { $scope.onSlotModifyUnselect() }
if (typeof $scope.onSlotModifyUnselect === 'function') { $scope.onSlotModifyUnselect(); }
// -> then, we re-affect the destination slot
if (!$scope.events.placable || ($scope.events.placable._id !== $scope.slot._id)) {
return $scope.events.placable = $scope.slot
return $scope.events.placable = $scope.slot;
} else {
return $scope.events.placable = null
return $scope.events.placable = null;
}
} else if ($scope.slot.is_reserved && $scope.events.modifiable && ($scope.slot.is_reserved._id === $scope.events.modifiable._id)) {
// slot is reserved and currently modified
// -> we cancel the modification
return $scope.cancelModifySlot()
return $scope.cancelModifySlot();
} else if ($scope.slot.is_reserved && (slotCanBeModified($scope.slot) || slotCanBeCanceled($scope.slot)) && !$scope.events.modifiable && ($scope.events.reserved.length === 0)) {
// slot is reserved and is ok to be modified or cancelled
// but we are not currently running a modification or having any slots in the cart
// -> first the affect the modification/cancellation rights attributes to the current slot
resetCartState()
$scope.slot.movable = slotCanBeModified($scope.slot)
$scope.slot.cancelable = slotCanBeCanceled($scope.slot)
resetCartState();
$scope.slot.movable = slotCanBeModified($scope.slot);
$scope.slot.cancelable = slotCanBeCanceled($scope.slot);
// -> then, we open a dialog to ask to the user to choose an action
return dialogs.confirm({
templateUrl: '<%= asset_path "shared/confirm_modify_slot_modal.html" %>',
resolve: {
object () { return $scope.slot }
object () { return $scope.slot; }
}
}
, function (type) {
// the user has choosen an action, so we proceed
if (type === 'move') {
if (typeof $scope.onSlotStartToModify === 'function') { $scope.onSlotStartToModify() }
return $scope.events.modifiable = $scope.slot
if (typeof $scope.onSlotStartToModify === 'function') { $scope.onSlotStartToModify(); }
return $scope.events.modifiable = $scope.slot;
} else if (type === 'cancel') {
return dialogs.confirm(
{
@ -310,67 +310,67 @@ Application.Directives.directive('cart', [ '$rootScope', '$uibModal', 'dialogs',
return {
title: _t('cart.confirmation_required'),
msg: _t('cart.do_you_really_want_to_cancel_this_reservation')
}
};
}
}
},
function () { // cancel confirmed
Slot.cancel({ id: $scope.slot.id }, function () { // successfully canceled
growl.success(_t('cart.reservation_was_cancelled_successfully'))
if (typeof $scope.onSlotCancelSuccess === 'function') { return $scope.onSlotCancelSuccess() }
growl.success(_t('cart.reservation_was_cancelled_successfully'));
if (typeof $scope.onSlotCancelSuccess === 'function') { return $scope.onSlotCancelSuccess(); }
}
, function () { // error while canceling
growl.error(_t('cart.cancellation_failed'))
})
growl.error(_t('cart.cancellation_failed'));
});
}
)
);
}
})
});
}
}
}
};
/**
* Reset the parameters that may lead to a wrong price but leave the content (events added to cart)
*/
var resetCartState = function () {
$scope.selectedPlan = null
$scope.coupon.applied = null
$scope.events.moved = null
$scope.events.paid = []
$scope.events.modifiable = null
return $scope.events.placable = null
}
$scope.selectedPlan = null;
$scope.coupon.applied = null;
$scope.events.moved = null;
$scope.events.paid = [];
$scope.events.modifiable = null;
return $scope.events.placable = null;
};
/**
* Determines if the provided booked slot is able to be modified by the user.
* @param slot {Object} fullCalendar event object
*/
var slotCanBeModified = function (slot) {
if ($scope.isAdmin()) { return true }
const slotStart = moment(slot.start)
const now = moment()
if ($scope.isAdmin()) { return true; }
const slotStart = moment(slot.start);
const now = moment();
if (slot.can_modify && $scope.enableBookingMove && (slotStart.diff(now, 'hours') >= $scope.moveBookingDelay)) {
return true
return true;
} else {
return false
return false;
}
}
};
/**
* Determines if the provided booked slot is able to be canceled by the user.
* @param slot {Object} fullCalendar event object
*/
var slotCanBeCanceled = function (slot) {
if ($scope.isAdmin()) { return true }
const slotStart = moment(slot.start)
const now = moment()
if ($scope.isAdmin()) { return true; }
const slotStart = moment(slot.start);
const now = moment();
if (slot.can_modify && $scope.enableBookingCancel && (slotStart.diff(now, 'hours') >= $scope.cancelBookingDelay)) {
return true
return true;
} else {
return false
return false;
}
}
};
/**
* Callback triggered when the selected slot changed
@ -378,47 +378,47 @@ Application.Directives.directive('cart', [ '$rootScope', '$uibModal', 'dialogs',
var planSelectionChanged = function () {
if (Auth.isAuthenticated()) {
if ($scope.selectedPlan !== $scope.plan) {
$scope.selectedPlan = $scope.plan
$scope.selectedPlan = $scope.plan;
} else {
$scope.selectedPlan = null
$scope.selectedPlan = null;
}
return updateCartPrice()
return updateCartPrice();
} else {
return $rootScope.login(null, function () {
$scope.selectedPlan = $scope.plan
return updateCartPrice()
})
$scope.selectedPlan = $scope.plan;
return updateCartPrice();
});
}
}
};
/**
* Update the total price of the current selection/reservation
*/
var updateCartPrice = function () {
if (Object.keys($scope.user).length > 0) {
const r = mkReservation($scope.user, $scope.events.reserved, $scope.selectedPlan)
const r = mkReservation($scope.user, $scope.events.reserved, $scope.selectedPlan);
return Price.compute(mkRequestParams(r, $scope.coupon.applied), function (res) {
$scope.amountTotal = res.price
$scope.totalNoCoupon = res.price_without_coupon
return setSlotsDetails(res.details)
})
$scope.amountTotal = res.price;
$scope.totalNoCoupon = res.price_without_coupon;
return setSlotsDetails(res.details);
});
} else {
// otherwise we alert, this error musn't occur when the current user is not admin
growl.warning(_t('cart.please_select_a_member_first'))
return $scope.amountTotal = null
growl.warning(_t('cart.please_select_a_member_first'));
return $scope.amountTotal = null;
}
}
};
var setSlotsDetails = function (details) {
angular.forEach($scope.events.reserved, function (slot) {
angular.forEach(details.slots, function (s) {
if (moment(s.start_at).isSame(slot.start)) {
slot.promo = s.promo
return slot.price = s.price
slot.promo = s.promo;
return slot.price = s.price;
}
})
})
}
});
});
};
/**
* Format the parameters expected by /api/prices/compute or /api/reservations and return the resulting object
@ -430,8 +430,8 @@ Application.Directives.directive('cart', [ '$rootScope', '$uibModal', 'dialogs',
return {
reservation,
coupon_code: ((coupon ? coupon.code : undefined))
}
}
};
};
/**
* Create an hash map implementing the Reservation specs
@ -447,18 +447,18 @@ Application.Directives.directive('cart', [ '$rootScope', '$uibModal', 'dialogs',
reservable_type: $scope.reservableType,
slots_attributes: [],
plan_id: ((plan ? plan.id : undefined))
}
};
angular.forEach(slots, function (slot, key) {
reservation.slots_attributes.push({
start_at: slot.start,
end_at: slot.end,
availability_id: slot.availability_id,
offered: slot.offered || false
})
})
});
});
return reservation
}
return reservation;
};
/**
* Open a modal window that allows the user to process a credit card payment for his current shopping cart.
@ -469,79 +469,79 @@ Application.Directives.directive('cart', [ '$rootScope', '$uibModal', 'dialogs',
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;
},
coupon () {
return $scope.coupon.applied
return $scope.coupon.applied;
}
},
controller: ['$scope', '$uibModalInstance', '$state', 'reservation', 'price', 'cgv', 'Auth', 'Reservation', 'wallet', 'helpers', '$filter', 'coupon',
function ($scope, $uibModalInstance, $state, reservation, price, cgv, Auth, Reservation, wallet, helpers, $filter, coupon) {
// user 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 to process the payment with Stripe, triggered on button click
*/
$scope.payment = function (status, response) {
if (response.error) {
growl.error(response.error.message)
growl.error(response.error.message);
} else {
$scope.attempting = true
$scope.reservation.card_token = response.id
$scope.attempting = true;
$scope.reservation.card_token = response.id;
Reservation.save(
mkRequestParams($scope.reservation, coupon),
function (reservation) { $uibModalInstance.close(reservation) },
function (reservation) { $uibModalInstance.close(reservation); },
function (response) {
$scope.alerts = []
$scope.alerts = [];
if (response.status === 500) {
$scope.alerts.push({
msg: response.statusText,
type: 'danger'
})
});
} else {
if (response.data.card && (response.data.card.join('').length > 0)) {
$scope.alerts.push({
msg: response.data.card.join('. '),
type: 'danger'
})
});
} else if (response.data.payment && (response.data.payment.join('').length > 0)) {
$scope.alerts.push({
msg: response.data.payment.join('. '),
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); });
};
/**
* Open a modal window that allows the user to process a local payment for his current shopping cart (admin only).
*/
@ -551,43 +551,43 @@ Application.Directives.directive('cart', [ '$rootScope', '$uibModal', 'dialogs',
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 wallet amount
$scope.walletAmount = wallet.amount
$scope.walletAmount = wallet.amount;
// Global price (total of all items)
$scope.price = price.price
$scope.price = price.price;
// Price to pay (wallet deducted)
$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('cart.confirm_payment_of_html', { ROLE: $rootScope.currentUser.role, AMOUNT: $filter('currency')($scope.amount) }, 'messageformat')
$scope.validButtonName = _t('cart.confirm_payment_of_html', { ROLE: $rootScope.currentUser.role, AMOUNT: $filter('currency')($scope.amount) }, 'messageformat');
} else {
if ((price.price > 0) && ($scope.walletAmount === 0)) {
$scope.validButtonName = _t('cart.confirm_payment_of_html', { ROLE: $rootScope.currentUser.role, AMOUNT: $filter('currency')(price.price) }, 'messageformat')
$scope.validButtonName = _t('cart.confirm_payment_of_html', { ROLE: $rootScope.currentUser.role, AMOUNT: $filter('currency')(price.price) }, 'messageformat');
} else {
$scope.validButtonName = _t('confirm')
$scope.validButtonName = _t('confirm');
}
}
@ -595,40 +595,40 @@ Application.Directives.directive('cart', [ '$rootScope', '$uibModal', 'dialogs',
* Callback to process the local payment, triggered on button click
*/
$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 = []
$scope.alerts.push({ msg: _t('cart.a_problem_occured_during_the_payment_process_please_try_again_later'), type: 'danger' })
return $scope.attempting = false
})
}
$scope.cancel = function () { $uibModalInstance.dismiss('cancel') }
$scope.alerts = [];
$scope.alerts.push({ msg: _t('cart.a_problem_occured_during_the_payment_process_please_try_again_later'), type: 'danger' });
return $scope.attempting = false;
});
};
$scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
}
]
}).result['finally'](null).then(function (reservation) { afterPayment(reservation) })
}
}).result['finally'](null).then(function (reservation) { afterPayment(reservation); });
};
/**
* Actions to run after the payment was successfull
*/
var afterPayment = function (reservation) {
// we set the cart content as 'paid' to display a summary of the transaction
$scope.events.paid = $scope.events.reserved
$scope.events.paid = $scope.events.reserved;
// we call the external callback if present
if (typeof $scope.afterPayment === 'function') { $scope.afterPayment(reservation) }
if (typeof $scope.afterPayment === 'function') { $scope.afterPayment(reservation); }
// we reset the coupon and the cart content and we unselect the slot
$scope.events.reserved = []
$scope.coupon.applied = null
$scope.slot = null
return $scope.selectedPlan = null
}
$scope.events.reserved = [];
$scope.coupon.applied = null;
$scope.slot = null;
return $scope.selectedPlan = null;
};
// !!! MUST BE CALLED AT THE END of the directive
return initialize()
return initialize();
}
})
});
}
])
]);

View File

@ -14,25 +14,25 @@ Application.Directives.directive('confirmationNeeded', [() =>
priority: 1,
terminal: true,
link (scope, element, attrs) {
const msg = attrs.confirmationNeeded || 'Are you sure?'
const clickAction = attrs.ngClick
const msg = attrs.confirmationNeeded || 'Are you sure?';
const clickAction = attrs.ngClick;
return element.bind('click', function () {
if (attrs.confirmationNeededIf != null) {
const confirmNeededIf = scope.$eval(attrs.confirmationNeededIf)
const confirmNeededIf = scope.$eval(attrs.confirmationNeededIf);
if (confirmNeededIf === true) {
if (window.confirm(msg)) {
return scope.$eval(clickAction)
return scope.$eval(clickAction);
}
} else {
return scope.$eval(clickAction)
return scope.$eval(clickAction);
}
} else {
if (window.confirm(msg)) {
return scope.$eval(clickAction)
return scope.$eval(clickAction);
}
}
})
});
}
})
])
]);

View File

@ -22,54 +22,54 @@ Application.Directives.directive('coupon', [ '$rootScope', 'Coupon', '_t', funct
link ($scope, element, attributes) {
// Whether code input is shown or not (ie. the link 'I have a coupon' is shown)
$scope.code =
{ input: false }
{ input: false };
// Available status are: 'pending', 'valid', 'invalid'
$scope.status = 'pending'
$scope.status = 'pending';
// Binding for the code inputed (see the attached template)
$scope.couponCode = null
$scope.couponCode = null;
// Code validation messages
$scope.messages = []
$scope.messages = [];
// Re-compute if the code can be applied when the total of the cart changes
$scope.$watch('total', function (newValue, oldValue) {
if (newValue && (newValue !== oldValue) && $scope.couponCode) {
return $scope.validateCode()
return $scope.validateCode();
}
})
});
/**
* Callback to validate the code
*/
$scope.validateCode = function () {
$scope.messages = []
$scope.messages = [];
if ($scope.couponCode === '') {
$scope.status = 'pending'
return $scope.coupon = null
$scope.status = 'pending';
return $scope.coupon = null;
} else {
return Coupon.validate({ code: $scope.couponCode, user_id: $scope.userId, amount: $scope.total }, function (res) {
$scope.status = 'valid'
$scope.coupon = res
$scope.status = 'valid';
$scope.coupon = res;
if (res.type === 'percent_off') {
return $scope.messages.push({ type: 'success', message: _t('the_coupon_has_been_applied_you_get_PERCENT_discount', { PERCENT: res.percent_off }) })
return $scope.messages.push({ type: 'success', message: _t('the_coupon_has_been_applied_you_get_PERCENT_discount', { PERCENT: res.percent_off }) });
} else {
return $scope.messages.push({ type: 'success', message: _t('the_coupon_has_been_applied_you_get_AMOUNT_CURRENCY', { AMOUNT: res.amount_off, CURRENCY: $rootScope.currencySymbol }) })
return $scope.messages.push({ type: 'success', message: _t('the_coupon_has_been_applied_you_get_AMOUNT_CURRENCY', { AMOUNT: res.amount_off, CURRENCY: $rootScope.currencySymbol }) });
}
}
, function (err) {
$scope.status = 'invalid'
$scope.coupon = null
return $scope.messages.push({ type: 'danger', message: _t(`unable_to_apply_the_coupon_because_${err.data.status}`) })
})
$scope.status = 'invalid';
$scope.coupon = null;
return $scope.messages.push({ type: 'danger', message: _t(`unable_to_apply_the_coupon_because_${err.data.status}`) });
});
}
}
};
/**
* Callback to remove the message at provided index from the displayed list
*/
$scope.closeMessage = function (index) { $scope.messages.splice(index, 1) }
$scope.closeMessage = function (index) { $scope.messages.splice(index, 1); };
}
})
}])
});
}]);

View File

@ -9,7 +9,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Directives.directive('fileread', [ () =>
({
@ -20,11 +20,11 @@ Application.Directives.directive('fileread', [ () =>
link (scope, element, attributes) {
return element.bind('change', changeEvent =>
scope.$apply(() => scope.fileread = changeEvent.target.files[0])
)
);
}
})
])
]);
// This `bsHolder` angular directive is a workaround for
// an incompatability between angular and the holder.js
@ -38,11 +38,11 @@ Application.Directives.directive('bsHolder', [ () =>
.addTheme('icon-xs', { background: 'white', foreground: '#e0e0e0', size: 20, font: 'FontAwesome' })
.addTheme('icon-black-xs', { background: 'black', foreground: 'white', size: 20, font: 'FontAwesome' })
.addTheme('avatar', { background: '#eeeeee', foreground: '#555555', size: 16, font: 'FontAwesome' })
.run(element[0])
.run(element[0]);
}
})
])
]);
Application.Directives.directive('match', [ () =>
({
@ -53,11 +53,11 @@ Application.Directives.directive('match', [ () =>
},
link (scope, elem, attrs, ctrl) {
return scope.$watch(() => (ctrl.$pristine && angular.isUndefined(ctrl.$modelValue)) || (scope.match === ctrl.$modelValue)
, currentValue => ctrl.$setValidity('match', currentValue))
, currentValue => ctrl.$setValidity('match', currentValue));
}
})
])
]);
Application.Directives.directive('publishProject', [ () =>
({
@ -65,30 +65,30 @@ Application.Directives.directive('publishProject', [ () =>
link (scope, elem, attrs, ctrl) {
return elem.bind('click', function ($event) {
if ($event) {
$event.preventDefault()
$event.stopPropagation()
$event.preventDefault();
$event.stopPropagation();
}
if (elem.attr('disabled')) { return }
const input = angular.element('<input name="project[state]" type="hidden" value="published">')
const form = angular.element('form')
form.append(input)
form.triggerHandler('submit')
return form[0].submit()
})
if (elem.attr('disabled')) { return; }
const input = angular.element('<input name="project[state]" type="hidden" value="published">');
const form = angular.element('form');
form.append(input);
form.triggerHandler('submit');
return form[0].submit();
});
}
})
])
]);
Application.Directives.directive('disableAnimation', ['$animate', ($animate) =>
({
restrict: 'A',
link (scope, elem, attrs) {
return attrs.$observe('disableAnimation', value => $animate.enabled(!value, elem))
return attrs.$observe('disableAnimation', value => $animate.enabled(!value, elem));
}
})
])
]);
/**
* Isolate a form's scope from its parent : no nested validation
@ -98,34 +98,34 @@ Application.Directives.directive('isolateForm', [ () =>
restrict: 'A',
require: '?form',
link (scope, elm, attrs, ctrl) {
if (!ctrl) { return }
if (!ctrl) { return; }
// Do a copy of the controller
const ctrlCopy = {}
angular.copy(ctrl, ctrlCopy)
const ctrlCopy = {};
angular.copy(ctrl, ctrlCopy);
// Get the form's parent
const parent = elm.parent().controller('form')
const parent = elm.parent().controller('form');
// Remove parent link to the controller
parent.$removeControl(ctrl)
parent.$removeControl(ctrl);
// Replace form controller with a "isolated form"
const isolatedFormCtrl = {
$setValidity (validationToken, isValid, control) {
ctrlCopy.$setValidity(validationToken, isValid, control)
return parent.$setValidity(validationToken, true, ctrl)
ctrlCopy.$setValidity(validationToken, isValid, control);
return parent.$setValidity(validationToken, true, ctrl);
},
$setDirty () {
elm.removeClass('ng-pristine').addClass('ng-dirty')
ctrl.$dirty = true
return ctrl.$pristine = false
elm.removeClass('ng-pristine').addClass('ng-dirty');
ctrl.$dirty = true;
return ctrl.$pristine = false;
}
}
};
return angular.extend(ctrl, isolatedFormCtrl)
return angular.extend(ctrl, isolatedFormCtrl);
}
})
])
]);

View File

@ -16,5 +16,5 @@ Application.Directives.directive('fabUserAvatar', [ function () {
avatarClass: '@'
},
templateUrl: '<%= asset_path "shared/_user_avatar.html" %>'
})
}])
});
}]);

View File

@ -9,7 +9,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
/**
* This directive will allow to select a member.
@ -26,23 +26,23 @@ Application.Directives.directive('selectMember', [ 'Diacritics', 'Member', funct
link (scope, element, attributes) {
return scope.autoCompleteName = function (nameLookup) {
if (!nameLookup) {
return
return;
}
scope.isLoadingMembers = true
const asciiName = Diacritics.remove(nameLookup)
scope.isLoadingMembers = true;
const asciiName = Diacritics.remove(nameLookup);
const q = { query: asciiName }
const q = { query: asciiName };
if (attributes.subscription) {
q['subscription'] = attributes.subscription
q['subscription'] = attributes.subscription;
}
return Member.search(q, function (users) {
scope.matchingMembers = users
return scope.isLoadingMembers = false
scope.matchingMembers = users;
return scope.isLoadingMembers = false;
}
, function (error) { console.error(error) })
}
, function (error) { console.error(error); });
};
}
})
}])
});
}]);

View File

@ -19,18 +19,18 @@ Application.Directives.directive('socialLink', [ function () {
templateUrl: '<%= asset_path "shared/_social_link.html" %>',
link (scope, element, attributes) {
if (scope.network === 'dailymotion') {
scope.image = "<%= asset_path('social/dailymotion.png') %>"
return scope.altText = 'd'
scope.image = "<%= asset_path('social/dailymotion.png') %>";
return scope.altText = 'd';
} else if (scope.network === 'echosciences') {
scope.image = "<%= asset_path('social/echosciences.png') %>"
return scope.altText = 'E)'
scope.image = "<%= asset_path('social/echosciences.png') %>";
return scope.altText = 'E)';
} else {
if (scope.network === 'website') {
return scope.faClass = 'fa-globe'
return scope.faClass = 'fa-globe';
} else {
return scope.faClass = `fa-${scope.network.replace('_', '-')}`
return scope.faClass = `fa-${scope.network.replace('_', '-')}`;
}
}
}
})
}])
});
}]);

View File

@ -1,23 +1,23 @@
'use strict'
'use strict';
// https://github.com/gtramontina/stripe-angular
Application.Directives.directive('stripeForm', ['$window',
function ($window) {
var directive = { restrict: 'A' }
var directive = { restrict: 'A' };
directive.link = function (scope, element, attributes) {
var form = angular.element(element)
var form = angular.element(element);
form.bind('submit', function () {
var button = form.find('button')
button.prop('disabled', true)
var button = form.find('button');
button.prop('disabled', true);
$window.Stripe.createToken(form[0], function () {
var args = arguments
var args = arguments;
scope.$apply(function () {
scope[attributes.stripeForm].apply(scope, args)
})
scope[attributes.stripeForm].apply(scope, args);
});
// button.prop('disabled', false);
})
})
}
return directive
}])
});
});
};
return directive;
}]);

View File

@ -10,46 +10,46 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Directives.directive('url', [ function () {
const URL_REGEXP = /^(https?:\/\/)([\da-z\.-]+)\.([-a-z0-9\.]{2,30})([\/\w \.-]*)*\/?$/
const URL_REGEXP = /^(https?:\/\/)([\da-z\.-]+)\.([-a-z0-9\.]{2,30})([\/\w \.-]*)*\/?$/;
return {
require: 'ngModel',
link (scope, element, attributes, ctrl) {
return ctrl.$validators.url = function (modelValue, viewValue) {
if (ctrl.$isEmpty(modelValue)) {
return true
return true;
}
if (URL_REGEXP.test(viewValue)) {
return true
return true;
}
// otherwise, this is invalid
return false
}
return false;
};
}
}
};
}
])
]);
Application.Directives.directive('endpoint', [ function () {
const ENDPOINT_REGEXP = /^\/?([-._~:?#\[\]@!$&'()*+,;=%\w]+\/?)*$/
const ENDPOINT_REGEXP = /^\/?([-._~:?#\[\]@!$&'()*+,;=%\w]+\/?)*$/;
return {
require: 'ngModel',
link (scope, element, attributes, ctrl) {
return ctrl.$validators.endpoint = function (modelValue, viewValue) {
if (ctrl.$isEmpty(modelValue)) {
return true
return true;
}
if (ENDPOINT_REGEXP.test(viewValue)) {
return true
return true;
}
// otherwise, this is invalid
return false
}
return false;
};
}
}
};
}
])
]);

View File

@ -11,142 +11,142 @@
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Filters.filter('array', [ () =>
function (arrayLength) {
if (arrayLength) {
arrayLength = Math.ceil(arrayLength)
const arr = new Array(arrayLength)
arrayLength = Math.ceil(arrayLength);
const arr = new Array(arrayLength);
for (let i = 0, end = arrayLength, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {
arr[i] = i
arr[i] = i;
}
return arr
return arr;
}
}
])
]);
// filter for projects and trainings
Application.Filters.filter('machineFilter', [ () =>
function (elements, selectedMachine) {
if (!angular.isUndefined(elements) && !angular.isUndefined(selectedMachine) && (elements != null) && (selectedMachine != null)) {
const filteredElements = []
const filteredElements = [];
angular.forEach(elements, function (element) {
if (element.machine_ids.indexOf(selectedMachine) !== -1) {
return filteredElements.push(element)
return filteredElements.push(element);
}
})
return filteredElements
});
return filteredElements;
} else {
return elements
return elements;
}
}
])
]);
Application.Filters.filter('projectMemberFilter', [ 'Auth', Auth =>
function (projects, selectedMember) {
if (!angular.isUndefined(projects) && angular.isDefined(selectedMember) && (projects != null) && (selectedMember != null) && (selectedMember !== '')) {
const filteredProject = []
const filteredProject = [];
// Mes projets
if (selectedMember === '0') {
angular.forEach(projects, function (project) {
if (project.author_id === Auth._currentUser.id) {
return filteredProject.push(project)
return filteredProject.push(project);
}
})
});
// les projets auxquels je collabore
} else {
angular.forEach(projects, function (project) {
if (project.user_ids.indexOf(Auth._currentUser.id) !== -1) {
return filteredProject.push(project)
return filteredProject.push(project);
}
})
});
}
return filteredProject
return filteredProject;
} else {
return projects
return projects;
}
}
])
]);
Application.Filters.filter('themeFilter', [ () =>
function (projects, selectedTheme) {
if (!angular.isUndefined(projects) && !angular.isUndefined(selectedTheme) && (projects != null) && (selectedTheme != null)) {
const filteredProjects = []
const filteredProjects = [];
angular.forEach(projects, function (project) {
if (project.theme_ids.indexOf(selectedTheme) !== -1) {
return filteredProjects.push(project)
return filteredProjects.push(project);
}
})
return filteredProjects
});
return filteredProjects;
} else {
return projects
return projects;
}
}
])
]);
Application.Filters.filter('componentFilter', [ () =>
function (projects, selectedComponent) {
if (!angular.isUndefined(projects) && !angular.isUndefined(selectedComponent) && (projects != null) && (selectedComponent != null)) {
const filteredProjects = []
const filteredProjects = [];
angular.forEach(projects, function (project) {
if (project.component_ids.indexOf(selectedComponent) !== -1) {
return filteredProjects.push(project)
return filteredProjects.push(project);
}
})
return filteredProjects
});
return filteredProjects;
} else {
return projects
return projects;
}
}
])
]);
Application.Filters.filter('projectsByAuthor', [ () =>
function (projects, authorId) {
if (!angular.isUndefined(projects) && angular.isDefined(authorId) && (projects != null) && (authorId != null) && (authorId !== '')) {
const filteredProject = []
const filteredProject = [];
angular.forEach(projects, function (project) {
if (project.author_id === authorId) {
return filteredProject.push(project)
return filteredProject.push(project);
}
})
return filteredProject
});
return filteredProject;
} else {
return projects
return projects;
}
}
])
]);
Application.Filters.filter('projectsCollabored', [ () =>
function (projects, memberId) {
if (!angular.isUndefined(projects) && angular.isDefined(memberId) && (projects != null) && (memberId != null) && (memberId !== '')) {
const filteredProject = []
const filteredProject = [];
angular.forEach(projects, function (project) {
if (project.user_ids.indexOf(memberId) !== -1) {
return filteredProject.push(project)
return filteredProject.push(project);
}
})
return filteredProject
});
return filteredProject;
} else {
return projects
return projects;
}
}
])
]);
// depend on humanize.js lib in /vendor
Application.Filters.filter('humanize', [ () =>
(element, param) => Humanize.truncate(element, param, null)
])
]);
/**
* This filter will convert ASCII carriage-return character to the HTML break-line tag
@ -154,11 +154,11 @@ Application.Filters.filter('humanize', [ () =>
Application.Filters.filter('breakFilter', [ () =>
function (text) {
if (text != null) {
return text.replace(/\n+/g, '<br />')
return text.replace(/\n+/g, '<br />');
}
}
])
]);
/**
* This filter will take a HTML text as input and will return it without the html tags
@ -166,224 +166,224 @@ Application.Filters.filter('breakFilter', [ () =>
Application.Filters.filter('simpleText', [ () =>
function (text) {
if (text != null) {
text = text.replace(/<br\s*\/?>/g, '\n')
return text.replace(/<\/?\w+[^>]*>/g, '')
text = text.replace(/<br\s*\/?>/g, '\n');
return text.replace(/<\/?\w+[^>]*>/g, '');
} else {
return ''
return '';
}
}
])
]);
Application.Filters.filter('toTrusted', [ '$sce', $sce =>
text => $sce.trustAsHtml(text)
])
]);
Application.Filters.filter('planIntervalFilter', [ () =>
(interval, intervalCount) => moment.duration(intervalCount, interval).humanize()
])
]);
Application.Filters.filter('humanReadablePlanName', ['$filter', $filter =>
function (plan, groups, short) {
if (plan != null) {
let result = plan.base_name
let result = plan.base_name;
if (groups != null) {
for (let group of Array.from(groups)) {
if (group.id === plan.group_id) {
if (short != null) {
result += ` - ${group.slug}`
result += ` - ${group.slug}`;
} else {
result += ` - ${group.name}`
result += ` - ${group.name}`;
}
}
}
}
result += ` - ${$filter('planIntervalFilter')(plan.interval, plan.interval_count)}`
return result
result += ` - ${$filter('planIntervalFilter')(plan.interval, plan.interval_count)}`;
return result;
}
}
])
]);
Application.Filters.filter('trainingReservationsFilter', [ () =>
function (elements, selectedScope) {
if (!angular.isUndefined(elements) && !angular.isUndefined(selectedScope) && (elements != null) && (selectedScope != null)) {
const filteredElements = []
const filteredElements = [];
angular.forEach(elements, function (element) {
switch (selectedScope) {
case 'future':
if (new Date(element.start_at) > new Date()) {
return filteredElements.push(element)
return filteredElements.push(element);
}
break
break;
case 'passed':
if ((new Date(element.start_at) <= new Date()) && !element.is_valid) {
return filteredElements.push(element)
return filteredElements.push(element);
}
break
break;
case 'valided':
if ((new Date(element.start_at) <= new Date()) && element.is_valid) {
return filteredElements.push(element)
return filteredElements.push(element);
}
break
break;
default:
return []
return [];
}
})
return filteredElements
});
return filteredElements;
} else {
return elements
return elements;
}
}
])
]);
Application.Filters.filter('eventsReservationsFilter', [ () =>
function (elements, selectedScope) {
if (!angular.isUndefined(elements) && !angular.isUndefined(selectedScope) && (elements != null) && (selectedScope != null) && (selectedScope !== '')) {
const filteredElements = []
const filteredElements = [];
angular.forEach(elements, function (element) {
if (angular.isUndefined(element.start_at)) { element.start_at = element.availability.start_at }
if (angular.isUndefined(element.end_at)) { element.end_at = element.availability.end_at }
if (angular.isUndefined(element.start_at)) { element.start_at = element.availability.start_at; }
if (angular.isUndefined(element.end_at)) { element.end_at = element.availability.end_at; }
switch (selectedScope) {
case 'future':
if (new Date(element.end_at) >= new Date()) {
return filteredElements.push(element)
return filteredElements.push(element);
}
break
break;
case 'future_asc':
if (new Date(element.end_at) >= new Date()) {
return filteredElements.push(element)
return filteredElements.push(element);
}
break
break;
case 'passed':
if (new Date(element.end_at) <= new Date()) {
return filteredElements.push(element)
return filteredElements.push(element);
}
break
break;
default:
return []
return [];
}
})
});
switch (selectedScope) {
case 'future_asc':
return filteredElements.reverse()
return filteredElements.reverse();
default:
return filteredElements
return filteredElements;
}
} else {
return elements
return elements;
}
}
])
]);
Application.Filters.filter('groupFilter', [ () =>
function (elements, member) {
if (!angular.isUndefined(elements) && !angular.isUndefined(member) && (elements != null) && (member != null)) {
const filteredElements = []
const filteredElements = [];
angular.forEach(elements, function (element) {
if (member.group_id === element.id) {
return filteredElements.push(element)
return filteredElements.push(element);
}
})
return filteredElements
});
return filteredElements;
} else {
return elements
return elements;
}
}
])
]);
Application.Filters.filter('groupByFilter', [ () =>
_.memoize((elements, field) => _.groupBy(elements, field))
])
]);
Application.Filters.filter('capitalize', [() =>
text => `${text.charAt(0).toUpperCase()}${text.slice(1).toLowerCase()}`
])
]);
Application.Filters.filter('reverse', [ () =>
function (items) {
if (!angular.isArray(items)) {
return items
return items;
}
return items.slice().reverse()
return items.slice().reverse();
}
])
]);
Application.Filters.filter('toArray', [ () =>
function (obj) {
if (!(obj instanceof Object)) { return obj }
if (!(obj instanceof Object)) { return obj; }
return _.map(obj, function (val, key) {
if (angular.isObject(val)) {
return Object.defineProperty(val, '$key', { __proto__: null, value: key })
return Object.defineProperty(val, '$key', { __proto__: null, value: key });
}
})
});
}
])
]);
Application.Filters.filter('toIsoDate', [ () =>
function (date) {
if (!(date instanceof Date) && !moment.isMoment(date)) { return date }
return moment(date).format('YYYY-MM-DD')
if (!(date instanceof Date) && !moment.isMoment(date)) { return date; }
return moment(date).format('YYYY-MM-DD');
}
])
]);
Application.Filters.filter('booleanFormat', [ '_t', _t =>
function (boolean) {
if (boolean || (boolean === 'true')) {
return _t('yes')
return _t('yes');
} else {
return _t('no')
return _t('no');
}
}
])
]);
Application.Filters.filter('booleanFormat', [ '_t', _t =>
function (boolean) {
if (((typeof boolean === 'boolean') && boolean) || ((typeof boolean === 'string') && (boolean === 'true'))) {
return _t('yes')
return _t('yes');
} else {
return _t('no')
return _t('no');
}
}
])
]);
Application.Filters.filter('maxCount', [ '_t', _t =>
function (max) {
if ((typeof max === 'undefined') || (max === null) || ((typeof max === 'number') && (max === 0))) {
return _t('unlimited')
return _t('unlimited');
} else {
return max
return max;
}
}
])
]);
Application.Filters.filter('filterDisabled', [ () =>
function (list, filter) {
if (angular.isArray(list)) {
return list.filter(function (e) {
switch (filter) {
case 'disabled': return e.disabled
case 'enabled': return !e.disabled
default: return true
case 'disabled': return e.disabled;
case 'enabled': return !e.disabled;
default: return true;
}
})
});
} else {
return list
return list;
}
}
])
]);

View File

@ -11,8 +11,8 @@
*/
angular.module('application.router', ['ui.router'])
.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function ($stateProvider, $urlRouterProvider, $locationProvider) {
$locationProvider.hashPrefix('!')
$urlRouterProvider.otherwise('/')
$locationProvider.hashPrefix('!');
$urlRouterProvider.otherwise('/');
// abstract root parents states
// these states controls the access rights to the various routes inherited from them
@ -30,14 +30,14 @@ angular.module('application.router', ['ui.router'])
'main': {}
},
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 }]
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; }]
},
onEnter: ['$rootScope', 'logoFile', 'logoBlackFile', function ($rootScope, logoFile, logoBlackFile) {
// Application logo
$rootScope.logo = logoFile.custom_asset
return $rootScope.logoBlack = logoBlackFile.custom_asset
$rootScope.logo = logoFile.custom_asset;
return $rootScope.logoBlack = logoBlackFile.custom_asset;
}]
})
.state('app.public', {
@ -49,10 +49,10 @@ angular.module('application.router', ['ui.router'])
authorizedRoles: ['member', 'admin']
},
resolve: {
currentUser: ['Auth', function (Auth) { return Auth.currentUser() }]
currentUser: ['Auth', function (Auth) { return Auth.currentUser(); }]
},
onEnter: ['$state', '$timeout', 'currentUser', '$rootScope', function ($state, $timeout, currentUser, $rootScope) {
$rootScope.currentUser = currentUser
$rootScope.currentUser = currentUser;
}]
})
.state('app.admin', {
@ -61,10 +61,10 @@ angular.module('application.router', ['ui.router'])
authorizedRoles: ['admin']
},
resolve: {
currentUser: ['Auth', function (Auth) { return Auth.currentUser() }]
currentUser: ['Auth', function (Auth) { return Auth.currentUser(); }]
},
onEnter: ['$state', '$timeout', 'currentUser', '$rootScope', function ($state, $timeout, currentUser, $rootScope) {
$rootScope.currentUser = currentUser
$rootScope.currentUser = currentUser;
}]
})
@ -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', {
@ -90,12 +90,12 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
lastMembersPromise: ['Member', function (Member) { return Member.lastSubscribed({ limit: 4 }).$promise }],
lastProjectsPromise: ['Project', function (Project) { return Project.lastPublished().$promise }],
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 }]
lastMembersPromise: ['Member', function (Member) { return Member.lastSubscribed({ limit: 4 }).$promise; }],
lastProjectsPromise: ['Project', function (Project) { return Project.lastPublished().$promise; }],
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; }]
}
})
@ -109,12 +109,12 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['fablab_name', 'name_genre']" }).$promise }],
activeProviderPromise: ['AuthProvider', function (AuthProvider) { return AuthProvider.active().$promise }],
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 }]
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['fablab_name', 'name_genre']" }).$promise; }],
activeProviderPromise: ['AuthProvider', function (AuthProvider) { return AuthProvider.active().$promise; }],
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; }]
}
})
@ -123,7 +123,7 @@ angular.module('application.router', ['ui.router'])
abstract: true,
url: '/dashboard',
resolve: {
memberPromise: ['Member', 'currentUser', function (Member, currentUser) { return Member.get({ id: currentUser.id }).$promise }]
memberPromise: ['Member', 'currentUser', function (Member, currentUser) { return Member.get({ id: currentUser.id }).$promise; }]
}
})
.state('app.logged.dashboard.profile', {
@ -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', {
@ -147,9 +147,9 @@ 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 }]
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; }]
}
})
.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', {
@ -209,9 +209,9 @@ 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 }]
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; }]
}
})
@ -225,8 +225,8 @@ 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 }]
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; }]
}
})
.state('app.logged.members', {
@ -238,8 +238,8 @@ 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 }]
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; }]
}
})
@ -253,10 +253,10 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
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 }]
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; }]
}
})
.state('app.logged.projects_new', {
@ -268,8 +268,8 @@ 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 }]
allowedExtensions: ['Project', function (Project) { return Project.allowedExtensions().$promise; }],
translations: [ 'Translations', function (Translations) { return Translations.query(['app.logged.projects_new', 'app.shared.project']).$promise; }]
}
})
.state('app.public.projects_show', {
@ -281,8 +281,8 @@ 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 }]
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; }]
}
})
.state('app.logged.projects_edit', {
@ -294,9 +294,9 @@ 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 }]
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; }]
}
})
@ -310,8 +310,8 @@ 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 }]
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; }]
}
})
.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', {
@ -335,8 +335,8 @@ 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 }]
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; }]
}
})
.state('app.logged.machines_reserve', {
@ -348,9 +348,9 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
plansPromise: ['Plan', function (Plan) { return Plan.query().$promise }],
groupsPromise: ['Group', function (Group) { return Group.query().$promise }],
machinePromise: ['Machine', '$stateParams', function (Machine, $stateParams) { return Machine.get({ id: $stateParams.id }).$promise }],
plansPromise: ['Plan', function (Plan) { return Plan.query().$promise; }],
groupsPromise: ['Group', function (Group) { return Group.query().$promise; }],
machinePromise: ['Machine', '$stateParams', function (Machine, $stateParams) { return Machine.get({ id: $stateParams.id }).$promise; }],
settingsPromise: ['Setting', function (Setting) {
return Setting.query({
names: `['machine_explications_alert', \
@ -361,12 +361,12 @@ angular.module('application.router', ['ui.router'])
'booking_cancel_enable', \
'booking_cancel_delay', \
'subscription_explications_alert']`
}).$promise
}).$promise;
}],
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
'app.shared.wallet', 'app.shared.coupon_input', 'app.shared.cart']).$promise;
}]
}
})
@ -379,8 +379,8 @@ 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 }]
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; }]
}
})
@ -395,8 +395,8 @@ 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 }]
spacesPromise: ['Space', function (Space) { return Space.query().$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', {
@ -422,8 +422,8 @@ 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 }]
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; }]
}
})
.state('app.admin.space_edit', {
@ -436,8 +436,8 @@ 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 }]
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; }]
}
})
.state('app.logged.space_reserve', {
@ -450,10 +450,10 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
spacePromise: ['Space', '$stateParams', function (Space, $stateParams) { return Space.get({ id: $stateParams.id }).$promise }],
availabilitySpacesPromise: ['Availability', '$stateParams', function (Availability, $stateParams) { return Availability.spaces({ spaceId: $stateParams.id }).$promise }],
plansPromise: ['Plan', function (Plan) { return Plan.query().$promise }],
groupsPromise: ['Group', function (Group) { return Group.query().$promise }],
spacePromise: ['Space', '$stateParams', function (Space, $stateParams) { return Space.get({ id: $stateParams.id }).$promise; }],
availabilitySpacesPromise: ['Availability', '$stateParams', function (Availability, $stateParams) { return Availability.spaces({ spaceId: $stateParams.id }).$promise; }],
plansPromise: ['Plan', function (Plan) { return Plan.query().$promise; }],
groupsPromise: ['Group', function (Group) { return Group.query().$promise; }],
settingsPromise: ['Setting', function (Setting) {
return Setting.query({
names: `['booking_window_start', \
@ -463,12 +463,12 @@ angular.module('application.router', ['ui.router'])
'booking_cancel_enable', \
'booking_cancel_delay', \
'subscription_explications_alert', \
'space_explications_alert']` }).$promise
'space_explications_alert']` }).$promise;
}],
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
'app.shared.wallet', 'app.shared.coupon_input', 'app.shared.cart']).$promise;
}]
}
})
@ -483,8 +483,8 @@ 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 }]
trainingsPromise: ['Training', function (Training) { return Training.query({ public_page: true }).$promise; }],
translations: [ 'Translations', function (Translations) { return Translations.query(['app.public.trainings_list']).$promise; }]
}
})
.state('app.public.training_show', {
@ -496,8 +496,8 @@ 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 }]
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; }]
}
})
.state('app.logged.trainings_reserve', {
@ -509,12 +509,12 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
explicationAlertPromise: ['Setting', function (Setting) { return Setting.get({ name: 'training_explications_alert' }).$promise }],
plansPromise: ['Plan', function (Plan) { return Plan.query().$promise }],
groupsPromise: ['Group', function (Group) { return Group.query().$promise }],
availabilityTrainingsPromise: ['Availability', '$stateParams', function (Availability, $stateParams) { return Availability.trainings({ trainingId: $stateParams.id }).$promise }],
explicationAlertPromise: ['Setting', function (Setting) { return Setting.get({ name: 'training_explications_alert' }).$promise; }],
plansPromise: ['Plan', function (Plan) { return Plan.query().$promise; }],
groupsPromise: ['Group', function (Group) { return Group.query().$promise; }],
availabilityTrainingsPromise: ['Availability', '$stateParams', function (Availability, $stateParams) { return Availability.trainings({ trainingId: $stateParams.id }).$promise; }],
trainingPromise: ['Training', '$stateParams', function (Training, $stateParams) {
if ($stateParams.id !== 'all') { return Training.get({ id: $stateParams.id }).$promise }
if ($stateParams.id !== 'all') { return Training.get({ id: $stateParams.id }).$promise; }
}],
settingsPromise: ['Setting', function (Setting) {
return Setting.query({
@ -526,12 +526,12 @@ angular.module('application.router', ['ui.router'])
'booking_cancel_delay', \
'subscription_explications_alert', \
'training_explications_alert', \
'training_information_message']` }).$promise
'training_information_message']` }).$promise;
}],
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
'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; }]
}
})
@ -560,12 +560,12 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
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 }],
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) {
return Translations.query(['app.public.plans', 'app.shared.member_select', 'app.shared.stripe', 'app.shared.wallet',
'app.shared.coupon_input']).$promise
'app.shared.coupon_input']).$promise;
}]
}
})
@ -580,10 +580,10 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
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 }]
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; }]
}
})
.state('app.public.events_show', {
@ -595,12 +595,12 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
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 }],
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) {
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
'app.shared.valid_reservation_modal', 'app.shared.wallet', 'app.shared.coupon_input']).$promise;
}]
}
})
@ -615,12 +615,12 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
bookingWindowStart: ['Setting', function (Setting) { return Setting.get({ name: 'booking_window_start' }).$promise }],
bookingWindowEnd: ['Setting', function (Setting) { return Setting.get({ name: 'booking_window_end' }).$promise }],
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 }]
bookingWindowStart: ['Setting', function (Setting) { return Setting.get({ name: 'booking_window_start' }).$promise; }],
bookingWindowEnd: ['Setting', function (Setting) { return Setting.get({ name: 'booking_window_end' }).$promise; }],
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; }]
}
})
@ -635,10 +635,10 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
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 }]
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; }]
}
})
@ -652,10 +652,10 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
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 }]
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; }]
}
})
@ -669,9 +669,9 @@ 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 }]
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; }]
}
})
.state('app.admin.trainings_new', {
@ -683,8 +683,8 @@ 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 }]
machinesPromise: ['Machine', function (Machine) { return Machine.query().$promise; }],
translations: [ 'Translations', function (Translations) { return Translations.query(['app.admin.trainings_new', 'app.shared.trainings']).$promise; }]
}
})
.state('app.admin.trainings_edit', {
@ -696,9 +696,9 @@ 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 }]
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; }]
}
})
// events
@ -711,12 +711,12 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
eventsPromise: ['Event', function (Event) { return Event.query({ page: 1 }).$promise }],
categoriesPromise: ['Category', function (Category) { return Category.query().$promise }],
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 }]
eventsPromise: ['Event', function (Event) { return Event.query({ page: 1 }).$promise; }],
categoriesPromise: ['Category', function (Category) { return Category.query().$promise; }],
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; }]
}
})
.state('app.admin.events_new', {
@ -728,11 +728,11 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
categoriesPromise: ['Category', function (Category) { return Category.query().$promise }],
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 }]
categoriesPromise: ['Category', function (Category) { return Category.query().$promise; }],
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; }]
}
})
.state('app.admin.events_edit', {
@ -744,12 +744,12 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
eventPromise: ['Event', '$stateParams', function (Event, $stateParams) { return Event.get({ id: $stateParams.id }).$promise }],
categoriesPromise: ['Category', function (Category) { return Category.query().$promise }],
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 }]
eventPromise: ['Event', '$stateParams', function (Event, $stateParams) { return Event.get({ id: $stateParams.id }).$promise; }],
categoriesPromise: ['Category', function (Category) { return Category.query().$promise; }],
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; }]
}
})
.state('app.admin.event_reservations', {
@ -761,9 +761,9 @@ 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 }]
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; }]
}
})
@ -777,19 +777,19 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
plans: ['Plan', function (Plan) { return Plan.query().$promise }],
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 }],
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 }],
trainingCreditsPromise: ['Credit', function (Credit) { return Credit.query({ creditable_type: 'Training' }).$promise }],
couponsPromise: ['Coupon', function (Coupon) { return Coupon.query().$promise }],
spacesPromise: ['Space', function (Space) { return Space.query().$promise }],
spacesPricesPromise: ['Price', function (Price) { return Price.query({ priceable_type: 'Space', plan_id: 'null' }).$promise }],
spacesCreditsPromise: ['Credit', function (Credit) { return Credit.query({ creditable_type: 'Space' }).$promise }]
plans: ['Plan', function (Plan) { return Plan.query().$promise; }],
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; }],
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; }],
trainingCreditsPromise: ['Credit', function (Credit) { return Credit.query({ creditable_type: 'Training' }).$promise; }],
couponsPromise: ['Coupon', function (Coupon) { return Coupon.query().$promise; }],
spacesPromise: ['Space', function (Space) { return Space.query().$promise; }],
spacesPricesPromise: ['Price', function (Price) { return Price.query({ priceable_type: 'Space', plan_id: 'null' }).$promise; }],
spacesCreditsPromise: ['Credit', function (Credit) { return Credit.query({ creditable_type: 'Space' }).$promise; }]
}
})
@ -797,9 +797,9 @@ angular.module('application.router', ['ui.router'])
.state('app.admin.plans', {
abstract: true,
resolve: {
prices: ['Pricing', function (Pricing) { return Pricing.query().$promise }],
groups: ['Group', function (Group) { return Group.query().$promise }],
partners: ['User', function (User) { return User.query({ role: 'partner' }).$promise }]
prices: ['Pricing', function (Pricing) { return Pricing.query().$promise; }],
groups: ['Group', function (Group) { return Group.query().$promise; }],
partners: ['User', function (User) { return User.query({ role: 'partner' }).$promise; }]
}
})
.state('app.admin.plans.new', {
@ -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', {
@ -823,11 +823,11 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
spaces: ['Space', function (Space) { return Space.query().$promise }],
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 }]
spaces: ['Space', function (Space) { return Space.query().$promise; }],
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; }]
}
})
@ -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', {
@ -853,8 +853,8 @@ 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 }]
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; }]
}
})
@ -878,14 +878,14 @@ angular.module('application.router', ['ui.router'])
'invoice_code-value', \
'invoice_code-active', \
'invoice_reference', \
'invoice_logo']` }).$promise
'invoice_logo']` }).$promise;
}],
invoices: [ 'Invoice', function (Invoice) {
return Invoice.list({
query: { number: '', customer: '', date: null, order_by: '-reference', page: 1, size: 20 }
}).$promise
}).$promise;
}],
translations: [ 'Translations', function (Translations) { return Translations.query('app.admin.invoices').$promise }]
translations: [ 'Translations', function (Translations) { return Translations.query('app.admin.invoices').$promise; }]
}
})
@ -911,12 +911,12 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
membersPromise: ['Member', function (Member) { return Member.list({ query: { search: '', order_by: 'id', page: 1, size: 20 } }).$promise }],
adminsPromise: ['Admin', function (Admin) { return Admin.query().$promise }],
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 }]
membersPromise: ['Member', function (Member) { return Member.list({ query: { search: '', order_by: 'id', page: 1, size: 20 } }).$promise; }],
adminsPromise: ['Admin', function (Admin) { return Admin.query().$promise; }],
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; }]
}
})
.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', {
@ -940,12 +940,12 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
memberPromise: ['Member', '$stateParams', function (Member, $stateParams) { return Member.get({ id: $stateParams.id }).$promise }],
activeProviderPromise: ['AuthProvider', function (AuthProvider) { return AuthProvider.active().$promise }],
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 }]
memberPromise: ['Member', '$stateParams', function (Member, $stateParams) { return Member.get({ id: $stateParams.id }).$promise; }],
activeProviderPromise: ['AuthProvider', function (AuthProvider) { return AuthProvider.active().$promise; }],
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; }]
}
})
.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; }]
}
})
@ -971,9 +971,9 @@ 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 }]
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; }]
}
})
.state('app.admin.authentication_edit', {
@ -985,9 +985,9 @@ 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 }]
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; }]
}
})
@ -1001,9 +1001,9 @@ 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 }]
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; }]
}
})
.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; }]
}
})
@ -1057,13 +1057,13 @@ angular.module('application.router', ['ui.router'])
'visibility_yearly', \
'visibility_others', \
'display_name_enable', \
'machines_sort_by']` }).$promise
'machines_sort_by']` }).$promise;
}],
cguFile: ['CustomAsset', function (CustomAsset) { return CustomAsset.get({ name: 'cgu-file' }).$promise }],
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 }]
cguFile: ['CustomAsset', function (CustomAsset) { return CustomAsset.get({ name: 'cgu-file' }).$promise; }],
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; }]
}
})
@ -1077,10 +1077,10 @@ 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 }]
clientsPromise: ['OpenAPIClient', function (OpenAPIClient) { return OpenAPIClient.query().$promise; }],
translations: [ 'Translations', function (Translations) { return Translations.query('app.admin.open_api_clients').$promise; }]
}
})
});
}
])
]);

View File

@ -9,13 +9,13 @@
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('_t', ['$filter', $filter =>
function (key, interpolation, options) {
if (interpolation == null) { interpolation = undefined }
if (options == null) { options = undefined }
return $filter('translate')(key, interpolation, options)
if (interpolation == null) { interpolation = undefined; }
if (options == null) { options = undefined; }
return $filter('translate')(key, interpolation, options);
}
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Abuse', ['$resource', $resource =>
$resource('/api/abuses/:id',
@ -19,4 +19,4 @@ Application.Services.factory('Abuse', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Admin', ['$resource', $resource =>
$resource('/api/admins/:id',
@ -19,4 +19,4 @@ Application.Services.factory('Admin', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('AgeRange', ['$resource', $resource =>
$resource('/api/age_ranges/:id',
@ -19,4 +19,4 @@ Application.Services.factory('AgeRange', ['$resource', $resource =>
}
)
])
]);

View File

@ -9,21 +9,21 @@
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('AuthService', ['Session', function (Session) {
return {
isAuthenticated () {
return (Session.currentUser != null) && (Session.currentUser.id != null)
return (Session.currentUser != null) && (Session.currentUser.id != null);
},
isAuthorized (authorizedRoles) {
if (!angular.isArray(authorizedRoles)) {
authorizedRoles = [authorizedRoles]
authorizedRoles = [authorizedRoles];
}
return this.isAuthenticated() && (authorizedRoles.indexOf(Session.currentUser.role) !== -1)
return this.isAuthenticated() && (authorizedRoles.indexOf(Session.currentUser.role) !== -1);
}
}
};
}
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('AuthProvider', ['$resource', $resource =>
$resource('/api/auth_providers/:id',
@ -31,4 +31,4 @@ Application.Services.factory('AuthProvider', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Availability', ['$resource', $resource =>
$resource('/api/availabilities/:id',
@ -46,4 +46,4 @@ Application.Services.factory('Availability', ['$resource', $resource =>
}
)
])
]);

View File

@ -9,16 +9,16 @@
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('CalendarConfig', [() =>
function (options) {
// The calendar is divided in slots of 1 hour
if (options == null) { options = {} }
const BASE_SLOT = '01:00:00'
if (options == null) { options = {}; }
const BASE_SLOT = '01:00:00';
// The calendar will be initialized positioned under 9:00 AM
const DEFAULT_CALENDAR_POSITION = '09:00:00'
const DEFAULT_CALENDAR_POSITION = '09:00:00';
const defaultOptions = {
timezone: Fablab.timezone,
@ -48,9 +48,9 @@ Application.Services.factory('CalendarConfig', [() =>
allDaySlot: false,
defaultView: 'agendaWeek',
editable: false
}
};
return Object.assign({}, defaultOptions, options)
return Object.assign({}, defaultOptions, options);
}
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Category', ['$resource', $resource =>
$resource('/api/categories/:id',
@ -19,4 +19,4 @@ Application.Services.factory('Category', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Component', ['$resource', $resource =>
$resource('/api/components/:id',
@ -19,4 +19,4 @@ Application.Services.factory('Component', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Coupon', ['$resource', $resource =>
$resource('/api/coupons/:id',
@ -27,4 +27,4 @@ Application.Services.factory('Coupon', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Credit', ['$resource', $resource =>
$resource('/api/credits/:id',
@ -19,4 +19,4 @@ Application.Services.factory('Credit', ['$resource', $resource =>
}
)
])
]);

View File

@ -4,19 +4,19 @@
*/
// TODO: This file was created by bulk-decaffeinate.
// Fix any style issues and re-enable lint.
'use strict'
'use strict';
Application.Services.service('CSRF', ['$cookies',
$cookies =>
({
setMetaTags () {
if (angular.element('meta[name="csrf-param"]').length === 0) {
angular.element('head').append('<meta name="csrf-param" content="authenticity_token">')
angular.element('head').append(`<meta name=\"csrf-token\" content=\"${$cookies['XSRF-TOKEN']}\">`)
angular.element('head').append('<meta name="csrf-param" content="authenticity_token">');
angular.element('head').append(`<meta name=\"csrf-token\" content=\"${$cookies['XSRF-TOKEN']}\">`);
} else {
angular.element('meta[name="csrf-token"]').replaceWith(`<meta name=\"csrf-token\" content=\"${$cookies['XSRF-TOKEN']}\">`)
angular.element('meta[name="csrf-token"]').replaceWith(`<meta name=\"csrf-token\" content=\"${$cookies['XSRF-TOKEN']}\">`);
}
}
})
])
]);

View File

@ -8,10 +8,10 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('CustomAsset', ['$resource', $resource =>
$resource('/api/custom_assets/:name',
{ name: '@name' })
])
]);

View File

@ -101,21 +101,21 @@ Application.Services.service('Diacritics', [
{ 'base': 'x', 'letters': '\u0078\u24E7\uFF58\u1E8B\u1E8D' },
{ 'base': 'y', 'letters': '\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF' },
{ 'base': 'z', 'letters': '\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763' }
]
];
var diacriticsMap = {}
var diacriticsMap = {};
for (var i = 0; i < defaultDiacriticsRemovalap.length; i++) {
var letters = defaultDiacriticsRemovalap[i].letters.split('')
var letters = defaultDiacriticsRemovalap[i].letters.split('');
for (var j = 0; j < letters.length; j++) {
diacriticsMap[letters[j]] = defaultDiacriticsRemovalap[i].base
diacriticsMap[letters[j]] = defaultDiacriticsRemovalap[i].base;
}
}
return str.replace(/[^\u0000-\u007E]/g, function (a) {
return diacriticsMap[a] || a
})
return diacriticsMap[a] || a;
});
}
}
};
}
])
]);

View File

@ -9,7 +9,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('dialogs', ['$uibModal', function ($uibModal) {
return ({
@ -22,27 +22,27 @@ Application.Services.factory('dialogs', ['$uibModal', function ($uibModal) {
return {
title: 'Titre de confirmation',
msg: 'Message de confirmation'
}
};
}
},
controller: ['$scope', '$uibModalInstance', '$state', 'object', function ($scope, $uibModalInstance, $state, object) {
$scope.object = object
$scope.ok = function (info) { $uibModalInstance.close(info) }
$scope.cancel = function () { $uibModalInstance.dismiss('cancel') }
$scope.object = object;
$scope.ok = function (info) { $uibModalInstance.close(info); };
$scope.cancel = function () { $uibModalInstance.dismiss('cancel'); };
}]
}
if (angular.isObject(options)) { angular.extend(defaultOpts, options) }
};
if (angular.isObject(options)) { angular.extend(defaultOpts, options); }
return $uibModal.open(defaultOpts)
.result['finally'](null).then(function (info) {
if (angular.isFunction(success)) {
return success(info)
return success(info);
}
}
, function (reason) {
if (angular.isFunction(error)) {
return error(reason)
return error(reason);
}
})
});
}
})
}])
});
}]);

View File

@ -1,3 +1,3 @@
Application.Services.service('es', function (esFactory) {
return esFactory({ host: window.location.origin })
})
return esFactory({ host: window.location.origin });
});

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Event', ['$resource', $resource =>
$resource('/api/events/:id',
@ -25,4 +25,4 @@ Application.Services.factory('Event', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('EventTheme', ['$resource', $resource =>
$resource('/api/event_themes/:id',
@ -19,4 +19,4 @@ Application.Services.factory('EventTheme', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,13 +8,13 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Export', ['$http', $http =>
({
status (query) {
return $http.post('/api/exports/status', query)
return $http.post('/api/exports/status', query);
}
})
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Group', ['$resource', $resource =>
$resource('/api/groups/:id',
@ -19,4 +19,4 @@ Application.Services.factory('Group', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,13 +8,13 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('helpers', [() =>
({
getAmountToPay (price, walletAmount) {
if (walletAmount > price) { return 0 } else { return price - walletAmount }
if (walletAmount > price) { return 0; } else { return price - walletAmount; }
}
})
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Invoice', ['$resource', $resource =>
$resource('/api/invoices/:id',
@ -24,4 +24,4 @@ Application.Services.factory('Invoice', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Licence', ['$resource', $resource =>
$resource('/api/licences/:id',
@ -19,4 +19,4 @@ Application.Services.factory('Licence', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Machine', ['$resource', $resource =>
$resource('/api/machines/:id',
@ -19,4 +19,4 @@ Application.Services.factory('Machine', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Member', ['$resource', $resource =>
$resource('/api/members/:id',
@ -44,4 +44,4 @@ Application.Services.factory('Member', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Notification', ['$resource', $resource =>
$resource('/api/notifications/:id',
@ -30,4 +30,4 @@ Application.Services.factory('Notification', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('OpenAPIClient', ['$resource', $resource =>
$resource('/api/open_api_clients/:id',
@ -23,4 +23,4 @@ Application.Services.factory('OpenAPIClient', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('OpenlabProject', ['$resource', $resource =>
$resource('/api/openlab_projects/:id',
@ -20,4 +20,4 @@ Application.Services.factory('OpenlabProject', ['$resource', $resource =>
}
)
])
]);

View File

@ -9,62 +9,62 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('paginationService', [function () {
const helpers = {}
const helpers = {};
helpers.pageCount = (totalCount, perPage) => Math.ceil(totalCount / perPage)
helpers.pageCount = (totalCount, perPage) => Math.ceil(totalCount / perPage);
helpers.hasNextPage = function (currentPage, totalCount, perPage) {
const _pageCount = helpers.pageCount(totalCount, perPage)
return (_pageCount !== currentPage) && (_pageCount !== 0)
}
const _pageCount = helpers.pageCount(totalCount, perPage);
return (_pageCount !== currentPage) && (_pageCount !== 0);
};
const Instance = function (resourceService, currentPage, perPage, totalCount, defaultQueryParams, callback, functionName) {
this.resourceService = resourceService
this.currentPage = currentPage
this.perPage = perPage
this.totalCount = totalCount
this.defaultQueryParams = defaultQueryParams
this.callback = callback
this.functionName = functionName || 'query'
this.loading = false
this.resourceService = resourceService;
this.currentPage = currentPage;
this.perPage = perPage;
this.totalCount = totalCount;
this.defaultQueryParams = defaultQueryParams;
this.callback = callback;
this.functionName = functionName || 'query';
this.loading = false;
this.pageCount = function () {
return helpers.pageCount(this.totalCount, this.perPage)
}
return helpers.pageCount(this.totalCount, this.perPage);
};
this.hasNextPage = function () {
return helpers.hasNextPage(this.currentPage, this.totalCount, this.perPage)
}
return helpers.hasNextPage(this.currentPage, this.totalCount, this.perPage);
};
this.loadMore = function (queryParams) {
let k, v
this.currentPage += 1
this.loading = true
let k, v;
this.currentPage += 1;
this.loading = true;
const _queryParams = { page: this.currentPage, per_page: this.perPage }
const _queryParams = { page: this.currentPage, per_page: this.perPage };
if (queryParams) {
for (k in queryParams) {
v = queryParams[k]
_queryParams[k] = v
v = queryParams[k];
_queryParams[k] = v;
}
}
for (k in this.defaultQueryParams) {
v = this.defaultQueryParams[k]
_queryParams[k] = v
v = this.defaultQueryParams[k];
_queryParams[k] = v;
}
return this.resourceService[this.functionName](_queryParams, dataPromise => {
this.callback(dataPromise)
return this.loading = false
})
}
}
this.callback(dataPromise);
return this.loading = false;
});
};
};
return { Instance }
return { Instance };
}
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Plan', ['$resource', $resource =>
$resource('/api/plans/:id',
@ -19,4 +19,4 @@ Application.Services.factory('Plan', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Price', ['$resource', $resource =>
$resource('/api/prices/:id',
@ -27,4 +27,4 @@ Application.Services.factory('Price', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('PriceCategory', ['$resource', $resource =>
$resource('/api/price_categories/:id',
@ -19,4 +19,4 @@ Application.Services.factory('PriceCategory', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Pricing', ['$resource', $resource =>
$resource('/api/pricing',
@ -19,4 +19,4 @@ Application.Services.factory('Pricing', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Project', ['$resource', $resource =>
$resource('/api/projects/:id',
@ -31,4 +31,4 @@ Application.Services.factory('Project', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Reservation', ['$resource', $resource =>
$resource('/api/reservations/:id',
@ -19,4 +19,4 @@ Application.Services.factory('Reservation', ['$resource', $resource =>
}
)
])
]);

View File

@ -9,17 +9,17 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.service('Session', [ function () {
this.create = function (user) {
return this.currentUser = user
}
return this.currentUser = user;
};
this.destroy = function () {
return this.currentUser = null
}
return this.currentUser = null;
};
return this
return this;
}
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Setting', ['$resource', $resource =>
$resource('/api/settings/:name',
@ -22,4 +22,4 @@ Application.Services.factory('Setting', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Slot', ['$resource', $resource =>
$resource('/api/slots/:id',
@ -23,4 +23,4 @@ Application.Services.factory('Slot', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,8 +8,8 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
// list the social networks supported in the user's profiles
Application.Services.factory('SocialNetworks', [ () => ['facebook', 'twitter', 'google_plus', 'viadeo', 'linkedin', 'instagram', 'youtube', 'vimeo', 'dailymotion', 'github', 'echosciences', 'website', 'pinterest', 'lastfm', 'flickr']
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Space', ['$resource', $resource =>
$resource('/api/spaces/:id',
@ -19,4 +19,4 @@ Application.Services.factory('Space', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Statistics', ['$resource', $resource => $resource('/api/statistics')
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Subscription', ['$resource', $resource =>
$resource('/api/subscriptions/:id',
@ -19,4 +19,4 @@ Application.Services.factory('Subscription', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Tag', ['$resource', $resource =>
$resource('/api/tags/:id',
@ -19,4 +19,4 @@ Application.Services.factory('Tag', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Theme', ['$resource', $resource =>
$resource('/api/themes/:id',
@ -19,4 +19,4 @@ Application.Services.factory('Theme', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Training', ['$resource', $resource =>
$resource('/api/trainings/:id',
@ -23,4 +23,4 @@ Application.Services.factory('Training', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('TrainingsPricing', ['$resource', $resource =>
$resource('/api/trainings_pricings/:id',
@ -19,4 +19,4 @@ Application.Services.factory('TrainingsPricing', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,18 +8,18 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Translations', ['$translatePartialLoader', '$translate', ($translatePartialLoader, $translate) =>
({
query (stateName) {
if (angular.isArray((stateName))) {
angular.forEach(stateName, state => $translatePartialLoader.addPart(state))
angular.forEach(stateName, state => $translatePartialLoader.addPart(state));
} else {
$translatePartialLoader.addPart(stateName)
$translatePartialLoader.addPart(stateName);
}
return $translate.refresh()
return $translate.refresh();
}
})
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Twitter', ['$resource', $resource => $resource('/api/feeds/twitter_timelines')
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('User', ['$resource', $resource =>
$resource('/api/users',
@ -19,4 +19,4 @@ Application.Services.factory('User', ['$resource', $resource =>
}
)
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Version', ['$resource', $resource => $resource('/api/version')
])
]);

View File

@ -8,7 +8,7 @@
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
'use strict'
'use strict';
Application.Services.factory('Wallet', ['$resource', $resource =>
$resource('/api/wallet',
@ -31,4 +31,4 @@ Application.Services.factory('Wallet', ['$resource', $resource =>
}
)
])
]);