From ae06540ea086407b508e5818b6d311ad97aa22e3 Mon Sep 17 00:00:00 2001 From: Jonathan Abbett Date: Fri, 16 Apr 2021 16:09:56 -0400 Subject: [PATCH] Better handling of tour triggering --- README.md | 8 ++--- app/assets/javascripts/abraham/index.js | 21 ++++++++++--- app/helpers/abraham_helper.rb | 23 -------------- app/views/application/_abraham.html.erb | 31 +++++++------------ test/dummy/app/views/dashboard/home.html.erb | 6 ++-- .../dummy/config/tours/dashboard/other.en.yml | 10 +++--- test/dummy/test/system/tours_test.rb | 18 +++++++++++ 7 files changed, 59 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index bc1bdea..564e6e1 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ _Guide your users in the one true path._ ![Watercolor Sheep](https://upload.wikimedia.org/wikipedia/commons/e/e4/Watercolor_Sheep_Drawing.jpg) -Abraham makes it easy to show guided tours to users of your Rails application. Abraham keeps track of whether someone has seen a tour so it doesn't appear again and also lets a user skip until their next visit. +Abraham makes it easy to show guided tours to users of your Rails application. When Abraham shows a tour, it keeps track of whether the user has completed it (so it doesn't get shown again) or dismissed it for later (so it reappears in a future user session). * Define tour content with simple YAML files, in any/many languages. * Organize tours by controller and action. @@ -157,14 +157,14 @@ walkthrough: text: "This walkthrough will show you how to..." ``` -Abraham creates a JavaScript event based on the tour name that you can wire into a link or button on that page. In the above example, you would use the `abraham:walthrough:start` event to make the tour appear: +This tour will not start automatically; instead, use the `Abraham.startTour` method with the tour name: ``` ``` @@ -173,7 +173,7 @@ Abraham creates a JavaScript event based on the tour name that you can wire into ``` ``` diff --git a/app/assets/javascripts/abraham/index.js b/app/assets/javascripts/abraham/index.js index 8d6b3a2..752e0fe 100644 --- a/app/assets/javascripts/abraham/index.js +++ b/app/assets/javascripts/abraham/index.js @@ -1,10 +1,23 @@ //= require js-cookie/src/js.cookie //= require shepherd.js/dist/js/shepherd -var abrahamReady = (callback) => { - if (document.readyState != "loading") callback(); - else document.addEventListener("DOMContentLoaded", callback); -} +var Abraham = new Object(); + +Abraham.tours = {}; +Abraham.incompleteTours = []; +Abraham.startTour = function(tourName) { + if (!Shepherd.activeTour) { + Abraham.tours[tourName].start(); + } +}; +Abraham.startNextIncompleteTour = function() { + if (Abraham.incompleteTours.length) { + Abraham.tours[Abraham.incompleteTours[0]].checkAndStart(); + } +}; + +document.addEventListener("DOMContentLoaded", Abraham.startNextIncompleteTour); +document.addEventListener("turbolinks:load", Abraham.startNextIncompleteTour); document.addEventListener('turbolinks:before-cache', function() { // Remove visible product tours diff --git a/app/helpers/abraham_helper.rb b/app/helpers/abraham_helper.rb index 99de648..caa54dc 100644 --- a/app/helpers/abraham_helper.rb +++ b/app/helpers/abraham_helper.rb @@ -1,29 +1,6 @@ # frozen_string_literal: true module AbrahamHelper - # def abraham_tour - # # Do we have tours for this controller/action in the user's locale? - # tours = Rails.configuration.abraham.tours["#{controller_name}.#{action_name}.#{I18n.locale}"] - - # tours ||= Rails.configuration.abraham.tours["#{controller_name}.#{action_name}.#{I18n.default_locale}"] - - # if tours - # completed = AbrahamHistory.where( - # creator_id: current_user.id, - # controller_name: controller_name, - # action_name: action_name - # ) - # remaining = tours.keys - completed.map(&:tour_name) - - # if remaining.any? - # # Generate the javascript snippet for the next remaining tour - # render(partial: "application/abraham", - # locals: { tour_name: remaining.first, - # steps: tours[remaining.first]["steps"] }) - # end - # end - # end - def abraham_tour # Do we have tours for this controller/action in the user's locale? tours = Rails.configuration.abraham.tours["#{controller_name}.#{action_name}.#{I18n.locale}"] diff --git a/app/views/application/_abraham.html.erb b/app/views/application/_abraham.html.erb index 8c3a5c7..886a092 100644 --- a/app/views/application/_abraham.html.erb +++ b/app/views/application/_abraham.html.erb @@ -1,8 +1,8 @@ diff --git a/test/dummy/app/views/dashboard/home.html.erb b/test/dummy/app/views/dashboard/home.html.erb index 5615857..6dd9958 100644 --- a/test/dummy/app/views/dashboard/home.html.erb +++ b/test/dummy/app/views/dashboard/home.html.erb @@ -11,15 +11,15 @@ diff --git a/test/dummy/config/tours/dashboard/other.en.yml b/test/dummy/config/tours/dashboard/other.en.yml index 799c65e..8b0d7ac 100644 --- a/test/dummy/config/tours/dashboard/other.en.yml +++ b/test/dummy/config/tours/dashboard/other.en.yml @@ -7,8 +7,8 @@ tour_one: element: "p" placement: "top" -# tour_two: -# steps: -# 1: -# title: "TOUR TWO step one ENGLISH" -# text: "we show this on your second visit" +tour_two: + steps: + 1: + title: "TOUR TWO step one ENGLISH" + text: "we show this on your second visit" diff --git a/test/dummy/test/system/tours_test.rb b/test/dummy/test/system/tours_test.rb index 66bbfe0..17636fa 100644 --- a/test/dummy/test/system/tours_test.rb +++ b/test/dummy/test/system/tours_test.rb @@ -93,4 +93,22 @@ class ToursTest < ApplicationSystemTestCase # No tour should be visible, since the first step is invalid refute_selector ".shepherd-element" end + + test "page with two incomplete tours shows them on consecutive visits" do + # First tour should appear at first visit + visit dashboard_other_url + assert_selector ".shepherd-element", visible: true + assert_selector ".shepherd-header", text: "TOUR ONE step one ENGLISH" + find(".shepherd-button", text: "Done").click + + # Second tour should appear at second visit + visit dashboard_other_url + assert_selector ".shepherd-element", visible: true + assert_selector ".shepherd-header", text: "TOUR TWO step one ENGLISH" + find(".shepherd-button", text: "Done").click + + # Now no tours should appear since they're both done + visit dashboard_other_url + refute_selector ".shepherd-element" + end end