abraham 2.2.0 → 2.3.0.beta

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d6094c0e5929d5da7e61f12bd1e60a11e450a05e2c3b99afc349b0b7d847edca
4
- data.tar.gz: 2b6df2f7d73f7b0c312b13ca3bc5adf16452437f1fd97faea90468093193f5fa
3
+ metadata.gz: 5872e5ab9e3d24a4133de7b4127934eba2b36688eac51eb4f29bfdd9c7a0f1ff
4
+ data.tar.gz: ead10365b2cdf82e9f9e49f7ee55d9525731093b0b1b6faafe720b789766c977
5
5
  SHA512:
6
- metadata.gz: 978175580bd5132ea570ea0c14421f6ac0def8ca523ce5dfea730c3934c49180c6f9909fd35f161190afddf02aade22c9d447cb74546c419d8cd143e77129d3e
7
- data.tar.gz: 9c46128409adfc46ed76abe7f07601d4e5035c63641c13e50b747e51a2e532910326ed77f63f7b2406feb4f5930feb8dbdbe10e5b660f858409f1ce7cf8f186c
6
+ metadata.gz: 810d59a5b7d8f35d787d65fec4e42c46cb27edc7228272aa337adb31ddf9a4f35167610046f99861af51ccd0a65dea2bd77d32ac41f8fd07ed5f349516faa8b4
7
+ data.tar.gz: bfe6c59e405805b0e98938480037fc5a2c40ef4ae965558060ac4767cbc522890b131f634a190847b92d759b9facd7ba472d4f67b8a0b32eb183f660164f7487
data/README.md CHANGED
@@ -6,12 +6,13 @@ _Guide your users in the one true path._
6
6
 
