1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-02-26 20:54:21 +01:00

Merge branch 'help' into dev

This commit is contained in:
Sylvain 2020-03-11 10:27:05 +01:00
commit 7292fb348b
32 changed files with 154 additions and 317 deletions

View File

@ -1,6 +1,7 @@
# Changelog Fab-manager
- Secure the session cookie
- Improved contextual help with a modal dialog
- Updated translations
- Refactored translations to help merging Crowdin PR

View File

@ -350,8 +350,6 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('calendar') < 0) {
uitour.start();
}
// start this tour when an user press F1 - this is contextual help
window.addEventListener('keydown', handleF1);
}
/* PRIVATE SCOPE */
@ -359,12 +357,7 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
/**
* Kind of constructor: these actions will be realized first when the controller is loaded
*/
const initialize = function () {
// listen the $destroy event of the controller to remove the F1 key binding
$scope.$on('$destroy', function () {
window.removeEventListener('keydown', handleF1);
});
};
const initialize = function () {};
/**
* Return an enumerable meaninful string for the gender of the provider user
@ -524,18 +517,6 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
$scope.availabilityDom = null;
};
/**
* Callback used to trigger the feature tour when the user press the F1 key.
* @param e {KeyboardEvent}
*/
const handleF1 = function (e) {
if (e.key === 'F1') {
e.preventDefault();
const tour = uiTourService.getTourByName('calendar');
if (tour) { tour.start(); }
}
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize();
}

View File

@ -466,8 +466,6 @@ Application.Controllers.controller('AdminEventsController', ['$scope', '$state',
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('events') < 0) {
uitour.start();
}
// start this tour when an user press F1 - this is contextual help
window.addEventListener('keydown', handleF1);
}
/* PRIVATE SCOPE */
@ -477,23 +475,6 @@ Application.Controllers.controller('AdminEventsController', ['$scope', '$state',
*/
const initialize = function () {
paginationCheck(eventsPromise, $scope.events);
// listen the $destroy event of the controller to remove the F1 key binding
$scope.$on('$destroy', function () {
window.removeEventListener('keydown', handleF1);
});
};
/**
* Callback used to trigger the feature tour when the user press the F1 key.
* @param e {KeyboardEvent}
*/
const handleF1 = function (e) {
if (e.key === 'F1') {
e.preventDefault();
const tour = uiTourService.getTourByName('events');
if (tour) { tour.start(); }
}
};
/**

View File

@ -675,8 +675,6 @@ Application.Controllers.controller('InvoicesController', ['$scope', '$state', 'I
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('invoices') < 0) {
uitour.start();
}
// start this tour when an user press F1 - this is contextual help
window.addEventListener('keydown', handleF1);
}
/* PRIVATE SCOPE */
@ -718,11 +716,6 @@ Application.Controllers.controller('InvoicesController', ['$scope', '$state', 'I
);
}
});
// listen the $destroy event of the controller to remove the F1 key binding
$scope.$on('$destroy', function () {
window.removeEventListener('keydown', handleF1);
});
};
/**
@ -790,18 +783,6 @@ Application.Controllers.controller('InvoicesController', ['$scope', '$state', 'I
});
};
/**
* Callback used to trigger the feature tour when the user press the F1 key.
* @param e {KeyboardEvent}
*/
const handleF1 = function (e) {
if (e.key === 'F1') {
e.preventDefault();
const tour = uiTourService.getTourByName('invoices');
if (tour) { tour.start(); }
}
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize();
}

View File

@ -431,8 +431,6 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce',
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('members') < 0) {
uitour.start();
}
// start this tour when an user press F1 - this is contextual help
window.addEventListener('keydown', handleF1);
}
/* PRIVATE SCOPE */
@ -444,9 +442,6 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce',
if (!membersPromise[0] || (membersPromise[0].maxMembers <= $scope.members.length)) {
return $scope.member.noMore = true;
}
$scope.$on('$destroy', function () {
window.removeEventListener('keydown', handleF1);
});
};
/**
@ -499,18 +494,6 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce',
});
};
/**
* Callback used to trigger the feature tour when the user press the F1 key.
* @param e {KeyboardEvent}
*/
const handleF1 = function (e) {
if (e.key === 'F1') {
e.preventDefault();
const tour = uiTourService.getTourByName('members');
if (tour) { tour.start(); }
}
};
// !!! MUST BE CALLED AT THE END of the controller
return initialize();
}

View File

