abraham 2.3.0.beta → 2.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5872e5ab9e3d24a4133de7b4127934eba2b36688eac51eb4f29bfdd9c7a0f1ff
4
- data.tar.gz: ead10365b2cdf82e9f9e49f7ee55d9525731093b0b1b6faafe720b789766c977
3
+ metadata.gz: 3f58e765abccdc1ca54c84235af22089873e9d3a5de2b4e862a85273f58d56a9
4
+ data.tar.gz: a8e6aafc28d11ebbb4c593c010d0d5eb5a9b204897394286bd1cdc3a5b4e67ef
5
5
  SHA512:
6
- metadata.gz: 810d59a5b7d8f35d787d65fec4e42c46cb27edc7228272aa337adb31ddf9a4f35167610046f99861af51ccd0a65dea2bd77d32ac41f8fd07ed5f349516faa8b4
7
- data.tar.gz: bfe6c59e405805b0e98938480037fc5a2c40ef4ae965558060ac4767cbc522890b131f634a190847b92d759b9facd7ba472d4f67b8a0b32eb183f660164f7487
6
+ metadata.gz: 05f6395978a18eb6cdfec2acae497620fdeee810e63fc3c78a314424b5d5f613017627bbad83182e8e42bb6fb0c0fe945f12cb6e28ee56794dc180014883267e
7
+ data.tar.gz: cc2846b357694af6e720cdc87d081968625f76870090116d056a7d5ace468bb6077231f5fb8e061b650a4c1fed6ee6e6d14d19c9ffe999d42ec5348d3fc4c3b3
data/README.md CHANGED
@@ -17,6 +17,7 @@ Abraham makes it easy to show guided tours to users of your Rails application. W
17
17
  ## Requirements
18
18
 
19
19
  * Abraham needs to know the current user to track tour views, e.g. `current_user` from Devise.
20
+ * If you are using a different method to identify who is currently logged in, you can, for example, add an alias to make it work. Assuming you have a method `current_foo` to identify your currenly logged-in user, you can add `alias_method 'current_user', 'current_foo'` in the place you define `current_foo`.
20
21
  * Abraham is tested on Rails 5.2, 6.0, and 6.1
21
22
 
22
23
  ## Installation
@@ -78,12 +79,15 @@ Tell Abraham where to insert its generated JavaScript in `app/views/layouts/appl
78
79
 
79
80
  ## Defining your tours
80
81
 
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.
82
+ 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. (As of version 2.4.0, Abraham respects controllers organized into modules.)
82
83
 
83
84
  ```
84
85
  config/
85
86
  └── tours/
86
- └── blog/
87
+ ├── admin/
88
+ │ └── articles/
89
+ │ └── edit.en.yml
90
+ ├── blog/
87
91
  │ ├── show.en.yml
88
92
  │ └── show.es.yml
89
93
  └── articles/
@@ -128,6 +132,8 @@ Abraham takes care of which buttons should appear with each step:
128
132
  * "Exit" and "Next" buttons on intermediate steps
129
133
  * "Done" button on the last step
130
134
 
135
+ See below for how to define custom buttons.
136
+
131
137
  When you specify an `attachTo` element, use the `placement` option to choose where the callout should appear relative to that element:
132
138
 
133
139
  * `bottom` / `bottom center`
@@ -147,7 +153,8 @@ Abraham tries to be helpful when your tour steps attach to page elements that ar
147
153
 
148
154
  ### Automatic vs. manual tours
149
155
 
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:
156
+ By default, Abraham will automatically start a tour that the current user hasn't seen yet.
157
+ You can instead define a tour to be triggered manually using the `trigger` option:
151
158
 
152
159
  ```yml
153
160
  walkthrough:
@@ -177,6 +184,52 @@ This tour will not start automatically; instead, use the `Abraham.startTour` met
177
184
  </script>
178
185
  ```
179
186
 
