abraham 0.1.0
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 +7 -0
- data/README.md +108 -0
- data/Rakefile +34 -0
- data/app/assets/config/abraham_manifest.js +0 -0
- data/app/controllers/abraham_histories_controller.rb +21 -0
- data/app/helpers/abraham_helper.rb +27 -0
- data/app/models/abraham_history.rb +3 -0
- data/app/models/application_record.rb +4 -0
- data/app/views/application/_abraham.html.erb +49 -0
- data/config/locales/en.yml +7 -0
- data/config/locales/es.yml +7 -0
- data/config/routes.rb +4 -0
- data/lib/abraham.rb +5 -0
- data/lib/abraham/engine.rb +9 -0
- data/lib/abraham/version.rb +4 -0
- data/lib/generators/abraham/install_generator.rb +27 -0
- data/lib/generators/abraham/templates/initializer.rb +21 -0
- data/lib/generators/abraham/templates/migration.rb +13 -0
- data/lib/tasks/abraham_tasks.rake +5 -0
- metadata +152 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 798c89c53a20fc5d954a4cee99c150957ff815e7
|
4
|
+
data.tar.gz: 2d6a3652a30b984510758e00fbf3683701b75c13
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2999a0ea6b03b1552d5c5d3acb9a48799c5241b5ab5d0a7b2964594848cb15688e1811a2c973fe119dab2d60e14488cb6731508fe52dbebacd473db40be80ca2
|
7
|
+
data.tar.gz: 3a3beb3fdc9eee073339a2269d783b6f683a22e5b280859ce6ecc28fb652eacee16b010d3e4ecd1f55105662f6e252c42d46193a69ee5129f61087277236503d
|
data/README.md
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
# Abraham
|
2
|
+
|
3
|
+
_Guide your users in the one true path._
|
4
|
+
|
5
|
+

