From 9e7822f34a42b156ad5c5e6cc5e02e2d56cb6608 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Wed, 11 Mar 2020 10:26:53 +0100 Subject: [PATCH] Improved contextual help with a modal dialog --- CHANGELOG.md | 1 + .../controllers/admin/calendar.js.erb | 21 +--------- .../controllers/admin/events.js.erb | 19 --------- .../controllers/admin/invoices.js.erb | 19 --------- .../controllers/admin/members.js.erb | 17 -------- .../controllers/admin/open_api_clients.js | 21 +--------- .../controllers/admin/pricing.js.erb | 19 --------- .../controllers/admin/project_elements.js | 39 +++++-------------- .../controllers/admin/settings.js.erb | 17 -------- .../controllers/admin/statistics.js.erb | 18 --------- .../controllers/admin/trainings.js.erb | 20 +--------- .../javascripts/controllers/machines.js.erb | 21 +--------- .../javascripts/controllers/spaces.js.erb | 21 +--------- app/assets/javascripts/services/help.js.erb | 19 +++++---- 14 files changed, 27 insertions(+), 245 deletions(-) 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');