@ -137,8 +137,6 @@ Application.Controllers.controller('OpenAPIClientsController', ['$scope', 'clien
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('open-api') < 0) {
uitour.start();
}
// start this tour when an user press F1 - this is contextual help
window.addEventListener('keydown', handleF1);
};
/* PRIVATE SCOPE */
@ -146,24 +144,7 @@ Application.Controllers.controller('OpenAPIClientsController', ['$scope', 'clien
/**
* Kind of constructor: these actions will be realized first when the controller is loaded
*/
const initialize = function () {
// listen the $destroy event of the controller to remove the F1 key binding
$scope.$on('$destroy', function () {
window.removeEventListener('keydown', handleF1);
});
};
/**
* Callback used to trigger the feature tour when the user press the F1 key.
* @param e {KeyboardEvent}
*/
const handleF1 = function (e) {
if (e.key === 'F1') {
e.preventDefault();
const tour = uiTourService.getTourByName('open-api');
if (tour) { tour.start(); }
}
};
const initialize = function () {};
// !!! MUST BE CALLED AT THE END of the controller
return initialize();

View File

@ -714,8 +714,6 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('pricing') < 0) {
uitour.start();
}
// start this tour when an user press F1 - this is contextual help
window.addEventListener('keydown', handleF1);
}
/* PRIVATE SCOPE */
@ -726,11 +724,6 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
const initialize = function () {
$scope.trainingCreditsGroups = groupCreditsByPlan($scope.trainingCredits);
// listen the $destroy event of the controller to remove the F1 key binding
$scope.$on('$destroy', function () {
window.removeEventListener('keydown', handleF1);
});
// adds empty array for plan which hasn't any credits yet
return (function () {
const result = [];
@ -745,18 +738,6 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
})();
};
/**
* Callback used to trigger the feature tour when the user press the F1 key.
* @param e {KeyboardEvent}
*/
const handleF1 = function (e) {
if (e.key === 'F1') {
e.preventDefault();
const tour = uiTourService.getTourByName('pricing');
if (tour) { tour.start(); }
}
};
/**
* Retrieve an item index by its ID from the given array of objects
* @param items {Array<{id:number}>}

View File

@ -26,7 +26,7 @@ Application.Controllers.controller('ProjectElementsController', ['$scope', '$sta
/**
* Saves a new component / Update an existing material to the server (form validation callback)
* @param data {Object} component name
* @param [data] {number} component id, in case of update
* @param [id] {number} component id, in case of update
*/
$scope.saveComponent = function (data, id) {
if (id != null) {
@ -49,9 +49,8 @@ Application.Controllers.controller('ProjectElementsController', ['$scope', '$sta
* Creates a new empty entry in the $scope.components array
*/
$scope.addComponent = function () {
$scope.inserted =
{ name: '' };
return $scope.components.push($scope.inserted);
$scope.inserted = { name: '' };
$scope.components.push($scope.inserted);
};
/**
@ -93,9 +92,8 @@ Application.Controllers.controller('ProjectElementsController', ['$scope', '$sta
* Creates a new empty entry in the $scope.themes array
*/
$scope.addTheme = function () {
$scope.inserted =
{ name: '' };
return $scope.themes.push($scope.inserted);
$scope.inserted = { name: '' };
$scope.themes.push($scope.inserted);
};
/**
@ -105,16 +103,16 @@ Application.Controllers.controller('ProjectElementsController', ['$scope', '$sta
*/
$scope.cancelTheme = function (rowform, index) {
if ($scope.themes[index].id != null) {
return rowform.$cancel();
rowform.$cancel();
} else {
return $scope.themes.splice(index, 1);
$scope.themes.splice(index, 1);
}
};
/**
* Saves a new licence / Update an existing licence to the server (form validation callback)
* @param data {Object} licence name and description
* @param [data] {number} licence id, in case of update
* @param [id] {number} licence id, in case of update
*/
$scope.saveLicence = function (data, id) {
if (id != null) {
@ -203,8 +201,6 @@ Application.Controllers.controller('ProjectElementsController', ['$scope', '$sta
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('project-elements') < 0) {
uitour.start();
}
// start this tour when an user press F1 - this is contextual help
window.addEventListener('keydown', handleF1);
};
/* PRIVATE SCOPE */
@ -212,24 +208,7 @@ Application.Controllers.controller('ProjectElementsController', ['$scope', '$sta
/**
* Kind of constructor: these actions will be realized first when the controller is loaded
*/
const initialize = function () {
// listen the $destroy event of the controller to remove the F1 key binding
$scope.$on('$destroy', function () {
window.removeEventListener('keydown', handleF1);
});
};
/**
* Callback used to trigger the feature tour when the user press the F1 key.
* @param e {KeyboardEvent}
*/
const handleF1 = function (e) {
if (e.key === 'F1') {
e.preventDefault();
const tour = uiTourService.getTourByName('project-elements');
if (tour) { tour.start(); }
}
};
const initialize = function () {};
// !!! MUST BE CALLED AT THE END of the controller
return initialize();

View File

@ -467,8 +467,6 @@ Application.Controllers.controller('SettingsController', ['$scope', '$rootScope'
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('settings') < 0) {
uitour.start();
}
// start this tour when an user press F1 - this is contextual help
window.addEventListener('keydown', handleF1);
}
/* PRIVATE SCOPE */
@ -521,23 +519,8 @@ Application.Controllers.controller('SettingsController', ['$scope', '$rootScope'
$scope.$watch('advancedSettings.open', function (newValue) {
if (newValue) $scope.codeMirrorEditor.refresh();
})
// listen the $destroy event of the controller to remove the F1 key binding
$scope.$on('$destroy', function () {
window.removeEventListener('keydown', handleF1);
});
};
/**
* Callback used to trigger the feature tour when the user press the F1 key.
* @param e {KeyboardEvent}
*/
const handleF1 = function (e) {
if (e.key === 'F1') {
e.preventDefault();
const tour = uiTourService.getTourByName('settings');
if (tour) { tour.start(); }
}
};
// init the controller (call at the end !)
return initialize();
}

View File

@ -391,8 +391,6 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('statistics') < 0) {
uitour.start();
}
// start this tour when an user press F1 - this is contextual help
window.addEventListener('keydown', handleF1);
}
/* PRIVATE SCOPE */
@ -408,22 +406,6 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
return $scope.preventRefresh = true;
}
});
// listen the $destroy event of the controller to remove the F1 key binding
$scope.$on('$destroy', function () {
window.removeEventListener('keydown', handleF1);
});
};
/**
* Callback used to trigger the feature tour when the user press the F1 key.
* @param e {KeyboardEvent}
*/
const handleF1 = function (e) {
if (e.key === 'F1') {
e.preventDefault();
const tour = uiTourService.getTourByName('statistics');
if (tour) { tour.start(); }
}
};
/**

View File

@ -401,8 +401,6 @@ Application.Controllers.controller('TrainingsAdminController', ['$scope', '$stat
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('trainings') < 0) {
uitour.start();
}
// start this tour when an user press F1 - this is contextual help
window.addEventListener('keydown', handleF1);
}
@ -411,24 +409,8 @@ Application.Controllers.controller('TrainingsAdminController', ['$scope', '$stat
/**
* Kind of constructor: these actions will be realized first when the controller is loaded
*/
const initialize = function () {
// listen the $destroy event of the controller to remove the F1 key binding
$scope.$on('$destroy', function () {
window.removeEventListener('keydown', handleF1);
});
};
const initialize = function () {};
/**
* Callback used to trigger the feature tour when the user press the F1 key.
* @param e {KeyboardEvent}
*/
const handleF1 = function (e) {
if (e.key === 'F1') {
e.preventDefault();
const tour = uiTourService.getTourByName('trainings');
if (tour) { tour.start(); }
}
};
/**
* Group the trainings availabilities by trainings and by dates and return the resulting tree

View File

@ -12,8 +12,8 @@
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
Application.Controllers.controller('ApplicationController', ['$rootScope', '$scope', '$window', '$locale', '$timeout', 'Session', 'AuthService', 'Auth', '$uibModal', '$state', 'growl', 'Notification', '$interval', 'Setting', '_t', 'Version',
function ($rootScope, $scope, $window, $locale, $timeout, Session, AuthService, Auth, $uibModal, $state, growl, Notification, $interval, Setting, _t, Version) {
Application.Controllers.controller('ApplicationController', ['$rootScope', '$scope', '$window', '$locale', '$timeout', 'Session', 'AuthService', 'Auth', '$uibModal', '$state', 'growl', 'Notification', '$interval', 'Setting', '_t', 'Version', 'Help',
function ($rootScope, $scope, $window, $locale, $timeout, Session, AuthService, Auth, $uibModal, $state, growl, Notification, $interval, Setting, _t, Version, Help) {
/* PRIVATE STATIC CONSTANTS */
// User's notifications will get refreshed every 30s
@ -346,22 +346,7 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco
$rootScope.login = $scope.login;
// handle F1 key to trigger help
window.addEventListener('keydown', function(e) {
if (e.key === 'F1') {
if ($rootScope.currentUser.role !== 'admin') return;
e.preventDefault();
// we wait a little bit and then, check if a tour has started (by checking for a tour popover).
// if not, we consider that we are on a page that does not provides a tour so we fallback to the default behavior
// -> opening the user's manual
setTimeout(function() {
const tourPopover = document.querySelector('.ui-tour-popup');
if (!tourPopover || (tourPopover.offsetTop === 0 && tourPopover.offsetTop === 0)) {
window.open('https://github.com/sleede/fab-manager/raw/master/doc/fr/guide_utilisation_fab_manager_v4.3.pdf', '_blank');
}
}, 300);
}
});
window.addEventListener('keydown', Help);
};
/**

View File

@ -1,7 +1,7 @@
'use strict';
Application.Controllers.controller('HomeController', ['$scope', '$stateParams', 'settingsPromise', 'Member', 'uiTourService', '_t',
function ($scope, $stateParams, settingsPromise, Member, uiTourService, _t) {
Application.Controllers.controller('HomeController', ['$scope', '$stateParams', 'settingsPromise', 'Member', 'uiTourService', '_t', 'Help',
function ($scope, $stateParams, settingsPromise, Member, uiTourService, _t, Help) {
/* PUBLIC SCOPE */
// Home page HTML content
@ -41,10 +41,6 @@ Application.Controllers.controller('HomeController', ['$scope', '$stateParams',
// We set the home page content, with the directives replacing the placeholders
$scope.homeContent = insertDirectives(settingsPromise.home_content);
// listen the $destroy event of the controller to remove the F1 key binding
$scope.$on('$destroy', function () {
window.removeEventListener('keydown', handleF1);
});
// for admins, setup the tour on login
$scope.$watch('currentUser', function (newValue, oldValue) {
@ -305,20 +301,6 @@ Application.Controllers.controller('HomeController', ['$scope', '$stateParams',
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('welcome') < 0) {
uitour.start();
}
// start this tour when an user press F1 - this is contextual help
window.addEventListener('keydown', handleF1);
};
/**
* Callback used to trigger the feature tour when the user press the F1 key.
* @param e {KeyboardEvent}
*/
const handleF1 = function (e) {
if (e.key === 'F1') {
e.preventDefault();
const tour = uiTourService.getTourByName('welcome');
if (tour) { tour.start(); }
}
};
// !!! MUST BE CALLED AT THE END of the controller

View File

@ -262,8 +262,6 @@ Application.Controllers.controller('MachinesController', ['$scope', '$state', '_
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('machines') < 0) {
uitour.start();
}
// start this tour when an user press F1 - this is contextual help
window.addEventListener('keydown', handleF1);
}
}
@ -272,24 +270,7 @@ Application.Controllers.controller('MachinesController', ['$scope', '$state', '_
/**
* Kind of constructor: these actions will be realized first when the controller is loaded
*/
const initialize = function () {
// listen the $destroy event of the controller to remove the F1 key binding
$scope.$on('$destroy', function () {
window.removeEventListener('keydown', handleF1);
});
}
/**
* Callback used to trigger the feature tour when the user press the F1 key.
* @param e {KeyboardEvent}
*/
const handleF1 = function (e) {
if (e.key === 'F1') {
e.preventDefault();
const tour = uiTourService.getTourByName('machines');
if (tour) { tour.start(); }
}
};
const initialize = function () {}
// !!! MUST BE CALLED AT THE END of the controller
return initialize();

View File

@ -174,8 +174,6 @@ Application.Controllers.controller('SpacesController', ['$scope', '$state', 'spa
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('spaces') < 0) {
uitour.start();
}
// start this tour when an user press F1 - this is contextual help
window.addEventListener('keydown', handleF1);
}
}
@ -184,24 +182,7 @@ Application.Controllers.controller('SpacesController', ['$scope', '$state', 'spa
/**
* Kind of constructor: these actions will be realized first when the controller is loaded
*/
const initialize = function () {
// listen the $destroy event of the controller to remove the F1 key binding
$scope.$on('$destroy', function () {
window.removeEventListener('keydown', handleF1);
});
}
/**
* Callback used to trigger the feature tour when the user press the F1 key.
* @param e {KeyboardEvent}
*/
const handleF1 = function (e) {
if (e.key === 'F1') {
e.preventDefault();
const tour = uiTourService.getTourByName('spaces');
if (tour) { tour.start(); }
}
};
const initialize = function () {}
// !!! MUST BE CALLED AT THE END of the controller
return initialize();

View File

@ -0,0 +1,58 @@
'use strict';
Application.Services.factory('Help', ['$rootScope', '$uibModal', '$state', function ($rootScope, $uibModal, $state) {
const TOURS = {
'app.public.home': 'welcome',
'app.public.machines_list': 'machines',
'app.public.spaces_list': 'spaces',
'app.admin.trainings': 'trainings',
'app.admin.calendar': 'calendar',
'app.admin.members': 'members',
'app.admin.invoices': 'invoices',
'app.admin.pricing': 'pricing',
'app.admin.events': 'events',
'app.admin.project_elements': 'project-elements',
'app.admin.statistics': 'statistics',
'app.admin.settings': 'settings',
'app.admin.open_api_clients': 'open-api'
};
return function (e) {
if (!$rootScope.currentUser || $rootScope.currentUser.role !== 'admin') return;
if (e.key === 'F1') {
e.preventDefault();
// retrieve the tour name, based on the current location
const tourName = TOURS[$state.current.name];
// if no tour, just open the guide
if (tourName === undefined) {
return window.open('https://github.com/sleede/fab-manager/raw/master/doc/fr/guide_utilisation_fab_manager_v4.3.pdf', '_blank');
}
$uibModal.open({
animation: true,
templateUrl: '<%= asset_path "shared/help_modal.html" %>',
resolve: {
tourName: function () { return tourName; }
},
controller: ['$scope', '$uibModalInstance', 'uiTourService', 'tourName', function ($scope, $uibModalInstance, uiTourService, tourName) {
// start the tour and hide the modal
$scope.onTour = function () {
const tour = uiTourService.getTourByName(tourName);
if (tour) { tour.start(); }
$uibModalInstance.close('tour');
};
// open the user's guide and hide the modal
$scope.onGuide = function () {
$uibModalInstance.close('guide');
};
}]
});
}
};
}]);

View File

@ -44,7 +44,7 @@
<b class="text-info" id="agepicker-from-info">{{agePicker.start}}</b>
<span translate>{{ 'app.admin.statistics.to_age' }}</span>
<b class="text-info" id="agepicker-to-info">{{agePicker.end}}</b>
<span translate>{{ 'app.admin.statistics._years_old' }}</span>
<span translate>{{ 'app.admin.statistics.years_old' }}</span>
</span>
<span class="text-gray" ng-show="!agePicker.start && !agePicker.end" translate>
{{ 'app.admin.statistics.age_filter' }}

View File

@ -0,0 +1,20 @@
<div class="modal-header">
<img ng-src="{{logoBlack.custom_asset_file_attributes.attachment_url}}" alt="{{logo.custom_asset_file_attributes.attachment}}" class="modal-logo"/>
<h1>
<i class="fa fa-question-circle" aria-hidden="true"></i>
<span translate>{{ 'app.shared.help.title' }}</span>
</h1>
</div>
<div class="modal-body">
<p translate>{{ 'app.shared.help.what_to_do' }}</p>
<div class="row text-center">
<button class="btn btn-default" ng-click="onTour()" translate>{{ 'app.shared.help.tour' }}</button>
</div>
<div class="row text-center m-t-lg m-b-md">
<a class="btn btn-default"
ng-click="onGuide()"
href="https://github.com/sleede/fab-manager/raw/master/doc/fr/guide_utilisation_fab_manager_v4.3.pdf"
target="_blank"
translate>{{ 'app.shared.help.guide' }}</a>
</div>
</div>

View File

@ -788,7 +788,6 @@ ach:
age_filter: "crwdns8095:0crwdne8095:0"
from_age: "crwdns8097:0crwdne8097:0" #eg. from 8 to 40 years old
to_age: "crwdns8099:0crwdne8099:0" #eg. from 8 to 40 years old
_years_old: "crwdns8101:0crwdne8101:0"
start: "crwdns8103:0crwdne8103:0"
end: "crwdns8105:0crwdne8105:0"
custom_filter: "crwdns8107:0crwdne8107:0"

View File

@ -95,7 +95,7 @@ en:
event_in_the_past: "Unable to create a slot in the past."
edit_event: "Edit the event"
view_reservations: "View reservations"
legend: "legend"
legend: "Legend"
and: "and"
external_sync: "Calendar synchronization"
# import external iCal calendar
@ -240,7 +240,7 @@ en:
edit_this_and_next: "This event and the following"
edit_all: "All events"
date_wont_change: "Warning: you have changed the event date. This modification won't be propagated to other occurrences of the periodic event."
event_successfully_updated: "Event successfully updated"
event_successfully_updated: "Event successfully updated."
events_updated: "The event, and {COUNT, plural, =1{one other} other{{COUNT} others}}, have been updated"
unable_to_update_the_event: "Unable to update the event"
events_not_updated: "On {TOTAL} events, {COUNT, plural, =1{one was not updated} other{{COUNT} were not deleted}}."
@ -340,7 +340,7 @@ en:
#ajouter un code promotionnel
coupons_new:
add_a_coupon: "Add a coupon"
unable_to_create_the_coupon_check_code_already_used: "Unable to create the coupon. Please check that the code is not already used"
unable_to_create_the_coupon_check_code_already_used: "Unable to create the coupon. Please check that the code is not already used."
#mettre à jour un code promotionnel
coupons_edit:
coupon: "Coupon:"
@ -692,7 +692,7 @@ en:
#import results
members_import_result:
import_results: "Import results"
import_details: "Import #{ID}, of {DATE}, initiated by {USER}"
import_details: "Import # {ID}, of {DATE}, initiated by {USER}"
results: "Results"
pending: "Pending..."
status_create: "Creating a new user"
@ -768,7 +768,7 @@ en:
add_a_new_authentication_provider: "Add a new authentication provider"
a_local_database_provider_already_exists_unable_to_create_another: "A \"Local Database\" provider already exists. Unable to create another."
local_provider_successfully_saved: "Local provider successfully saved."
it_is_required_to_set_the_matching_between_User.uid_and_the_API_to_add_this_provider: "It is required to set the matching between User.uid and the API to add this provider"
it_is_required_to_set_the_matching_between_User.uid_and_the_API_to_add_this_provider: "It is required to set the matching between User.uid and the API to add this provider."
security_issue_detected: "Security issue detected"
beware_the_oauth2_authenticatoin_provider_you_are_about_to_add_isnt_using_HTTPS: "Beware: the OAuth 2 provider you are about to add isn't using HTTPS."
this_is_a_serious_security_issue_on_internet_and_should_never_be_used_except_for_testing_purposes: "This is a serious security issue on internet and should never be used except for testing purposes."
@ -778,8 +778,8 @@ en:
#edit an authentication provider (SSO)
authentication_edit:
provider: "Provider :"
it_is_required_to_set_the_matching_between_User.uid_and_the_API_to_add_this_provider: "It is required to set the matching between User.uid and the API to add this provider"
provider_successfully_updated: "Provider successfully updated"
it_is_required_to_set_the_matching_between_User.uid_and_the_API_to_add_this_provider: "It is required to set the matching between User.uid and the API to add this provider."
provider_successfully_updated: "Provider successfully updated."
an_error_occurred_unable_to_update_the_provider: "An error occurred: unable to update the provider."
#statistics tables
statistics:
@ -788,7 +788,6 @@ en:
age_filter: "Age filter"
from_age: "From" #eg. from 8 to 40 years old
to_age: "to" #eg. from 8 to 40 years old
_years_old: "years old"
start: "Start:"
end: "End:"
custom_filter: "Custom filter"
@ -801,7 +800,7 @@ en:
entries: "Entries:"
revenue_: "Revenue:"
average_age: "Average age:"
years_old: "Years old"
years_old: "years old"
total: "Total"
available_hours: "Hours available for booking:"
available_tickets: "Tickets available for booking:"
@ -1009,10 +1008,10 @@ en:
api_documentation: "API documentation"
open_api_clients: "OpenAPI clients"
name: "Name"
calls_count: "calls count"
calls_count: "Calls count"
token: "Token"
created_at: "Creation date"
reset_token: "revoke access"
reset_token: "Revoke access"
client_name: "Client's name"
confirmation_required: "Confirmation required"
do_you_really_want_to_delete_this_open_api_client: "Do you really want to delete this OpenAPI client?"
@ -1042,6 +1041,7 @@ en:
report_will_be_destroyed: "Once the report has been processed, it will be deleted. This can't be undone, continue?"
report_removed: "The report has been deleted"
failed_to_remove: "An error occurred, unable to delete the report"
#feature tour
tour:
conclusion:
title: "Thank you for your attention"
@ -1052,7 +1052,7 @@ en:
content: "Here you can create, modify and delete trainings. It is also the place where you can validate the training courses followed by your members."
trainings:
title: "Manage trainings"
content: "<p>When creating a training, you can define a default number of places. However, the number of actual places may be modified for each session.</p><p>The training sessions are scheduled from the administrator tab [Calendar].</p><p>Another thing: it is possible to associate one or more machines with a training. This makes it a prerequisite for the reservation of these machines.</p>"
content: "<p>When creating a training, you can define a default number of places. However, the number of actual places may be modified for each session.</p><p>The training sessions are scheduled from the administrator tab « Calendar ».</p><p>Another thing: it is possible to associate one or more machines with a training. This makes it a prerequisite for the reservation of these machines.</p>"
filter:
title: "Filter"
content: "By default, only active courses are displayed here. Display the others by choosing another filter here."

View File

@ -788,7 +788,6 @@ es:
age_filter: "Filtro de edad"
from_age: "Desde" #eg. from 8 to 40 years old
to_age: "a" #eg. from 8 to 40 years old
_years_old: "años"
start: "Principio:"
end: "Final:"
custom_filter: "Filtro personalizado"

View File

@ -788,7 +788,6 @@ fr:
age_filter: "Filtre d'âge"
from_age: "De" #eg. from 8 to 40 years old
to_age: "à" #eg. from 8 to 40 years old
_years_old: "ans"
start: "Début :"
end: "Fin :"
custom_filter: "Filtre personnalisé"
@ -1042,6 +1041,7 @@ fr:
report_will_be_destroyed: "Une fois le signalement traité, le rapport sera supprimé. Cette action est irréversible, continuer ?"
report_removed: "Le rapport a bien été supprimé"
failed_to_remove: "Une erreur est survenue, impossible de supprimer le rapport"
#feature tour
tour:
conclusion:
title: "Merci de votre attention"

View File

@ -788,7 +788,6 @@ pt:
age_filter: "Filtro de idade"
from_age: "Dos" #eg. from 8 to 40 years old
to_age: "aos" #eg. from 8 to 40 years old
_years_old: "anos de idade"
start: "Início:"
end: "Fim:"
custom_filter: "Filtro customizado"
@ -801,7 +800,7 @@ pt:
entries: "Entradas:"
revenue_: "Receita:"
average_age: "Idade média:"
years_old: "Anos de idade"
years_old: "anos de idade"
total: "Total"
available_hours: "Horas disponíveis para reserva:"
available_tickets: "Vagas disponíveis para reserva:"

View File

@ -45,7 +45,7 @@ en:
empty: ''
#dashboard: edit my profile
settings:
last_activity_on_: "Last activity on"
last_activity_on_: "Last activity on {DATE}"
i_want_to_change_group: "I want to change group!"
your_subscription_expires_on_: "Your subscription expires on"
no_subscriptions: "No subscriptions"

View File

@ -45,7 +45,7 @@ es:
empty: ''
#dashboard: edit my profile
settings:
last_activity_on_: "Última vez activo"
last_activity_on_: "Última vez activo {DATE}"
i_want_to_change_group: "Quiero cambiar de grupo"
your_subscription_expires_on_: "su suscripción acaba el"
no_subscriptions: "Sin suscripciones"

View File

@ -45,7 +45,7 @@ pt:
empty: ''
#dashboard: edit my profile
settings:
last_activity_on_: "Última atividade em"
last_activity_on_: "Última atividade em {DATE}"
i_want_to_change_group: "Eu quero trocar de grupo!"
your_subscription_expires_on_: "Sua inscrição expira em"
no_subscriptions: "Sem inscrições"

View File

@ -102,7 +102,7 @@ en:
connection: "Connection"
password_forgotten: "Forgotten password?"
confirm_my_account: "Confirm my e-mail"
not_registered_to_the_fablab: "Not registered to the Fablab?"
not_registered_to_the_fablab: "Not registered to the FabLab?"
create_an_account: "Create an account"
wrong_email_or_password: "Wrong e-mail or password."
caps_lock_is_on: "Caps lock key is on."
@ -148,9 +148,10 @@ en:
from_time_to_time: "From {START} to {END}"
free_entry: "Free entry"
free_admission: "Free admission"
full_price: "Full price"
full_price: "Full price: "
event_full: "Event full"
still_available: "Available place(s)"
still_available: "Available place(s): "
all_day: "All day"
#projects gallery
projects_list:
the_fablab_projects: "The Fab Lab projects"
@ -258,7 +259,7 @@ en:
subscription_confirmation: "Subscription confirmation"
here_is_the_NAME_subscription_summary: "Here is the {NAME}'s subscription summary:"
confirm_payment_of_html: "{ROLE, select, admin{Cash} other{Pay}}: {AMOUNT}" #(contexte : validate a payment of $20,00)
online_payment_disabled: "Payment by credit card is not available. Please contact the Fablab's reception directly."
online_payment_disabled: "Payment by credit card is not available. Please contact the FabLab's reception directly."
#Fablab's events list
events_list:
the_fablab_s_events: "The Fablab's events"
@ -301,7 +302,7 @@ en:
book: "Book"
confirm_and_pay: "Confirm and pay"
confirm_payment_of_html: "{ROLE, select, admin{Cash} other{Pay}}: {AMOUNT}" #(contexte : validate a payment of $20,00)
online_payment_disabled: "Payment by credit card is not available. Please contact the Fablab's reception directly."
online_payment_disabled: "Payment by credit card is not available. Please contact the FabLab's reception directly."
please_select_a_member_first: "Please select a member first"
change_the_reservation: "Change the reservation"
you_can_shift_this_reservation_on_the_following_slots: "You can shift this reservation on the following slots:"
@ -311,15 +312,15 @@ en:
delete_this_event: "Only this event"
delete_this_and_next: "This event and the following"
delete_all: "All events"
event_successfully_deleted: "Event successfully deleted"
event_successfully_deleted: "Event successfully deleted."
events_deleted: "The event, and {COUNT, plural, =1{one other} other{{COUNT} others}}, have been deleted"
unable_to_delete_the_event: "Unable to delete the event, it may be booked by a member"
events_not_deleted: "On {TOTAL} events, {COUNT, plural, =1{one was not deleted} other{{COUNT} were not deleted}}. Some reservations may exists on {COUNT, plural, =1{it} other{them}}."
cancel_the_reservation: "Cancel the reservation"
do_you_really_want_to_cancel_this_reservation_this_apply_to_all_booked_tickets: "Do you really want to cancel this reservation? This apply to ALL booked tickets."
reservation_was_successfully_cancelled: "Reservation was successfully cancelled"
reservation_was_successfully_cancelled: "Reservation was successfully cancelled."
cancellation_failed: "Cancellation failed."
event_is_over: "The event is over"
event_is_over: "The event is over."
thanks_for_coming: "Thanks for coming!"
view_event_list: "View events to come"
share_on_facebook: "Share on Facebook"
@ -381,7 +382,7 @@ en:
content: "Visualize at a glance everything that is scheduled for the next coming weeks (events, training, machines available, etc.)."
projects:
title: "Projects"
content: "<p>Document and share all your creations with the community.</p><p>If you use OpenLab, you will also be able to consult the projects of the entire Fab-Manager network. <a href='mailto:contact@fab-manager.com'>Contact-us</a> to get your access, it's free!</p>"
content: "<p>Document and share all your creations with the community.</p><p>If you use OpenLab, you will also be able to consult the projects of the entire Fab-manager network. <a href='mailto:contact@fab-manager.com'>Contact-us</a> to get your access, it's free!</p>"
plans:
title: "Subscriptions"
content: "Subscriptions provide a way to segment your prices and provide benefits to regular users."
@ -399,13 +400,13 @@ en:
content: "<p>Find your personal information here as well as all your activity on Fab-manager.</p><p>This space is also available for all your members.</p>"
news:
title: "News"
content: "<p>This space allows you to display the latest news from your structure.</p><p>You can easily change its content from [Customization]> [Home page].</p>"
content: "<p>This space allows you to display the latest news from your structure.</p><p>You can easily change its content from « Customization », « Home page».</p>"
last_projects:
title: "Last projects"
content: "<p>This carousel scrolls through the latest projects documented by your members.</p>"
last_tweet:
title: "Last tweet"
content: "<p>Le dernier tweet de votre flux Twitter peut s'afficher ici.</p><p>Configure it from [Customization]> [Home page].</p>"
content: "<p>Le dernier tweet de votre flux Twitter peut s'afficher ici.</p><p>Configure it from « Customization », « Home page».</p>"
last_members:
title: "Last members"
content: "The last registered members who have validated their address and agreed to be contacted will be shown here."

View File

@ -151,6 +151,7 @@ es:
full_price: "Precio final"
event_full: "Evento lleno"
still_available: "Available place(s)"
all_day: "Todo el día"
#projects gallery
projects_list:
the_fablab_projects: "Los proyectos del FabLab"

View File

@ -102,7 +102,7 @@ fr:
connection: "Connexion"
password_forgotten: "Mot de passe oublié ?"
confirm_my_account: "Confirmer mon adresse de courriel"
not_registered_to_the_fablab: "Vous n'êtes pas inscrit au FAB LAB ?"
not_registered_to_the_fablab: "Vous n'êtes pas inscrit au FabLab ?"
create_an_account: "Créer un compte"
wrong_email_or_password: "Adresse courriel ou mot de passe incorrect."
caps_lock_is_on: "La touche de verrouillage des majuscules est activée."
@ -143,14 +143,15 @@ fr:
#next events summary on the home page
fablab_s_next_events: "Les prochains évènements du Fab Lab"
every_events: "Tous les évènements"
from_date_to_date: "du {START} au {END}"
on_the_date: "le {DATE}"
from_time_to_time: "de {START} à {END}"
from_date_to_date: "Du {START} au {END}"
on_the_date: "Le {DATE}"
from_time_to_time: "De {START} à {END}"
free_entry: "Accès libre"
free_admission: "Entrée gratuite"
full_price: "Plein tarif : "
event_full: "Événement complet"
still_available: "Place(s) disponible(s) :"
all_day: "Toute la journée"
#projects gallery
projects_list:
the_fablab_projects: "Les projets du FabLab"

View File

@ -151,6 +151,7 @@ pt:
full_price: "Valor inteira"
event_full: "Evento lotado"
still_available: "Locais disponíveis"
all_day: "O dia inteiro"
#projects gallery
projects_list:
the_fablab_projects: "Projetos do Fab Lab"

View File

@ -214,7 +214,7 @@ en:
user_profile: "User profile"
warning_incomplete_user_profile_probably_imported_from_sso: "Warning: This user's profile is incomplete. As \"single sign-on\" (SSO) authentication is currently enabled, it may probably be an imported but non merged account. Do not modify it unless you know what your doing."
group: "Group"
group_is_required: "Group is required"
group_is_required: "Group is required."
trainings: "Trainings"
tags: "Tags"
#partial form to edit/create an authentication provider (SSO)
@ -308,10 +308,10 @@ en:
to_credit: 'Credit'
wallet_credit_successfully: "Wallet of user is credited successfully."
a_problem_occurred_for_wallet_credit: "A problem is occurred while taking the credit of wallet"
amount_is_required: "The amount is required"
amount_is_required: "The amount is required."
amount_minimum_1: "The amount minimum is 1"
amount_confirm_is_required: "The amount confirmation is required"
amount_confirm_does_not_match: "The amount confirmation does not match"
amount_confirm_is_required: "The amount confirmation is required."
amount_confirm_does_not_match: "The amount confirmation does not match."
you_have_amount_in_wallet: "You have {amount} {currency} in your wallet"
client_have_amount_in_wallet: "Client has {amount} {currency} in wallet"
wallet_pay_reservation: "You can pay direct your reservation"
@ -415,7 +415,7 @@ en:
confirm_payment_of_html: "{ROLE, select, admin{Payment on site} other{Pay}}: {AMOUNT}" #eg. confirm my payment of $20.00
a_problem_occurred_during_the_payment_process_please_try_again_later: "A problem occurred during the payment process. Please try again later."
none: "None"
online_payment_disabled: "Online payment is not available. Please contact the Fablab reception directly."
online_payment_disabled: "Online payment is not available. Please contact the FabLab's reception directly."
slot_restrict_plans: "This slot is restricted for the plans below:"
slot_restrict_subscriptions_must_select_plan: "The slot is restricted for the subscribers. Please select a plan first."
slot_restrict_plans_of_others_groups: "The slot is restricted for the subscribers of others groups."
@ -425,7 +425,14 @@ en:
slot_at_same_time: "Conflict with others reservations"
do_you_really_want_to_book_slot_at_same_time: "Do you really want to book this slot? Other bookings take place at the same time"
unable_to_book_slot_because_really_have_reservation_at_same_time: "Unable to book this slot because the following reservation occurs at the same time."
# feature-tour modal
tour:
previous: "Previous"
next: "Next"
end: "End the tour"
# help modal
help:
title: "Help"
what_to_do: "What do you want to do?"
tour: "Start the feature tour"
guide: "Open the user's manual"

View File

@ -425,7 +425,14 @@ fr:
slot_at_same_time: "Conflit avec d'autres réservations"
do_you_really_want_to_book_slot_at_same_time: "Êtes-vous sûr de réserver ce créneau ? D'autres réservations ont lieu en même temps"
unable_to_book_slot_because_really_have_reservation_at_same_time: "Impossible de réserver ce créneau car les réservations ci-dessous ont lieu en même temps."
# feature-tour modal
tour:
previous: "Précédent"
next: "Suivant"
end: "Terminer la visite"
# help modal
help:
title: "Aide"
what_to_do: "Que voulez-vous faire ?"
tour: "Lancer la visite guidée"
guide: "Ouvrir le manuel de l'utilisateur"