187
+ ### Custom buttons
188
+
189
+ You can define custom buttons in a step like so:
190
+
191
+ ```
192
+ my_tour:
193
+ steps:
194
+ 1:
195
+ text: "Welcome to my custom button tour"
196
+ buttons:
197
+ 1:
198
+ text: 'Show this to me later'
199
+ action: 'cancel'
200
+ classes: 'custom-button shepherd-button-secondary'
201
+ 2:
202
+ text: 'Finish now'
203
+ action: 'complete'
204
+ classes: 'custom-button'
205
+ ```
206
+
207
+ * `action` is one of the Shepherd tour method names, i.e. `cancel`, `next`, or `complete`
208
+ * `classes` are the CSS class names you want applied to the button
209
+
210
+ ### Flipper integration
211
+
212
+ If you have [Flipper](https://github.com/jnunemaker/flipper) installed as a dependency in your project you will be able to enable or disable tours based on a flipper using the `flipper_key` option. This will automatically enable a tour when this flipper is active and disable it when it's inactive.
213
+
214
+ ```yml
215
+ walkthrough:
216
+ flipper_key: "name_of_flipper"
217
+ steps:
218
+ 1:
219
+ text: "This walkthrough will show you how to..."
220
+ ```
221
+
222
+ If you would like to disable a tour when a flipper is active you may couple the `flipper_key` option with the `flipper_activation` option. `flipper_activation` supports "enabled" or "disabled" as options. If you enter something other than "enabled" or "disabled" it will use the default, which is "enabled".
223
+
224
+ ```yml
225
+ walkthrough:
226
+ flipper_key: "name_of_flipper"
227
+ flipper_activation: "disabled"
228
+ steps:
229
+ 1:
230
+ text: "This walkthrough will show you how to..."
231
+ ```
232
+
180
233
  ### Testing your tours
181
234
 
182
235
  Abraham loads tour definitions once when you start your server. Restart your server to see tour changes.
@@ -193,7 +246,18 @@ end
193
246
 
194
247
  We provide a [small example app](https://github.com/actmd/abraham-example) that implements Abraham, so you can see it in action.
195
248
 
196
- ## Upgrading from version 1
249
+ ## Upgrading
250
+
251
+ ### From version 2.3.0 or earlier
252
+
253
+ Abraham 2.4.0 introduced an updated initializer that supports controllers organized into modules.
254
+ Rerun the generator with these options to replace the old initializer:
255
+
256
+ ```
257
+ $ rails generate abraham:install --skip-migration --skip-config
258
+ ```
259
+
260
+ ### From version 1
197
261
 
198
262
  Abraham v1 was built using Shepherd 1.8, v2 now uses Shepherd 6 – quite a jump, yes.
199
263
 
@@ -249,7 +313,7 @@ gem 'abraham', path: '~/Workspace/abraham'
249
313
 
250
314
  #### Automated testing
251
315
 
252
- We use TravisCI to automatically test this engine with Rails 5.2, 6.0, and 6.1. For test history, venture over to [TravisCI](https://travis-ci.com/actmd/abraham).
316
+ We use GitHub Actions to automatically test this engine with Rails 5.2, 6.0, and 6.1.
253
317
 
254
318
  ### Releasing
255
319
 
@@ -1,17 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AbrahamHelper
4
+ include FlipperHelper
5
+
4
6
  def abraham_tour
5
7
  # Do we have tours for this controller/action in the user's locale?
6
- tours = Rails.configuration.abraham.tours["#{controller_name}.#{action_name}.#{I18n.locale}"]
8
+ tours = Rails.configuration.abraham.tours["#{controller_path}.#{action_name}.#{I18n.locale}"]
7
9
  # Otherwise, default to the default locale
8
- tours ||= Rails.configuration.abraham.tours["#{controller_name}.#{action_name}.#{I18n.default_locale}"]
10
+ tours ||= Rails.configuration.abraham.tours["#{controller_path}.#{action_name}.#{I18n.default_locale}"]
9
11
 
10
12
  if tours
11
13
  # Have any automatic tours been completed already?
12
14
  completed = AbrahamHistory.where(
13
15
  creator_id: current_user.id,
14
- controller_name: controller_name,
16
+ controller_name: controller_path,
15
17
  action_name: action_name
16
18
  )
17
19
 
@@ -21,11 +23,16 @@ module AbrahamHelper
21
23
  tour_html = ''
22
24
 
23
25
  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"] })
26
+ flipper_key = tours[key]["flipper_key"]
27
+ flipper_activation = tours[key]["flipper_activation"]
28
+
29
+ if should_add_tour(flipper_key, flipper_activation)
30
+ tour_html += render(partial: "application/abraham",
31
+ locals: { tour_name: key,
32
+ tour_completed: tour_keys_completed.include?(key),
33
+ trigger: tours[key]["trigger"],
34
+ steps: tours[key]["steps"] })
35
+ end
29
36
  end
30
37
 
31
38
  tour_html.html_safe
@@ -33,7 +40,7 @@ module AbrahamHelper
33
40
  end
34
41
 
35
42
  def abraham_cookie_prefix
36
- "abraham-#{fetch_application_name.to_s.underscore}-#{current_user.id}-#{controller_name}-#{action_name}"
43
+ "abraham-#{fetch_application_name.to_s.underscore}-#{current_user.id}-#{controller_path}-#{action_name}"
37
44
  end
38
45
 
39
46
  def fetch_application_name
@@ -44,7 +51,6 @@ module AbrahamHelper
44
51
  end
45
52
  end
46
53
 
47
-
48
54
  def abraham_domain
49
55
  request.host
50
56
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FlipperHelper
4
+ def should_add_tour(flipper_key, flipper_activation)
5
+ return true if !flipper_defined?
6
+
7
+ case process_activation_option(flipper_activation)
8
+ when "enabled"
9
+ return (flipper_key && Flipper.enabled?(flipper_key.to_sym)) || flipper_key.nil?
10
+ when "disabled"
11
+ return (flipper_key && !Flipper.enabled?(flipper_key.to_sym)) || flipper_key.nil?
12
+ else
13
+ return false
14
+ end
15
+ end
16
+
17
+ private
18
+ def flipper_defined?
19
+ Object.const_defined?("Flipper")
20
+ end
21
+
22
+ def process_activation_option(flipper_activation)
23
+ return "disabled" if flipper_activation == "disabled"
24
+ "enabled"
25
+ end
26
+ end
@@ -9,7 +9,7 @@
9
9
  headers: { 'Content-Type': 'application/json' },
10
10
  body: JSON.stringify({
11
11
  authenticity_token: '<%= form_authenticity_token %>',
12
- controller_name: '<%= controller_name %>',
12
+ controller_name: '<%= controller_path %>',
13
13
  action_name: '<%= action_name %>',
14
14
  tour_name: '<%= tour_name %>'
15
15
  })
@@ -29,22 +29,28 @@
29
29
  <% end %>
30
30
  text: "<%= step['text'] %>",
31
31
  <% if step.key?('attachTo') %>
32
- attachTo: { element: "<%= step['attachTo']['element'] %>", on: "<%= step['attachTo']['placement'] %>" },
32
+ attachTo: { element: "<%= escape_javascript(step['attachTo']['element'].html_safe) %>", on: "<%= step['attachTo']['placement'] %>" },
33
33
  showOn: function() {
34
34
  // Only display this step if its selector is present
35
- return document.querySelector("<%= step['attachTo']['element'] %>") ? true : false
35
+ return document.querySelector("<%= escape_javascript(step['attachTo']['element'].html_safe) %>") ? true : false
36
36
  },
37
37
  <% end %>
38
38
  buttons: [
39
- <% if index == steps.size - 1 %>
40
- { text: '<%= t('abraham.done') %>', action: Abraham.tours["<%= tour_name %>"].complete }
39
+ <% if step.key?('buttons') %>
40
+ <% step['buttons'].each do |button| %>
41
+ { text: '<%= button[1]['text'] %>', action: Abraham.tours["<%= tour_name %>"].<%= button[1]['action'] %>, classes: '<%= button[1]['classes'] %>' },
42
+ <% end %>
41
43
  <% else %>
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 }
44
+ <% if index == steps.size - 1 %>
45
+ { text: '<%= t('abraham.done') %>', action: Abraham.tours["<%= tour_name %>"].complete }
45
46
  <% 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 }
47
+ <% if index == 0 %>
48
+ { text: '<%= t('abraham.later') %>', action: Abraham.tours["<%= tour_name %>"].cancel, classes: 'shepherd-button-secondary' },
49
+ { text: '<%= t('abraham.continue') %>', action: Abraham.tours["<%= tour_name %>"].next }
50
+ <% else %>
51
+ { text: '<%= t('abraham.exit') %>', action: Abraham.tours["<%= tour_name %>"].cancel, classes: 'shepherd-button-secondary' },
52
+ { text: '<%= t('abraham.next') %>', action: Abraham.tours["<%= tour_name %>"].next }
53
+ <% end %>
48
54
  <% end %>
49
55
  <% end %>
50
56
  ]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Abraham
4
- VERSION = "2.3.0.beta"
4
+ VERSION = "2.5.1"
5
5
  end
@@ -10,6 +10,7 @@ module Abraham
10
10
 
11
11
  class_option :'skip-migration', type: :boolean, desc: "Don't generate a migration for the histories table"
12
12
  class_option :'skip-initializer', type: :boolean, desc: "Don't generate an initializer"
13
+ class_option :'skip-config', type: :boolean, desc: "Don't generate a config file"
13
14
 
14
15
  source_root File.expand_path(File.join(File.dirname(__FILE__), "templates"))
15
16
 
@@ -24,6 +25,11 @@ module Abraham
24
25
  return if options["skip-initializer"]
25
26
 
26
27
  copy_file "initializer.rb", "config/initializers/abraham.rb"
28
+ end
29
+
30
+ def create_config
31
+ return if options["skip-config"]
32
+
27
33
  copy_file "abraham.yml", "config/abraham.yml"
28
34
  end
29
35
  end
@@ -2,18 +2,18 @@
2
2
 
3
3
  Rails.application.configure do
4
4
  tours = {}
5
+ tours_root = Pathname.new(Rails.root.join("config/tours"))
5
6
 
6
- if Rails.root.join('config/tours').exist?
7
- Dir[Rails.root.join('config/tours/*/')].each do |dir|
8
- Dir[dir + '*.yml'].each do |yml|
9
- path_parts = yml.split(File::SEPARATOR)
10
- controller = path_parts[path_parts.size - 2]
11
- file_parts = path_parts[path_parts.size - 1].split('.')
12
- action = file_parts[0]
13
- locale = file_parts[1]
14
- t = YAML.load_file(yml)
15
- tours["#{controller}.#{action}.#{locale}"] = t
16
- end
7
+ if Rails.root.join("config/tours").exist?
8
+ Dir.glob(Rails.root.join("config/tours/**/*.yml")).each do |yml|
9
+ relative_filename = Pathname.new(yml).relative_path_from(tours_root)
10
+ # `controller_path` is either "controller_name" or "module_name/controller_name"
11
+ controller_path, filename = relative_filename.split
12
+ file_parts = filename.to_s.split(".")
13
+ action = file_parts[0]
14
+ locale = file_parts[1]
15
+ t = YAML.load_file(yml)
16
+ tours["#{controller_path}.#{action}.#{locale}"] = t
17
17
  end
18
18
  end
19
19
 
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.3.0.beta
4
+ version: 2.5.1
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-21 00:00:00.000000000 Z
11
+ date: 2022-06-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sassc-rails
@@ -96,6 +96,7 @@ files:
96
96
  - app/assets/stylesheets/abraham/theme-default.scss
97
97
  - app/controllers/abraham_histories_controller.rb
98
98
  - app/helpers/abraham_helper.rb
99
+ - app/helpers/flipper_helper.rb
99
100
  - app/models/abraham_history.rb
100
101
  - app/models/application_record.rb
101
102
  - app/views/application/_abraham.html.erb
@@ -126,9 +127,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
126
127
  version: '0'
127
128
  required_rubygems_version: !ruby/object:Gem::Requirement
128
129
  requirements:
129
- - - ">"
130
+ - - ">="
130
131
  - !ruby/object:Gem::Version
131
- version: 1.3.1
132
+ version: '0'
132
133
  requirements: []
133
134
  rubygems_version: 3.0.8
134
135
  signing_key: