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 +4 -4
- data/README.md +69 -5
- data/app/helpers/abraham_helper.rb +16 -10
- data/app/helpers/flipper_helper.rb +26 -0
- data/app/views/application/_abraham.html.erb +16 -10
- data/lib/abraham/version.rb +1 -1
- data/lib/generators/abraham/install_generator.rb +6 -0
- data/lib/generators/abraham/templates/initializer.rb +11 -11
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f58e765abccdc1ca54c84235af22089873e9d3a5de2b4e862a85273f58d56a9
|
4
|
+
data.tar.gz: a8e6aafc28d11ebbb4c593c010d0d5eb5a9b204897394286bd1cdc3a5b4e67ef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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.
|
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
|
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
|
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["#{
|
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["#{
|
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:
|
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
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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}-#{
|
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: '<%=
|
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
|
40
|
-
|
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 ==
|
43
|
-
{ text: '<%= t('abraham.
|
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
|
-
|
47
|
-
|
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
|
]
|
data/lib/abraham/version.rb
CHANGED
@@ -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(
|
7
|
-
Dir
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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.
|
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:
|
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:
|
132
|
+
version: '0'
|
132
133
|
requirements: []
|
133
134
|
rubygems_version: 3.0.8
|
134
135
|
signing_key:
|