Compare commits

...

5 Commits

Author SHA1 Message Date
Jonathan Abbett
a587638d8d Final cleanup 2021-06-17 16:21:31 -04:00
Jonathan Abbett
5f7458ff71 Merge branch 'develop' into feature/controller-path 2021-06-17 16:13:33 -04:00
Jonathan Abbett
51419b83ea Clean up initializer 2021-06-17 12:44:34 -04:00
Jonathan Abbett
35875549c5 Readme 2021-06-17 11:31:06 -04:00
Jonathan Abbett
a5c4e8ef71 Support for controller modules (resolves #38) 2021-06-17 11:17:32 -04:00
12 changed files with 84 additions and 46 deletions

View File

@ -1,14 +0,0 @@
language: ruby
env:
- 'RAILS_VERSION=5.2.0'
- 'RAILS_VERSION=6.0.0'
- 'RAILS_VERSION=6.1.0'
before_script:
- 'yarn'
- 'bundle install'
- 'RAILS_ENV=test bundle exec rake db:create'
- 'RAILS_ENV=test bundle exec rake db:migrate'
script: 'RAILS_ENV=test bundle exec rake test'

View File

@ -78,12 +78,15 @@ Tell Abraham where to insert its generated JavaScript in `app/views/layouts/appl
## Defining your tours ## Defining your tours
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. 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.)
``` ```
config/ config/
└── tours/ └── tours/
└── blog/ ├── admin/
│ └── articles/
│ └── edit.en.yml
├── blog/
│ ├── show.en.yml │ ├── show.en.yml
│ └── show.es.yml │ └── show.es.yml
└── articles/ └── articles/
@ -147,7 +150,8 @@ Abraham tries to be helpful when your tour steps attach to page elements that ar
### Automatic vs. manual tours ### Automatic vs. manual tours
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: 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:
```yml ```yml
walkthrough: walkthrough:
@ -193,7 +197,18 @@ end
We provide a [small example app](https://github.com/actmd/abraham-example) that implements Abraham, so you can see it in action. We provide a [small example app](https://github.com/actmd/abraham-example) that implements Abraham, so you can see it in action.
## Upgrading from version 1 ## Upgrading
### From version 2.3.0 or earlier
Abraham 2.4.0 introduced an updated initializer that supports controllers organized into modules.
Rerun the generator with these options to replace the old initializer:
```
$ rails generate abraham:install --skip-migration --skip-config
```
### From version 1
Abraham v1 was built using Shepherd 1.8, v2 now uses Shepherd 6 quite a jump, yes. Abraham v1 was built using Shepherd 1.8, v2 now uses Shepherd 6 quite a jump, yes.
@ -249,7 +264,7 @@ gem 'abraham', path: '~/Workspace/abraham'
#### Automated testing #### Automated testing
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). We use GitHub Actions to automatically test this engine with Rails 5.2, 6.0, and 6.1.
### Releasing ### Releasing

View File

@ -3,15 +3,15 @@
module AbrahamHelper module AbrahamHelper
def abraham_tour def abraham_tour
# Do we have tours for this controller/action in the user's locale? # 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_path}.#{action_name}.#{I18n.locale}"]
# Otherwise, default to the default locale # Otherwise, default to the default locale
tours ||= Rails.configuration.abraham.tours["#{controller_name}.#{action_name}.#{I18n.default_locale}"] tours ||= Rails.configuration.abraham.tours["#{controller_path}.#{action_name}.#{I18n.default_locale}"]
if tours if tours
# Have any automatic tours been completed already? # Have any automatic tours been completed already?
completed = AbrahamHistory.where( completed = AbrahamHistory.where(
creator_id: current_user.id, creator_id: current_user.id,
controller_name: controller_name, controller_name: controller_path,
action_name: action_name action_name: action_name
) )
@ -33,7 +33,7 @@ module AbrahamHelper
end end
def abraham_cookie_prefix def abraham_cookie_prefix
"abraham-#{fetch_application_name.to_s.underscore}-#{current_user.id}-#{controller_name}-#{action_name}" "abraham-#{fetch_application_name.to_s.underscore}-#{current_user.id}-#{controller_path}-#{action_name}"
end end
def fetch_application_name def fetch_application_name
@ -44,7 +44,6 @@ module AbrahamHelper
end end
end end
def abraham_domain def abraham_domain
request.host request.host
end end

View File

@ -9,7 +9,7 @@
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ body: JSON.stringify({
authenticity_token: '<%= form_authenticity_token %>', authenticity_token: '<%= form_authenticity_token %>',
controller_name: '<%= controller_name %>', controller_name: '<%= controller_path %>',
action_name: '<%= action_name %>', action_name: '<%= action_name %>',
tour_name: '<%= tour_name %>' tour_name: '<%= tour_name %>'
}) })

View File

@ -10,6 +10,7 @@ module Abraham
class_option :'skip-migration', type: :boolean, desc: "Don't generate a migration for the histories table" class_option :'skip-migration', type: :boolean, desc: "Don't generate a migration for the histories table"
class_option :'skip-initializer', type: :boolean, desc: "Don't generate an initializer" class_option :'skip-initializer', type: :boolean, desc: "Don't generate an initializer"
class_option :'skip-config', type: :boolean, desc: "Don't generate a config file"
source_root File.expand_path(File.join(File.dirname(__FILE__), "templates")) source_root File.expand_path(File.join(File.dirname(__FILE__), "templates"))
@ -24,6 +25,11 @@ module Abraham
return if options["skip-initializer"] return if options["skip-initializer"]
copy_file "initializer.rb", "config/initializers/abraham.rb" copy_file "initializer.rb", "config/initializers/abraham.rb"
end
def create_config
return if options["skip-config"]
copy_file "abraham.yml", "config/abraham.yml" copy_file "abraham.yml", "config/abraham.yml"
end end
end end

View File

@ -2,18 +2,18 @@
Rails.application.configure do Rails.application.configure do
tours = {} tours = {}
tours_root = Pathname.new(Rails.root.join("config/tours"))
if Rails.root.join('config/tours').exist? if Rails.root.join("config/tours").exist?
Dir[Rails.root.join('config/tours/*/')].each do |dir| Dir.glob(Rails.root.join("config/tours/**/*.yml")).each do |yml|
Dir[dir + '*.yml'].each do |yml| relative_filename = Pathname.new(yml).relative_path_from(tours_root)
path_parts = yml.split(File::SEPARATOR) # `controller_path` is either "controller_name" or "module_name/controller_name"
controller = path_parts[path_parts.size - 2] controller_path, filename = relative_filename.split
file_parts = path_parts[path_parts.size - 1].split('.') file_parts = filename.to_s.split(".")
action = file_parts[0] action = file_parts[0]
locale = file_parts[1] locale = file_parts[1]
t = YAML.load_file(yml) t = YAML.load_file(yml)
tours["#{controller}.#{action}.#{locale}"] = t tours["#{controller_path}.#{action}.#{locale}"] = t
end
end end
end end

View File

@ -0,0 +1,5 @@
# frozen_string_literal: true
class Foobar::DashboardController < ApplicationController
def home; end
end

View File

@ -0,0 +1,4 @@
<h1>Foobar::Dashboard#home</h1>
<p>Find me in app/views/foobar/dashboard/home.html.erb</p>
We should get a unique tour for this module, not the same one as Dashboard#home

View File

@ -2,18 +2,18 @@
Rails.application.configure do Rails.application.configure do
tours = {} tours = {}
tours_root = Pathname.new(Rails.root.join("config/tours"))
if Rails.root.join("config/tours").exist? if Rails.root.join("config/tours").exist?
Dir[Rails.root.join("config/tours/*/")].each do |dir| Dir.glob(Rails.root.join("config/tours/**/*.yml")).each do |yml|
Dir[dir + "*.yml"].each do |yml| relative_filename = Pathname.new(yml).relative_path_from(tours_root)
path_parts = yml.split(File::SEPARATOR) # `controller_path` is either "controller_name" or "module_name/controller_name"
controller = path_parts[path_parts.size - 2] controller_path, filename = relative_filename.split
file_parts = path_parts[path_parts.size - 1].split(".") file_parts = filename.to_s.split(".")
action = file_parts[0] action = file_parts[0]
locale = file_parts[1] locale = file_parts[1]
t = YAML.load_file(yml) t = YAML.load_file(yml)
tours["#{controller}.#{action}.#{locale}"] = t tours["#{controller_path}.#{action}.#{locale}"] = t
end
end end
end end

View File

@ -6,5 +6,9 @@ Rails.application.routes.draw do
get "dashboard/placement" get "dashboard/placement"
get "dashboard/missing" get "dashboard/missing"
namespace :foobar do
get "dashboard/home"
end
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end end

View File

@ -0,0 +1,4 @@
module:
steps:
1:
text: "This tour should appear for the Foobar::DashboardController only"

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
require "test_helper"
class Foobar::DashboardControllerTest < ActionDispatch::IntegrationTest
test "home should have home tour code" do
get foobar_dashboard_home_url
assert_response :success
assert_select "body script" do |element|
# it's the Foobar module home tour
assert element.text.include? "This tour should appear for the Foobar::DashboardController only"
end
end
end