|
6
|
+
|
7
|
+
Abraham injects dynamically-generated [Shepherd.js](http://github.hubspot.com/shepherd/docs/welcome/) 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.
|
8
|
+
|
9
|
+
* Define tour content with simple YAML files, in any/many languages.
|
10
|
+
* Organize tours by controller and action.
|
11
|
+
* Plays nicely with Turbolinks.
|
12
|
+
|
13
|
+
## Requirements
|
14
|
+
|
15
|
+
* devise? (for current_user)
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
Add Abraham to your Gemfile:
|
20
|
+
|
21
|
+
```
|
22
|
+
gem 'abraham'
|
23
|
+
```
|
24
|
+
|
25
|
+
Then run:
|
26
|
+
|
27
|
+
```
|
28
|
+
$ bundle install
|
29
|
+
$ rails generate abraham:install
|
30
|
+
```
|
31
|
+
|
32
|
+
Require Shepherd.js in `app/assets/javascripts/application.js`
|
33
|
+
|
34
|
+
```
|
35
|
+
//= require shepherd.js.js
|
36
|
+
```
|
37
|
+
|
38
|
+
Require a Shepherd.js CSS theme in `app/assets/stylesheets/application.scss`
|
39
|
+
|
40
|
+
```
|
41
|
+
//= require "shepherd.js/dist/css/shepherd-theme-default"
|
42
|
+
```
|
43
|
+
|
44
|
+
Shepherd.js provides the following themes:
|
45
|
+
|
46
|
+
- `shepherd-theme-arrows`
|
47
|
+
- `shepherd-theme-arrows-fix`
|
48
|
+
- `shepherd-theme-arrows-plain-buttons`
|
49
|
+
- `shepherd-theme-dark`
|
50
|
+
- `shepherd-theme-default`
|
51
|
+
- `shepherd-theme-square`
|
52
|
+
- `shepherd-theme-square-dark`
|
53
|
+
|
54
|
+
## Defining your tours
|
55
|
+
|
56
|
+
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.
|
57
|
+
|
58
|
+
```
|
59
|
+
config/
|
60
|
+
└── tours/
|
61
|
+
└── blog/
|
62
|
+
│ ├── show.en.yml
|
63
|
+
│ └── show.es.yml
|
64
|
+
└── articles/
|
65
|
+
├── index.en.yml
|
66
|
+
├── index.es.yml
|
67
|
+
├── show.en.yml
|
68
|
+
└── show.es.yml
|
69
|
+
```
|
70
|
+
|
71
|
+
NB: You must specify a locale in the filename, even if you're only supporting one language.
|
72
|
+
|
73
|
+
### Tour content
|
74
|
+
|
75
|
+
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 to the left, right, top, or bottom.
|
76
|
+
|
77
|
+
```yaml
|
78
|
+
intro:
|
79
|
+
steps:
|
80
|
+
1:
|
81
|
+
text: "Welcome to your dashboard! This is where we'll highlight key information to manage your day."
|
82
|
+
2:
|
83
|
+
title: "Events"
|
84
|
+
text: "If you're participating in any events today, we'll show that here."
|
85
|
+
attachTo:
|
86
|
+
element: ".dashboard-events"
|
87
|
+
placement: "right"
|
88
|
+
3:
|
89
|
+
title: "Search"
|
90
|
+
text: "You can find anything else by using the search bar."
|
91
|
+
attachTo:
|
92
|
+
element: ".navbar-primary form"
|
93
|
+
placement: "bottom"
|
94
|
+
```
|
95
|
+
|
96
|
+
Abraham takes care of which buttons should appear with each step:
|
97
|
+
|
98
|
+
* "Later" and "Continue" buttons on the first step
|
99
|
+
* "Exit" and "Next" buttons on intermediate steps
|
100
|
+
* "Done" button on the last step
|
101
|
+
|
102
|
+
### Testing your tours
|
103
|
+
|
104
|
+
Abraham loads tour definitions once when you start your server. If you'd like to iteratively test changes without restarting your server, use the Rails console to rerun the initializer:
|
105
|
+
|
106
|
+
```
|
107
|
+
???
|
108
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'rdoc/task'
|
9
|
+
|
10
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
11
|
+
rdoc.rdoc_dir = 'rdoc'
|
12
|
+
rdoc.title = 'Abraham'
|
13
|
+
rdoc.options << '--line-numbers'
|
14
|
+
rdoc.rdoc_files.include('README.md')
|
15
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
16
|
+
end
|
17
|
+
|
18
|
+
APP_RAKEFILE = File.expand_path('../test/dummy/Rakefile', __FILE__)
|
19
|
+
load 'rails/tasks/engine.rake'
|
20
|
+
|
21
|
+
load 'rails/tasks/statistics.rake'
|
22
|
+
|
23
|
+
require 'bundler/gem_tasks'
|
24
|
+
|
25
|
+
require 'rake/testtask'
|
26
|
+
|
27
|
+
Rake::TestTask.new(:test) do |t|
|
28
|
+
t.libs << 'lib'
|
29
|
+
t.libs << 'test'
|
30
|
+
t.pattern = 'test/**/*_test.rb'
|
31
|
+
t.verbose = false
|
32
|
+
end
|
33
|
+
|
34
|
+
task default: :test
|
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
class AbrahamHistoriesController < ApplicationController
|
3
|
+
def create
|
4
|
+
@abraham_history = AbrahamHistory.new(abraham_history_params)
|
5
|
+
@abraham_history.creator_id = current_user
|
6
|
+
respond_to do |format|
|
7
|
+
if @abraham_history.save
|
8
|
+
format.json { render json: @abraham_history, status: :created }
|
9
|
+
else
|
10
|
+
format.json { render json: @abraham_history.errors, status: :unprocessable_entity }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
# Never trust parameters from the scary internet, only allow the white list through.
|
18
|
+
def abraham_history_params
|
19
|
+
params.require(:abraham_history).permit(:controller_name, :action_name, :tour_name)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module AbrahamHelper
|
3
|
+
def abraham_tour
|
4
|
+
# Do we have tours for this controller/action in the user's locale?
|
5
|
+
tours = Rails.configuration.abraham.tours["#{controller_name}.#{action_name}.#{I18n.locale}"]
|
6
|
+
|
7
|
+
unless tours
|
8
|
+
# How about the default locale?
|
9
|
+
tours = Rails.configuration.abraham.tours["#{controller_name}.#{action_name}.#{I18n.default_locale}"]
|
10
|
+
end
|
11
|
+
|
12
|
+
if tours
|
13
|
+
completed = AbrahamHistory.where(
|
14
|
+
creator_id: current_user, controller_name: controller_name,
|
15
|
+
action_name: action_name
|
16
|
+
)
|
17
|
+
remaining = tours.keys - completed.map(&:tour_name)
|
18
|
+
|
19
|
+
if remaining.any?
|
20
|
+
# Generate the javascript snippet for the next remaining tour
|
21
|
+
render(partial: 'application/abraham',
|
22
|
+
locals: { tour_name: remaining.first,
|
23
|
+
steps: tours[remaining.first]['steps'] })
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
<script>
|
2
|
+
var tour = new Shepherd.Tour({
|
3
|
+
defaults: {
|
4
|
+
classes: '<%= Rails.configuration.abraham.default_theme %>'
|
5
|
+
}
|
6
|
+
});
|
7
|
+
|
8
|
+
tour.on("complete", function() {
|
9
|
+
// ajax
|
10
|
+
return $.ajax({
|
11
|
+
url: "/abraham_histories/",
|
12
|
+
type: "POST",
|
13
|
+
dataType: "json",
|
14
|
+
contentType: "application/json",
|
15
|
+
data: JSON.stringify({
|
16
|
+
controller_name: '<%= controller_name %>',
|
17
|
+
action_name: '<%= action_name %>',
|
18
|
+
tour_name: '<%= tour_name %>'
|
19
|
+
})
|
20
|
+
});
|
21
|
+
});
|
22
|
+
|
23
|
+
<% steps.each_with_index do |(key, step), index| %>
|
24
|
+
tour.addStep('step-<%= key %>', {
|
25
|
+
<% if step.key?('title') %>
|
26
|
+
title: "<%= step['title'] %>",
|
27
|
+
<% end %>
|
28
|
+
text: "<%= step['text'] %>",
|
29
|
+
<% if step.key?('attachTo') %>
|
30
|
+
attachTo: { element: "<%= step['attachTo']['element'] %>", on: "<%= step['attachTo']['placement'] %>" },
|
31
|
+
<% end %>
|
32
|
+
buttons: [
|
33
|
+
<% if index == 0 %>
|
34
|
+
{ text: '<%= t('abraham.later') %>', action: tour.cancel, classes: 'shepherd-button-secondary' },
|
35
|
+
{ text: '<%= t('abraham.continue') %>', action: tour.next }
|
36
|
+
<% else %>
|
37
|
+
<% if index == steps.size - 1 %>
|
38
|
+
{ text: '<%= t('abraham.done') %>', action: tour.complete }
|
39
|
+
<% else %>
|
40
|
+
{ text: '<%= t('abraham.exit') %>', action: tour.cancel, classes: 'shepherd-button-secondary' },
|
41
|
+
{ text: '<%= t('abraham.next') %>', action: tour.next }
|
42
|
+
<% end %>
|
43
|
+
<% end %>
|
44
|
+
]
|
45
|
+
});
|
46
|
+
<% end %>
|
47
|
+
|
48
|
+
tour.start();
|
49
|
+
</script>
|
data/config/routes.rb
ADDED
data/lib/abraham.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'rails/generators'
|
3
|
+
require 'rails/generators/active_record'
|
4
|
+
|
5
|
+
module Abraham
|
6
|
+
module Generators
|
7
|
+
class InstallGenerator < ActiveRecord::Generators::Base
|
8
|
+
argument :name, type: :string, default: 'random_name'
|
9
|
+
|
10
|
+
class_option :'skip-migration', type: :boolean, desc: "Don't generate a migration for the histories table"
|
11
|
+
class_option :'skip-initializer', type: :boolean, desc: "Don't generate an initializer"
|
12
|
+
|
13
|
+
source_root File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
|
14
|
+
|
15
|
+
# Copies the migration template to db/migrate.
|
16
|
+
def copy_files
|
17
|
+
return if options['skip-migration']
|
18
|
+
migration_template 'migration.rb', 'db/migrate/create_abraham_histories.rb'
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_initializer
|
22
|
+
return if options['skip-initializer']
|
23
|
+
copy_file 'initializer.rb', 'config/initializers/abraham.rb'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
Rails.application.configure do
|
3
|
+
tours = {}
|
4
|
+
|
5
|
+
if Rails.root.join('config/tours').exist?
|
6
|
+
Dir[Rails.root.join('config/tours/*/')].each do |dir|
|
7
|
+
Dir[dir + '*.yml'].each do |yml|
|
8
|
+
path_parts = yml.split(File::SEPARATOR)
|
9
|
+
controller = path_parts[path_parts.size - 2]
|
10
|
+
file_parts = path_parts[path_parts.size - 1].split('.')
|
11
|
+
action = file_parts[0]
|
12
|
+
locale = file_parts[1]
|
13
|
+
t = YAML.load_file(yml)
|
14
|
+
tours["#{controller}.#{action}.#{locale}"] = t
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
config.abraham.default_theme = 'shepherd-theme-default'
|
20
|
+
config.abraham.tours = tours
|
21
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
class CreateAbrahamHistories < ActiveRecord::Migration[5.0]
|
3
|
+
def change
|
4
|
+
create_table :abraham_histories do |t|
|
5
|
+
t.string :controller_name
|
6
|
+
t.string :action_name
|
7
|
+
t.string :tour_name
|
8
|
+
t.references :creator, null: false, index: true
|
9
|
+
|
10
|
+
t.timestamps index: true
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
metadata
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: abraham
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jonathan Abbett
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-11-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 5.0.0
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 5.0.0.1
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 5.0.0
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 5.0.0.1
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: sass-rails
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '5.0'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '5.0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rails-assets-shepherd.js
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.8'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '1.8'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: sqlite3
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: rubocop
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: jquery-rails
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
type: :runtime
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
description: Guide your users in the one true path.
|
104
|
+
email:
|
105
|
+
- jonathan@act.md
|
106
|
+
executables: []
|
107
|
+
extensions: []
|
108
|
+
extra_rdoc_files: []
|
109
|
+
files:
|
110
|
+
- README.md
|
111
|
+
- Rakefile
|
112
|
+
- app/assets/config/abraham_manifest.js
|
113
|
+
- app/controllers/abraham_histories_controller.rb
|
114
|
+
- app/helpers/abraham_helper.rb
|
115
|
+
- app/models/abraham_history.rb
|
116
|
+
- app/models/application_record.rb
|
117
|
+
- app/views/application/_abraham.html.erb
|
118
|
+
- config/locales/en.yml
|
119
|
+
- config/locales/es.yml
|
120
|
+
- config/routes.rb
|
121
|
+
- lib/abraham.rb
|
122
|
+
- lib/abraham/engine.rb
|
123
|
+
- lib/abraham/version.rb
|
124
|
+
- lib/generators/abraham/install_generator.rb
|
125
|
+
- lib/generators/abraham/templates/initializer.rb
|
126
|
+
- lib/generators/abraham/templates/migration.rb
|
127
|
+
- lib/tasks/abraham_tasks.rake
|
128
|
+
homepage: http://getabraham.com
|
129
|
+
licenses:
|
130
|
+
- MIT
|
131
|
+
metadata: {}
|
132
|
+
post_install_message:
|
133
|
+
rdoc_options: []
|
134
|
+
require_paths:
|
135
|
+
- lib
|
136
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
requirements: []
|
147
|
+
rubyforge_project:
|
148
|
+
rubygems_version: 2.6.8
|
149
|
+
signing_key:
|
150
|
+
specification_version: 4
|
151
|
+
summary: Trackable application tours for Rails with i18n support.
|
152
|
+
test_files: []
|