diff --git a/administrator/language/en-GB/mod_guidedtours.ini b/administrator/language/en-GB/mod_guidedtours.ini index 0003ee393d86d..3e8fd58484a2a 100644 --- a/administrator/language/en-GB/mod_guidedtours.ini +++ b/administrator/language/en-GB/mod_guidedtours.ini @@ -4,8 +4,10 @@ ; Note : All ini files need to be saved as UTF-8 MOD_GUIDEDTOURS="Guided Tours" +MOD_GUIDEDTOURS_FIELD_TOUR_COUNT_DESC="The maximum number of tours to show in the dropdown" +MOD_GUIDEDTOURS_FIELD_TOUR_COUNT_LABEL="Tour Count" MOD_GUIDEDTOURS_GENERIC_TOUR="Generic" MOD_GUIDEDTOURS_MENU="Take a Tour" +MOD_GUIDEDTOURS_SHOW_ALL="Show all tours" MOD_GUIDEDTOURS_START_TOUR="Start tour" -MOD_GUIDEDTOUR_SHOW_ALL="Show all tours" MOD_GUIDEDTOURS_XML_DESCRIPTION="This module shows a list of the available guided tours." diff --git a/administrator/modules/mod_guidedtours/mod_guidedtours.xml b/administrator/modules/mod_guidedtours/mod_guidedtours.xml index c44aa5ba85606..d98b170c78e7f 100644 --- a/administrator/modules/mod_guidedtours/mod_guidedtours.xml +++ b/administrator/modules/mod_guidedtours/mod_guidedtours.xml @@ -22,6 +22,19 @@ +
+ +
+
-'; diff --git a/build/media_source/plg_system_tour/css/guide.css b/build/media_source/plg_system_tour/css/guide.css index 42e0b9c9b8df2..feb49400e5954 100644 --- a/build/media_source/plg_system_tour/css/guide.css +++ b/build/media_source/plg_system_tour/css/guide.css @@ -1,18 +1,29 @@ -.subhead .btn { - margin: 0; -} +/** + * @copyright (C) 2012 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ .shepherd-title { - flex: 1 1 auto; + flex: 1 1 auto; + line-height: 1.5em; +} + +.shepherd-progress { + margin: 0 15px; +} + +.shepherd-text { + line-height: 1.5em; + padding: 1em; } .shepherd-footer { - display: grid; - grid-template-columns: repeat(3, 1fr); + display: grid; + grid-template-columns: repeat(3, 1fr); } .shepherd-button-primary { - grid-column-start: 3; + grid-column-start: 3; } .shepherd-enabled.shepherd-element[data-popper-placement="bottom"] { diff --git a/build/media_source/plg_system_tour/js/guide.es5.js b/build/media_source/plg_system_tour/js/guide.es5.js index 92248604784f6..1df722fe6bbb0 100644 --- a/build/media_source/plg_system_tour/js/guide.es5.js +++ b/build/media_source/plg_system_tour/js/guide.es5.js @@ -3,10 +3,10 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt */ -function checkAndRedirect(redirectUrl) { - const currentURL = window.location.href; - if (currentURL !== redirectUrl) { - window.location.href = redirectUrl; +function checkAndRedirect(redirect_url) { + const current_url = window.location.href; + if (current_url !== redirect_url) { + window.location.href = redirect_url; } } @@ -16,7 +16,7 @@ function instantiateTour() { cancelIcon: { enabled: true, }, - classes: 'class-1 class-2 shepherd-theme-arrows', + classes: 'shepherd-theme-arrows', scrollTo: { behavior: 'smooth', block: 'center', @@ -27,11 +27,19 @@ function instantiateTour() { }); } +function addProgressIndicator(step_element, index, total) { + const header = step_element.querySelector('.shepherd-header'); + let progress = document.createElement('span'); + progress.classList.add('shepherd-progress'); + progress.innerText = `${index}/${total}`; + header.insertBefore(progress, step_element.querySelector('.shepherd-cancel-icon')); +} + function addStepToTourButton(tour, obj, index, buttons) { tour.addStep({ title: obj.steps[index].title, text: obj.steps[index].description, - classes: 'intro-step shepherd-theme-arrows', + classes: 'shepherd-theme-arrows', attachTo: { element: obj.steps[index].target, on: obj.steps[index].position, @@ -40,31 +48,31 @@ function addStepToTourButton(tour, obj, index, buttons) { interactive_type: obj.steps[index].interactive_type, }, buttons: buttons, - id: obj.steps[index].ordering, + id: obj.steps[index].id, arrow: true, when: { show() { - const currentStepIndex = `${tour.currentStep.id}`; - sessionStorage.setItem('currentStepId', String(currentStepIndex)); - const theElement = this.getElement(); - if (theElement) { - theElement.focus = () => { + const current_step_id = `${tour.currentStep.id}`; + sessionStorage.setItem('currentStepId', String(current_step_id)); - const tabbed_elements = document.querySelectorAll('[tabindex]'); - tabbed_elements.forEach(function(elt) { - elt.setAttribute('tabindex', '-1'); - }); + const step_element = this.getElement(); + addProgressIndicator(step_element, parseInt(current_step_id) + 1, sessionStorage.getItem('stepCount')); - tour.currentStep.getTarget().focus(); - tour.currentStep.getTarget().tabIndex = 1; + step_element.focus = () => { + const tabbed_elements = document.querySelectorAll('[tabindex]'); + tabbed_elements.forEach(function(elt) { + elt.setAttribute('tabindex', '-1'); + }); + + tour.currentStep.getTarget().focus(); + tour.currentStep.getTarget().tabIndex = 1; + + const popup_buttons = tour.currentStep.getElement().querySelectorAll('.shepherd-content button'); + popup_buttons.forEach(function(elt, index) { + elt.setAttribute('tabindex', popup_buttons.length + 1 - index); // loose tab on 'back' + }); + } - const popup_buttons = tour.currentStep.getElement().querySelectorAll('.shepherd-content button'); - popup_buttons.forEach(function(elt, index) { - //elt.setAttribute('tabindex', popup_buttons.length + 1 - index); // loose tab on 'back' - elt.setAttribute('tabindex', index + 2); - }); - } - } if (obj.steps[index].type === 1) { checkAndRedirect(Joomla.getOptions('system.paths').rootFull + tour.currentStep.options.attachTo.url); } @@ -91,13 +99,23 @@ function addInitialStepToTourButton(tour, obj) { }, ], id: 0, + when: { + show() { + const current_step_id = `${tour.currentStep.id}`; + sessionStorage.setItem('currentStepId', String(current_step_id)); + + const step_count = this.getTour().steps.length; + sessionStorage.setItem('stepCount', String(step_count)); + + addProgressIndicator(this.getElement(), 1, step_count); + }, + }, }); } function addCancelTourEvent(tour) { tour.on('cancel', () => { - sessionStorage.removeItem('currentStepId'); - sessionStorage.removeItem('tourId'); + emptyStorage(); const url = `${Joomla.getOptions('system.paths').rootFull}administrator/index.php?option=com_ajax&plugin=tour&group=system&format=raw&method=post&tour_id=-1`; fetch( url, @@ -152,13 +170,13 @@ function enableButton(event) { element.removeAttribute('disabled'); } -function CreateAndStartTour(obj) { - const currentStepId = sessionStorage.getItem('currentStepId'); +function createAndStartTour(obj) { + const current_step_id = sessionStorage.getItem('currentStepId'); let prevStep = ''; const tour = instantiateTour(); let ind = 0; - if (currentStepId) { - ind = obj.steps.findIndex((x) => x.id === Number(currentStepId)); + if (current_step_id) { + ind = obj.steps.findIndex((x) => x.id === Number(current_step_id)); if (ind < 0) { return; } @@ -239,6 +257,12 @@ function tourWasSelected(element) { } } +function emptyStorage() { + sessionStorage.removeItem('currentStepId'); + sessionStorage.removeItem('stepCount'); + sessionStorage.removeItem('tourId'); +} + Joomla = window.Joomla || {}; ((Joomla, document) => { @@ -247,29 +271,27 @@ Joomla = window.Joomla || {}; document.addEventListener('GuidedTourLoaded', (event) => { sessionStorage.setItem('tourId', event.detail.id); const uri = Joomla.getOptions('system.paths').rootFull; - const currentURL = window.location.href; - if (currentURL !== uri + event.detail.url) { + const current_url = window.location.href; + if (current_url !== uri + event.detail.url) { window.location.href = uri + event.detail.url; } else { - CreateAndStartTour(event.detail); + createAndStartTour(event.detail); } }); document.addEventListener('DOMContentLoaded', () => { - const tourId = sessionStorage.getItem('tourId'); - if (tourId) { - const myTour = Joomla.getOptions('myTour'); - if (myTour) { - CreateAndStartTour(JSON.parse(myTour)); + const tour_id = sessionStorage.getItem('tourId'); + if (tour_id) { + const my_tour = Joomla.getOptions('myTour'); + if (my_tour) { + createAndStartTour(JSON.parse(my_tour)); } else { - sessionStorage.removeItem('currentStepId'); - sessionStorage.removeItem('tourId'); + emptyStorage(); } } // Opt-in Start buttons const elements = document.querySelectorAll('.button-start-guidedtour'); - elements.forEach(elem => { elem.addEventListener('click', e => { tourWasSelected(e.target); diff --git a/plugins/system/tour/tour.php b/plugins/system/tour/tour.php index 12f5735e0aecd..5a58719c21002 100644 --- a/plugins/system/tour/tour.php +++ b/plugins/system/tour/tour.php @@ -152,7 +152,8 @@ protected function getJsonTour($tour_id) $tour_steps = $mySteps->getItems(); - foreach ($tour_steps as $step) { + foreach ($tour_steps as $i => $step) { + $step->id = $i + 1; $step->title = Text::_($step->title); $step->description = Text::_($step->description);