7
7
  ![Watercolor Sheep](https://upload.wikimedia.org/wikipedia/commons/e/e4/Watercolor_Sheep_Drawing.jpg)
8
8
 
9
- Abraham injects dynamically-generated [Shepherd](https://shepherdjs.dev/) JavaScript code into your Rails application whenever a user should see a guided tour. Skip a tour, and we'll try again next time; complete a tour, and it won't show up again.
9
+ 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).
10
10
 
11
11
  * Define tour content with simple YAML files, in any/many languages.
12
12
  * Organize tours by controller and action.
13
- * Plays nicely with Turbolinks.
14
- * Ships with two basic CSS themes (default & dark) -- or write your own
13
+ * Trigger tours automatically on page load or manually via JavaScript method.
14
+ * Built with the [Shepherd JS](https://shepherdjs.dev/) library. Plays nicely with Turbolinks.
15
+ * Ships with two basic CSS themes (default & dark) — or write your own
15
16
 
16
17
  ## Requirements
17
18
 
@@ -38,7 +39,7 @@ $ rails db:migrate
38
39
  Install the JavaScript dependencies:
39
40
 
40
41
  ```
41
- $ yarn add jquery@^3.4.0 js-cookie@^2.2.0 shepherd.js@^6.0.0-beta
42
+ $ yarn add js-cookie@^2.2.0 shepherd.js@^6.0.0-beta
42
43
  ```
43
44
 
44
45
  Require `abraham` in `app/assets/javascripts/application.js`
@@ -77,7 +78,7 @@ Tell Abraham where to insert its generated JavaScript in `app/views/layouts/appl
77
78
 
78
79
  ## Defining your tours
79
80
 
80
- Define your tours in the `config/tours` directory. Its directory structure should mirror your application's controllers, and the tour files should mirror your actions/views.
81
+ Define your tours in the `config/tours` directory corresponding to the views defined in your application. Its directory structure mirrors your application's controllers, and the tour files mirror your actions/views.
81
82
 
82
83
  ```
83
84
  config/
@@ -92,11 +93,15 @@ config/
92
93
  └── show.es.yml
93
94
  ```
94
95
 
95
- NB: You must specify a locale in the filename, even if you're only supporting one language.
96
+ For example, per above, when a Spanish-speaking user visits `/articles/`, they'll see the tours defined by `config/tours/articles/index.es.yml`.
97
+
98
+ (Note: You must specify a locale in the filename, even if you're only supporting one language.)
96
99
 
97
100
  ### Tour content
98
101
 
99
- A tour is composed of a series of steps. A step may have a title and must have a description. You may attach a step to a particular element on the page, and place the callout in a particular position (see below).
102
+ Within a tour file, each tour is composed of a series of **steps**. A step may have a `title` and must have `text`. You may attach a step to a particular element on the page, and place the callout in a particular position.
103
+
104
+ In this example, we define a tour called "intro" with 3 steps:
100
105
 
101
106
  ```yaml
102
107
  intro:
@@ -129,7 +134,7 @@ When you specify an `attachTo` element, use the `placement` option to choose whe
129
134
  * `bottom left`
130
135
  * `bottom right`
131
136
  * `center` / `middle` / `middle center`
132
- * `left` / `middle left'
137
+ * `left` / `middle left`
133
138
  * `right` / `middle right`
134
139
  * `top` / `top center`
135
140
  * `top left`
@@ -140,6 +145,38 @@ Abraham tries to be helpful when your tour steps attach to page elements that ar
140
145
  * If your first step is attached to a particular element, and that element is not present on the page, the tour won't start. ([#28](https://github.com/actmd/abraham/issues/28))
141
146
  * If your tour has an intermediate step attached to a missing element, Abraham will skip that step and automatically show the next. ([#6](https://github.com/actmd/abraham/issues/6))
142
147
 
148
+ ### Automatic vs. manual tours
149
+
150
+ By default, Abraham will automatically start a tour that the current user hasn't seen yet. You can instead define a tour to be triggered manually using the `trigger` option:
151
+
152
+ ```yml
153
+ walkthrough:
154
+ trigger: "manual"
155
+ steps:
156
+ 1:
157
+ text: "This walkthrough will show you how to..."
158
+ ```
159
+
160
+ This tour will not start automatically; instead, use the `Abraham.startTour` method with the tour name:
161
+
162
+ ```
163
+ <button id="startTour">Start tour</button>
164
+
165
+ <script>
166
+ document.querySelector("#startTour").addEventListener("click", function() {
167
+ Abraham.startTour("walkthrough"));
168
+ });
169
+ </script>
170
+ ```
171
+
172
+ ...or if you happen to use jQuery:
173
+
174
+ ```
175
+ <script>
176
+ $("#startTour").on("click", function() { Abraham.startTour('walkthrough'); })
177
+ </script>
178
+ ```
179
+
143
180
  ### Testing your tours
144
181
 
145
182
  Abraham loads tour definitions once when you start your server. Restart your server to see tour changes.
@@ -154,11 +191,11 @@ end
154
191
 
155
192
  ## Full example
156
193
 
157
- We provide a [small example app](https://github.com/actmd/abraham-example) that implements abraham, so you can see it in action.
194
+ We provide a [small example app](https://github.com/actmd/abraham-example) that implements Abraham, so you can see it in action.
158
195
 
159
196
  ## Upgrading from version 1
160
197
 
161
- Abraham v1 was built using Shepherd 1.8, v2 now uses Shepherd 6 -- quite a jump, yes.
198
+ Abraham v1 was built using Shepherd 1.8, v2 now uses Shepherd 6 quite a jump, yes.
162
199
 
163
200
  If you were using Abraham v1, you'll want to take the following steps to upgrade:
164
201
 
@@ -1,7 +1,28 @@
1
1
  //= require js-cookie/src/js.cookie
2
2
  //= require shepherd.js/dist/js/shepherd
3
3
 
4
+ var Abraham = new Object();
5
+
6
+ Abraham.tours = {};
7
+ Abraham.incompleteTours = [];
8
+ Abraham.startTour = function(tourName) {
9
+ if (!Shepherd.activeTour) {
10
+ Abraham.tours[tourName].start();
11
+ }
12
+ };
13
+ Abraham.startNextIncompleteTour = function() {
14
+ if (Abraham.incompleteTours.length) {
15
+ Abraham.tours[Abraham.incompleteTours[0]].checkAndStart();
16
+ }
17
+ };
18
+
19
+ document.addEventListener("DOMContentLoaded", Abraham.startNextIncompleteTour);
20
+ document.addEventListener("turbolinks:load", Abraham.startNextIncompleteTour);
21
+
4
22
  document.addEventListener('turbolinks:before-cache', function() {
5
23
  // Remove visible product tours
6
24
  document.querySelectorAll(".shepherd-element").forEach(function(el) { el.remove() });
25
+ // Clear Abraham data
26
+ Abraham.tours = {};
27
+ Abraham.incompleteTours = [];
7
28
  });
@@ -4,23 +4,31 @@ module AbrahamHelper
4
4
  def abraham_tour
5
5
  # Do we have tours for this controller/action in the user's locale?
6
6
  tours = Rails.configuration.abraham.tours["#{controller_name}.#{action_name}.#{I18n.locale}"]
7
-
7
+ # Otherwise, default to the default locale
8
8
  tours ||= Rails.configuration.abraham.tours["#{controller_name}.#{action_name}.#{I18n.default_locale}"]
9
9
 
10
10
  if tours
11
+ # Have any automatic tours been completed already?
11
12
  completed = AbrahamHistory.where(
12
13
  creator_id: current_user.id,
13
14
  controller_name: controller_name,
14
15
  action_name: action_name
15
16
  )
16
- remaining = tours.keys - completed.map(&:tour_name)
17
17
 
18
- if remaining.any?
19
- # Generate the javascript snippet for the next remaining tour
20
- render(partial: "application/abraham",
21
- locals: { tour_name: remaining.first,
22
- steps: tours[remaining.first]["steps"] })
18
+ tour_keys_completed = completed.map(&:tour_name)
19
+ tour_keys = tours.keys
20
+
21
+ tour_html = ''
22
+
23
+ tour_keys.each do |key|
24
+ tour_html += render(partial: "application/abraham",
25
+ locals: { tour_name: key,
26
+ tour_completed: tour_keys_completed.include?(key),
27
+ trigger: tours[key]["trigger"],
28
+ steps: tours[key]["steps"] })
23
29
  end
30
+
31
+ tour_html.html_safe
24
32
  end
25
33
  end
26
34
 
@@ -1,7 +1,8 @@
1
1
  <script>
2
- var tour = new Shepherd.Tour(<%= Rails.configuration.abraham.tour_options.html_safe unless Rails.configuration.abraham.tour_options.nil? %>);
2
+ Abraham.tours["<%= tour_name %>"] = new Shepherd.Tour(<%= Rails.configuration.abraham.tour_options.html_safe unless Rails.configuration.abraham.tour_options.nil? %>);
3
3
 
4
- tour.on("complete", function() {
4
+ <% if trigger != 'manual' %>
5
+ Abraham.tours["<%= tour_name %>"].on("complete", function() {
5
6
  // Make AJAX call to save history of tour completion
6
7
  return fetch("/abraham_histories/", {
7
8
  method: "POST",
@@ -15,12 +16,13 @@
15
16
  });
16
17
  });
17
18
 
18
- tour.on("cancel", function() {
19
+ Abraham.tours["<%= tour_name %>"].on("cancel", function() {
19
20
  Cookies.set('<%= abraham_cookie_prefix %>-<%= tour_name %>', 'later', { domain: '<%= abraham_domain %>' });
20
21
  });
22
+ <% end %>
21
23
 
22
24
  <% steps.each_with_index do |(key, step), index| %>
23
- tour.addStep({
25
+ Abraham.tours["<%= tour_name %>"].addStep({
24
26
  id: 'step-<%= key %>',
25
27
  <% if step.key?('title') %>
26
28
  title: "<%= step['title'] %>",
@@ -34,35 +36,40 @@
34
36
  },
35
37
  <% end %>
36
38
  buttons: [
37
- <% if index == 0 %>
38
- { text: '<%= t('abraham.later') %>', action: tour.cancel, classes: 'shepherd-button-secondary' },
39
- { text: '<%= t('abraham.continue') %>', action: tour.next }
39
+ <% if index == steps.size - 1 %>
40
+ { text: '<%= t('abraham.done') %>', action: Abraham.tours["<%= tour_name %>"].complete }
40
41
  <% else %>
41
- <% if index == steps.size - 1 %>
42
- { text: '<%= t('abraham.done') %>', action: tour.complete }
43
- <% else %>
44
- { text: '<%= t('abraham.exit') %>', action: tour.cancel, classes: 'shepherd-button-secondary' },
45
- { text: '<%= t('abraham.next') %>', action: tour.next }
46
- <% end %>
42
+ <% if index == 0 %>
43
+ { text: '<%= t('abraham.later') %>', action: Abraham.tours["<%= tour_name %>"].cancel, classes: 'shepherd-button-secondary' },
44
+ { text: '<%= t('abraham.continue') %>', action: Abraham.tours["<%= tour_name %>"].next }
45
+ <% else %>
46
+ { text: '<%= t('abraham.exit') %>', action: Abraham.tours["<%= tour_name %>"].cancel, classes: 'shepherd-button-secondary' },
47
+ { text: '<%= t('abraham.next') %>', action: Abraham.tours["<%= tour_name %>"].next }
48
+ <% end %>
47
49
  <% end %>
48
50
  ]
49
51
  });
50
52
  <% end %>
51
53
 
52
- tour.start = function (start) {
53
- return function () {
54
- // Don't start the tour if the user dismissed it once this session
55
- var tourMayStart = !Cookies.get('<%= abraham_cookie_prefix %>-<%= tour_name %>', {domain: '<%= abraham_domain %>'});
56
- <% if steps.first[1]['attachTo'] %>
57
- // Don't start the tour if the first step's element is missing
58
- tourMayStart = tourMayStart && document.querySelector("<%= steps.first[1]['attachTo']['element'] %>");
59
- <% end %>
60
-
61
- if (tourMayStart) {
62
- start();
54
+ <% if trigger != "manual" %>
55
+ Abraham.tours["<%= tour_name %>"].checkAndStart = function (start) {
56
+ return function () {
57
+ // Don't start the tour if the user dismissed it once this session
58
+ var tourMayStart = !Cookies.get('<%= abraham_cookie_prefix %>-<%= tour_name %>', {domain: '<%= abraham_domain %>'});
59
+ <% if steps.first[1]['attachTo'] %>
60
+ // Don't start the tour if the first step's element is missing
61
+ tourMayStart = tourMayStart && document.querySelector("<%= steps.first[1]['attachTo']['element'] %>");
62
+ <% end %>
63
+
64
+ if (tourMayStart) {
65
+ start();
66
+ }
63
67
  }
64
- }
65
- }(tour.start)
68
+ }(Abraham.tours["<%= tour_name %>"].start)
69
+
70
+ <% if !tour_completed %>
71
+ Abraham.incompleteTours.push("<%= tour_name %>");
72
+ <% end %>
73
+ <% end %>
66
74
 
67
- tour.start()
68
75
  </script>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Abraham
4
- VERSION = "2.2.0"
4
+ VERSION = "2.3.0.beta"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: abraham
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.3.0.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Abbett
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-15 00:00:00.000000000 Z
11
+ date: 2021-04-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sassc-rails
@@ -126,9 +126,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
126
126
  version: '0'
127
127
  required_rubygems_version: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - ">="
129
+ - - ">"
130
130
  - !ruby/object:Gem::Version
131
- version: '0'
131
+ version: 1.3.1
132
132
  requirements: []
133
133
  rubygems_version: 3.0.8
134
134
  signing_key: