diff --git a/CHANGELOG.md b/CHANGELOG.md
index e1934b758..11da68a94 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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
 
diff --git a/app/assets/javascripts/controllers/admin/calendar.js.erb b/app/assets/javascripts/controllers/admin/calendar.js.erb
index 0a6fe92b5..8fbb2ec14 100644
--- a/app/assets/javascripts/controllers/admin/calendar.js.erb
+++ b/app/assets/javascripts/controllers/admin/calendar.js.erb
@@ -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();
   }
diff --git a/app/assets/javascripts/controllers/admin/events.js.erb b/app/assets/javascripts/controllers/admin/events.js.erb
index 425e7af6d..1a1efbd6f 100644
--- a/app/assets/javascripts/controllers/admin/events.js.erb
+++ b/app/assets/javascripts/controllers/admin/events.js.erb
@@ -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(); }
-      }
     };
 
     /**
diff --git a/app/assets/javascripts/controllers/admin/invoices.js.erb b/app/assets/javascripts/controllers/admin/invoices.js.erb
index 9c7a72356..27a4298e1 100644
--- a/app/assets/javascripts/controllers/admin/invoices.js.erb
+++ b/app/assets/javascripts/controllers/admin/invoices.js.erb
@@ -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();
   }
diff --git a/app/assets/javascripts/controllers/admin/members.js.erb b/app/assets/javascripts/controllers/admin/members.js.erb
index d1bfa3fb8..e392925d2 100644
--- a/app/assets/javascripts/controllers/admin/members.js.erb
+++ b/app/assets/javascripts/controllers/admin/members.js.erb
@@ -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();
   }
diff --git a/app/assets/javascripts/controllers/admin/open_api_clients.js b/app/assets/javascripts/controllers/admin/open_api_clients.js
index d30ba1a8e..0b71944dc 100644
--- a/app/assets/javascripts/controllers/admin/open_api_clients.js
+++ b/app/assets/javascripts/controllers/admin/open_api_clients.js
@@ -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();
diff --git a/app/assets/javascripts/controllers/admin/pricing.js.erb b/app/assets/javascripts/controllers/admin/pricing.js.erb
index 2e8eae011..96239941e 100644
--- a/app/assets/javascripts/controllers/admin/pricing.js.erb
+++ b/app/assets/javascripts/controllers/admin/pricing.js.erb
@@ -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}>}
diff --git a/app/assets/javascripts/controllers/admin/project_elements.js b/app/assets/javascripts/controllers/admin/project_elements.js
index 557404615..3ab047d1d 100644
--- a/app/assets/javascripts/controllers/admin/project_elements.js
+++ b/app/assets/javascripts/controllers/admin/project_elements.js
@@ -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();
diff --git a/app/assets/javascripts/controllers/admin/settings.js.erb b/app/assets/javascripts/controllers/admin/settings.js.erb
index d7e5fc337..7f4947fca 100644
--- a/app/assets/javascripts/controllers/admin/settings.js.erb
+++ b/app/assets/javascripts/controllers/admin/settings.js.erb
@@ -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();
   }
diff --git a/app/assets/javascripts/controllers/admin/statistics.js.erb b/app/assets/javascripts/controllers/admin/statistics.js.erb
index 8f6e42491..85e650247 100644
--- a/app/assets/javascripts/controllers/admin/statistics.js.erb
+++ b/app/assets/javascripts/controllers/admin/statistics.js.erb
@@ -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(); }
-      }
     };
 
     /**
diff --git a/app/assets/javascripts/controllers/admin/trainings.js.erb b/app/assets/javascripts/controllers/admin/trainings.js.erb
index 1710b5806..b0d90551e 100644
--- a/app/assets/javascripts/controllers/admin/trainings.js.erb
+++ b/app/assets/javascripts/controllers/admin/trainings.js.erb
@@ -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
diff --git a/app/assets/javascripts/controllers/machines.js.erb b/app/assets/javascripts/controllers/machines.js.erb
index f21f106ce..434bee02e 100644
--- a/app/assets/javascripts/controllers/machines.js.erb
+++ b/app/assets/javascripts/controllers/machines.js.erb
@@ -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();
diff --git a/app/assets/javascripts/controllers/spaces.js.erb b/app/assets/javascripts/controllers/spaces.js.erb
index bc0fba8ab..fe268ea36 100644
--- a/app/assets/javascripts/controllers/spaces.js.erb
+++ b/app/assets/javascripts/controllers/spaces.js.erb
@@ -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();
diff --git a/app/assets/javascripts/services/help.js.erb b/app/assets/javascripts/services/help.js.erb
index 983a085f5..344af4bde 100644
--- a/app/assets/javascripts/services/help.js.erb
+++ b/app/assets/javascripts/services/help.js.erb
@@ -1,6 +1,6 @@
 'use strict';
 
-Application.Services.factory('Help', ['$uibModal', '$state', function ($uibModal, $state) {
+Application.Services.factory('Help', ['$rootScope', '$uibModal', '$state', function ($rootScope, $uibModal, $state) {
   const TOURS = {
     'app.public.home': 'welcome',
     'app.public.machines_list': 'machines',
@@ -11,31 +11,36 @@ Application.Services.factory('Help', ['$uibModal', '$state', function ($uibModal
     'app.admin.invoices': 'invoices',
     'app.admin.pricing': 'pricing',
     'app.admin.events': 'events',
-    'app.admin.project_elements': 'project_elements',
+    'app.admin.project_elements': 'project-elements',
     'app.admin.statistics': 'statistics',
     'app.admin.settings': 'settings',
-    'app.admin.open_api_clients': 'open_api'
+    '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 tour = TOURS[$state.current.name];
+      const tourName = TOURS[$state.current.name];
 
       // if no tour, just open the guide
-      if (tour === undefined) {
+      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" %>',
-        controller: ['$scope', '$uibModalInstance', 'uiTourService', function ($scope, $uibModalInstance, uiTourService) {
+        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(tour);
+            const tour = uiTourService.getTourByName(tourName);
             if (tour) { tour.start(); }
 
             $uibModalInstance.close('tour');