Commit d75dc8aeea45cb8603cde9b08456d32d782354ce

Authored by Victor Costa
1 parent 5db7c221

site_tour: set triggers for groups

plugins/site_tour/controllers/site_tour_plugin_admin_controller.rb
@@ -10,11 +10,15 @@ class SiteTourPluginAdminController < AdminController @@ -10,11 +10,15 @@ class SiteTourPluginAdminController < AdminController
10 10
11 @settings = Noosfero::Plugin::Settings.new(environment, SiteTourPlugin, settings) 11 @settings = Noosfero::Plugin::Settings.new(environment, SiteTourPlugin, settings)
12 @settings.actions_csv = convert_to_csv(@settings.actions) 12 @settings.actions_csv = convert_to_csv(@settings.actions)
  13 + @settings.group_triggers_csv = convert_to_csv(@settings.group_triggers)
13 14
14 if request.post? 15 if request.post?
15 - @settings.actions = convert_from_csv(settings[:actions_csv]) 16 + @settings.actions = convert_actions_from_csv(settings[:actions_csv])
16 @settings.settings.delete(:actions_csv) 17 @settings.settings.delete(:actions_csv)
17 18
  19 + @settings.group_triggers = convert_group_triggers_from_csv(settings[:group_triggers_csv])
  20 + @settings.settings.delete(:group_triggers_csv)
  21 +
18 @settings.save! 22 @settings.save!
19 session[:notice] = 'Settings succefully saved.' 23 session[:notice] = 'Settings succefully saved.'
20 redirect_to :action => 'index' 24 redirect_to :action => 'index'
@@ -25,14 +29,22 @@ class SiteTourPluginAdminController < AdminController @@ -25,14 +29,22 @@ class SiteTourPluginAdminController < AdminController
25 29
26 def convert_to_csv(actions) 30 def convert_to_csv(actions)
27 CSV.generate do |csv| 31 CSV.generate do |csv|
28 - (@settings.actions||[]).each { |action| csv << action.values } 32 + (actions||[]).each { |action| csv << action.values }
29 end 33 end
30 end 34 end
31 35
32 - def convert_from_csv(actions_csv) 36 + def convert_actions_from_csv(actions_csv)
  37 + return [] if actions_csv.blank?
33 CSV.parse(actions_csv).map do |action| 38 CSV.parse(actions_csv).map do |action|
34 {:language => action[0], :group_name => action[1], :selector => action[2], :description => action[3]} 39 {:language => action[0], :group_name => action[1], :selector => action[2], :description => action[3]}
35 end 40 end
36 end 41 end
37 42
  43 + def convert_group_triggers_from_csv(group_triggers_csv)
  44 + return [] if group_triggers_csv.blank?
  45 + CSV.parse(group_triggers_csv).map do |group|
  46 + {:group_name => group[0], :selector => group[1], :event => group[2]}
  47 + end
  48 + end
  49 +
38 end 50 end
plugins/site_tour/lib/site_tour_plugin.rb
@@ -29,7 +29,7 @@ class SiteTourPlugin &lt; Noosfero::Plugin @@ -29,7 +29,7 @@ class SiteTourPlugin &lt; Noosfero::Plugin
29 settings = Noosfero::Plugin::Settings.new(environment, SiteTourPlugin) 29 settings = Noosfero::Plugin::Settings.new(environment, SiteTourPlugin)
30 actions = (settings.actions||[]).select {|action| action[:language] == language} 30 actions = (settings.actions||[]).select {|action| action[:language] == language}
31 31
32 - render(:file => 'tour_actions', :locals => { :actions => actions, :js_file => js_file}) 32 + render(:file => 'tour_actions', :locals => { :actions => actions, :group_triggers => settings.group_triggers, :js_file => js_file})
33 end 33 end
34 end 34 end
35 35
plugins/site_tour/lib/site_tour_plugin/tour_block.rb
1 class SiteTourPlugin::TourBlock < Block 1 class SiteTourPlugin::TourBlock < Block
2 2
3 settings_items :actions, :type => Array, :default => [{:group_name => 'tour_plugin', :selector => '.site-tour-plugin_tour-block .tour-button', :description => _('Click to start tour!')}] 3 settings_items :actions, :type => Array, :default => [{:group_name => 'tour_plugin', :selector => '.site-tour-plugin_tour-block .tour-button', :description => _('Click to start tour!')}]
  4 + settings_items :group_triggers, :type => Array, :default => []
4 settings_items :display_button, :type => :boolean, :default => true 5 settings_items :display_button, :type => :boolean, :default => true
5 6
6 - attr_accessible :actions, :display_button 7 + attr_accessible :actions, :display_button, :group_triggers
7 8
8 before_save do |block| 9 before_save do |block|
9 block.actions.reject! {|i| i[:group_name].blank? && i[:selector].blank? && i[:description].blank?} 10 block.actions.reject! {|i| i[:group_name].blank? && i[:selector].blank? && i[:description].blank?}
  11 + block.group_triggers.reject! {|i| i[:group_name].blank? && i[:selector].blank? && i[:event].blank?}
10 end 12 end
11 13
12 def self.description 14 def self.description
plugins/site_tour/public/edit_tour_block.css
  1 +#edit-tour-block .list-items {
  2 + margin-bottom: 25px;
  3 +}
1 4
2 -#edit-tour-block #droppable-tour-actions {  
3 - padding-left: 23px; 5 +#edit-tour-block .droppable-items {
  6 + padding-left: 0;
4 margin-top: -12px; 7 margin-top: -12px;
5 } 8 }
6 9
7 -#edit-tour-block #droppable-tour-actions li { 10 +#edit-tour-block .droppable-items li {
8 list-style-type: none; 11 list-style-type: none;
9 } 12 }
10 13
11 -#edit-tour-block .action-row { 14 +#edit-tour-block .item-row {
12 line-height: 25px; 15 line-height: 25px;
13 margin-bottom: 5px; 16 margin-bottom: 5px;
14 - padding: 10px 1px 10px 10px; 17 + padding: 0;
15 cursor: pointer; 18 cursor: pointer;
16 width: 97%; 19 width: 97%;
17 } 20 }
18 21
19 -#edit-tour-block .action-row:hover {  
20 - background: #ddd url(../images/drag-and-drop.png) no-repeat; 22 +#edit-tour-block .item-row:hover {
  23 + background: #ddd url(/images/drag-and-drop.png) no-repeat;
21 background-position: 98% 15px; 24 background-position: 98% 15px;
22 } 25 }
23 26
24 -#edit-tour-block .action-row li { 27 +#edit-tour-block .item-row li {
25 list-style-type: none; 28 list-style-type: none;
26 display: inline; 29 display: inline;
27 margin-left: 5px; 30 margin-left: 5px;
@@ -30,7 +33,6 @@ @@ -30,7 +33,6 @@
30 #edit-tour-block { 33 #edit-tour-block {
31 width: 620px; 34 width: 620px;
32 position: relative; 35 position: relative;
33 - left: -24px;  
34 } 36 }
35 37
36 #edit-tour-block #new-template { 38 #edit-tour-block #new-template {
@@ -39,8 +41,7 @@ @@ -39,8 +41,7 @@
39 41
40 #edit-tour-block .list-header { 42 #edit-tour-block .list-header {
41 width: 98%; 43 width: 98%;
42 - height: 25px;  
43 - padding: 10px 1px 10px 10px; 44 + padding: 0 1px 10px 10px;
44 margin-bottom: 5px; 45 margin-bottom: 5px;
45 cursor: pointer; 46 cursor: pointer;
46 } 47 }
@@ -49,16 +50,16 @@ @@ -49,16 +50,16 @@
49 list-style-type: none; 50 list-style-type: none;
50 display: inline; 51 display: inline;
51 font-weight: bold; 52 font-weight: bold;
52 - font-size: 14px; 53 + font-size: 12px;
53 text-align: center; 54 text-align: center;
54 } 55 }
55 56
56 #edit-tour-block .list-header .list-name { 57 #edit-tour-block .list-header .list-name {
57 - margin-left: 50px; 58 + margin-left: 20px;
58 } 59 }
59 #edit-tour-block .list-header .list-selector { 60 #edit-tour-block .list-header .list-selector {
60 margin-left: 63px; 61 margin-left: 63px;
61 } 62 }
62 -#edit-tour-block .list-header .list-description { 63 +#edit-tour-block .list-header .list-description, #edit-tour-block .list-header .list-event {
63 margin-left: 68px; 64 margin-left: 68px;
64 } 65 }
plugins/site_tour/public/edit_tour_block.js
1 -function add_new_action() {  
2 - var new_action = jQuery('#edit-tour-block #new-template>li').clone();  
3 - new_action.show();  
4 - jQuery('#droppable-tour-actions').append(new_action);  
5 -}  
6 -  
7 jQuery(document).ready(function(){ 1 jQuery(document).ready(function(){
8 - jQuery('#edit-tour-block').on('click', '.delete-tour-action-row', function() { 2 + jQuery('#edit-tour-block').on('click', '.add-item', function() {
  3 + var container = jQuery(this).closest('.list-items');
  4 + var new_action = container.find('#new-template>li').clone();
  5 + new_action.show();
  6 + container.find('.droppable-items').append(new_action);
  7 + });
  8 +
  9 + jQuery('#edit-tour-block').on('click', '.delete-tour-block-item', function() {
9 jQuery(this).parent().parent().remove(); 10 jQuery(this).parent().parent().remove();
10 return false; 11 return false;
11 }); 12 });
12 13
13 - jQuery("#droppable-tour-actions").sortable({ 14 + jQuery("#edit-tour-block .droppable-items").sortable({
14 revert: true, 15 revert: true,
15 axis: "y" 16 axis: "y"
16 }); 17 });
plugins/site_tour/public/main.js
1 var siteTourPlugin = (function() { 1 var siteTourPlugin = (function() {
2 2
3 var actions = []; 3 var actions = [];
  4 + var groupTriggers = [];
4 var userData = {}; 5 var userData = {};
  6 + var intro;
5 7
6 function hasMark(name) { 8 function hasMark(name) {
7 return jQuery.cookie("_noosfero_.sitetour." + name) || 9 return jQuery.cookie("_noosfero_.sitetour." + name) ||
@@ -19,7 +21,7 @@ var siteTourPlugin = (function() { @@ -19,7 +21,7 @@ var siteTourPlugin = (function() {
19 jQuery('.site-tour-plugin').removeAttr('data-intro data-intro-name data-step'); 21 jQuery('.site-tour-plugin').removeAttr('data-intro data-intro-name data-step');
20 } 22 }
21 23
22 - function configureIntro(force) { 24 + function configureIntro(force, actions) {
23 clearAll(); 25 clearAll();
24 for(var i=0; i<actions.length; i++) { 26 for(var i=0; i<actions.length; i++) {
25 var action = actions[i]; 27 var action = actions[i];
@@ -38,20 +40,43 @@ var siteTourPlugin = (function() { @@ -38,20 +40,43 @@ var siteTourPlugin = (function() {
38 } 40 }
39 } 41 }
40 42
  43 + function actionsOnload() {
  44 + var groups = jQuery.map(groupTriggers, function(g) { return g.name; });
  45 + return jQuery.grep(actions, function(n, i) { return jQuery.inArray(n.name, groups); });
  46 + }
  47 +
  48 + function actionsByGroup(group) {
  49 + return jQuery.grep(actions, function(n, i) { return n.name===group });
  50 + }
  51 +
  52 + function forceParam() {
  53 + return jQuery.deparam.querystring()['siteTourPlugin']==='force';
  54 + }
  55 +
41 return { 56 return {
42 add: function (name, selector, text, step) { 57 add: function (name, selector, text, step) {
43 actions.push({name: name, selector: selector, text: text, step: step}); 58 actions.push({name: name, selector: selector, text: text, step: step});
44 }, 59 },
  60 + addGroupTrigger: function(name, selector, ev) {
  61 + groupTriggers.push({name: name, selector: selector, event: ev});
  62 + plugin = this;
  63 + var handler = function() {
  64 + configureIntro(forceParam(), actionsByGroup(name));
  65 + intro.start();
  66 + jQuery(document).off(ev, selector, handler);
  67 + };
  68 + jQuery(document).on(ev, selector, handler);
  69 + },
45 start: function(data, force) { 70 start: function(data, force) {
46 - force = typeof force !== 'undefined' ? force : false; 71 + force = typeof force !== 'undefined' ? force : false || forceParam();
47 userData = data; 72 userData = data;
48 73
49 - var intro = introJs(); 74 + intro = introJs();
50 intro.onafterchange(function(targetElement) { 75 intro.onafterchange(function(targetElement) {
51 var name = jQuery(targetElement).attr('data-intro-name'); 76 var name = jQuery(targetElement).attr('data-intro-name');
52 mark(name); 77 mark(name);
53 }); 78 });
54 - configureIntro(force); 79 + configureIntro(force, actionsOnload());
55 intro.start(); 80 intro.start();
56 }, 81 },
57 force: function() { 82 force: function() {
@@ -62,6 +87,6 @@ var siteTourPlugin = (function() { @@ -62,6 +87,6 @@ var siteTourPlugin = (function() {
62 87
63 jQuery( document ).ready(function( $ ) { 88 jQuery( document ).ready(function( $ ) {
64 $(window).bind('userDataLoaded', function(event, data) { 89 $(window).bind('userDataLoaded', function(event, data) {
65 - siteTourPlugin.start(data, jQuery.deparam.querystring()['siteTourPlugin']==='force'); 90 + siteTourPlugin.start(data);
66 }); 91 });
67 }); 92 });
plugins/site_tour/test/functional/site_tour_plugin_admin_controller_test.rb
@@ -17,6 +17,13 @@ class SiteTourPluginAdminControllerTest &lt; ActionController::TestCase @@ -17,6 +17,13 @@ class SiteTourPluginAdminControllerTest &lt; ActionController::TestCase
17 assert_equal [{:language => 'en', :group_name => 'tour_plugin', :selector => '.tour-button', :description => 'Click'}], @settings.actions 17 assert_equal [{:language => 'en', :group_name => 'tour_plugin', :selector => '.tour-button', :description => 'Click'}], @settings.actions
18 end 18 end
19 19
  20 + should 'parse csv and save group triggers array in plugin settings' do
  21 + group_triggers_csv = "tour_plugin,.tour-button,mouseenter"
  22 + post :index, :settings => {"group_triggers_csv" => group_triggers_csv}
  23 + @settings = Noosfero::Plugin::Settings.new(environment.reload, SiteTourPlugin)
  24 + assert_equal [{:group_name => 'tour_plugin', :selector => '.tour-button', :event => 'mouseenter'}], @settings.group_triggers
  25 + end
  26 +
20 should 'do not store actions_csv' do 27 should 'do not store actions_csv' do
21 actions_csv = "en,tour_plugin,.tour-button,Click" 28 actions_csv = "en,tour_plugin,.tour-button,Click"
22 post :index, :settings => {"actions_csv" => actions_csv} 29 post :index, :settings => {"actions_csv" => actions_csv}
@@ -24,13 +31,29 @@ class SiteTourPluginAdminControllerTest &lt; ActionController::TestCase @@ -24,13 +31,29 @@ class SiteTourPluginAdminControllerTest &lt; ActionController::TestCase
24 assert_equal nil, @settings.settings[:actions_csv] 31 assert_equal nil, @settings.settings[:actions_csv]
25 end 32 end
26 33
  34 + should 'do not store group_triggers_csv' do
  35 + group_triggers_csv = "tour_plugin,.tour-button,click"
  36 + post :index, :settings => {"group_triggers_csv" => group_triggers_csv}
  37 + @settings = Noosfero::Plugin::Settings.new(environment.reload, SiteTourPlugin)
  38 + assert_equal nil, @settings.settings[:group_triggers_csv]
  39 + end
  40 +
27 should 'convert actions array to csv to enable user edition' do 41 should 'convert actions array to csv to enable user edition' do
28 @settings = Noosfero::Plugin::Settings.new(environment.reload, SiteTourPlugin) 42 @settings = Noosfero::Plugin::Settings.new(environment.reload, SiteTourPlugin)
29 @settings.actions = [{:language => 'en', :group_name => 'tour_plugin', :selector => '.tour-button', :description => 'Click'}] 43 @settings.actions = [{:language => 'en', :group_name => 'tour_plugin', :selector => '.tour-button', :description => 'Click'}]
30 @settings.save! 44 @settings.save!
31 45
32 get :index 46 get :index
33 - assert_tag :tag => 'textarea', :content => "\nen,tour_plugin,.tour-button,Click\n" 47 + assert_tag :tag => 'textarea', :attributes => {:class => 'actions-csv'}, :content => "\nen,tour_plugin,.tour-button,Click\n"
  48 + end
  49 +
  50 + should 'convert group_triggers array to csv to enable user edition' do
  51 + @settings = Noosfero::Plugin::Settings.new(environment.reload, SiteTourPlugin)
  52 + @settings.group_triggers = [{:group_name => 'tour_plugin', :selector => '.tour-button', :event => 'click'}]
  53 + @settings.save!
  54 +
  55 + get :index
  56 + assert_tag :tag => 'textarea', :attributes => {:class => 'groups-csv'}, :content => "\ntour_plugin,.tour-button,click\n"
34 end 57 end
35 58
36 end 59 end
plugins/site_tour/views/blocks/tour.html.erb
@@ -7,5 +7,5 @@ @@ -7,5 +7,5 @@
7 <% edit_mode = controller.send(:boxes_editor?) && controller.send(:uses_design_blocks?) %> 7 <% edit_mode = controller.send(:boxes_editor?) && controller.send(:uses_design_blocks?) %>
8 8
9 <% unless edit_mode %> 9 <% unless edit_mode %>
10 - <%= render :file => 'tour_actions', :locals => {:actions => block.actions} %> 10 + <%= render :file => 'tour_actions', :locals => {:actions => block.actions, :group_triggers => block.group_triggers} %>
11 <% end %> 11 <% end %>
plugins/site_tour/views/box_organizer/site_tour_plugin/_tour_block.html.erb
@@ -3,23 +3,41 @@ @@ -3,23 +3,41 @@
3 3
4 <%= labelled_form_field check_box(:block, :display_button) + _('Display help button'), '' %> 4 <%= labelled_form_field check_box(:block, :display_button) + _('Display help button'), '' %>
5 5
6 -<strong><%= _('Actions') %></strong>  
7 <div id='edit-tour-block'> 6 <div id='edit-tour-block'>
8 - <ul class='list-header'>  
9 - <li class='list-name'><%= _('Group Name') %></li>  
10 - <li class='list-selector'><%= _('Selector') %></li>  
11 - <li class='list-description'><%= _('Description') %></li>  
12 - </ul>  
13 - <ul id="droppable-tour-actions">  
14 - <% for action in @block.actions do %>  
15 - <%= render :partial => 'box_organizer/site_tour_plugin/tour_block_item', :locals => {:action => action} %>  
16 - <% end %>  
17 - </ul> 7 + <div id="tooltip-actions" class="list-items">
  8 + <h3><%= _('Tooltip Actions') %></h3>
  9 + <ul class='list-header'>
  10 + <li class='list-name'><%= _('Group Name') %></li>
  11 + <li class='list-selector'><%= _('Selector') %></li>
  12 + <li class='list-description'><%= _('Description') %></li>
  13 + </ul>
  14 + <ul id="droppable-tour-actions" class="droppable-items">
  15 + <% for action in @block.actions do %>
  16 + <%= render :partial => 'box_organizer/site_tour_plugin/tour_block_item', :locals => {:action => action} %>
  17 + <% end %>
  18 + </ul>
  19 + <div id="new-template">
  20 + <%= render :partial => 'box_organizer/site_tour_plugin/tour_block_item', :locals => {:action => {} } %>
  21 + </div>
  22 + <%= link_to_function(_('New Tooltip'), :class => 'add-item button icon-add with-text') %>
  23 + </div>
18 24
19 - <div id="new-template">  
20 - <% template_action = {} %>  
21 - <%= render :partial => 'box_organizer/site_tour_plugin/tour_block_item', :locals => {:action => template_action} %> 25 + <div id="group-triggers" class="list-items">
  26 + <h3><%= _('Group Triggers') %></h3>
  27 + <ul class='list-header'>
  28 + <li class='list-name'><%= _('Group Name') %></li>
  29 + <li class='list-selector'><%= _('Selector') %></li>
  30 + <li class='list-event'><%= _('Event') %></li>
  31 + </ul>
  32 + <ul id="droppable-tour-group-triggers" class="droppable-items">
  33 + <% for group in @block.group_triggers do %>
  34 + <%= render :partial => 'box_organizer/site_tour_plugin/tour_block_group_item', :locals => {:group => group} %>
  35 + <% end %>
  36 + </ul>
  37 + <div id="new-template">
  38 + <%= render :partial => 'box_organizer/site_tour_plugin/tour_block_group_item', :locals => {:group => {} } %>
  39 + </div>
  40 + <%= link_to_function(_('New Group Trigger'), :class => 'add-item button icon-add with-text') %>
22 </div> 41 </div>
23 -</div>  
24 42
25 -<%= link_to_function(_('New'), 'add_new_action();', :class => 'button icon-add with-text') %> 43 +</div>
plugins/site_tour/views/box_organizer/site_tour_plugin/_tour_block_group_item.html.erb 0 → 100644
@@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
  1 +<li>
  2 + <ul class="item-row">
  3 + <li>
  4 + <%= text_field_tag 'block[group_triggers][][group_name]', group[:group_name], :class => 'group-name', :maxlength => 20 %>
  5 + </li>
  6 + <li>
  7 + <%= text_field_tag 'block[group_triggers][][selector]', group[:selector], :class => 'selector' %>
  8 + </li>
  9 + <li>
  10 + <%= text_field_tag 'block[group_triggers][][event]', group[:event], :class => 'description' %>
  11 + </li>
  12 + <li>
  13 + <%= button_without_text(:delete, _('Delete'), "#" , :class=>"delete-tour-block-item") %>
  14 + </li>
  15 + </ul>
  16 +</li>
  17 +
plugins/site_tour/views/box_organizer/site_tour_plugin/_tour_block_item.html.erb
1 <li> 1 <li>
2 - <ul class="action-row"> 2 + <ul class="item-row">
3 <li> 3 <li>
4 <%= text_field_tag 'block[actions][][group_name]', action[:group_name], :class => 'group-name', :maxlength => 20 %> 4 <%= text_field_tag 'block[actions][][group_name]', action[:group_name], :class => 'group-name', :maxlength => 20 %>
5 </li> 5 </li>
@@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
10 <%= text_field_tag 'block[actions][][description]', action[:description], :class => 'description' %> 10 <%= text_field_tag 'block[actions][][description]', action[:description], :class => 'description' %>
11 </li> 11 </li>
12 <li> 12 <li>
13 - <%= button_without_text(:delete, _('Delete'), "#" , :class=>"delete-tour-action-row") %> 13 + <%= button_without_text(:delete, _('Delete'), "#" , :class=>"delete-tour-block-item") %>
14 </li> 14 </li>
15 </ul> 15 </ul>
16 </li> 16 </li>
plugins/site_tour/views/site_tour_plugin_admin/index.html.erb
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 <%= form_for(:settings) do |f| %> 3 <%= form_for(:settings) do |f| %>
4 4
5 <%= labelled_form_field _('Tooltips (CSV format: language, group name, selector, description)'), f.text_area(:actions_csv, :style => 'width: 100%', :class => 'actions-csv') %> 5 <%= labelled_form_field _('Tooltips (CSV format: language, group name, selector, description)'), f.text_area(:actions_csv, :style => 'width: 100%', :class => 'actions-csv') %>
  6 + <%= labelled_form_field _('Group Triggers (CSV format: group name, selector, event (e.g. mouseenter, click))'), f.text_area(:group_triggers_csv, :style => 'width: 100%', :class => 'groups-csv', :rows => 7) %>
6 7
7 <% button_bar do %> 8 <% button_bar do %>
8 <%= submit_button(:save, _('Save'), :cancel => {:controller => 'plugins', :action => 'index'}) %> 9 <%= submit_button(:save, _('Save'), :cancel => {:controller => 'plugins', :action => 'index'}) %>
plugins/site_tour/views/tour_actions.html.erb
@@ -5,8 +5,13 @@ @@ -5,8 +5,13 @@
5 <script> 5 <script>
6 jQuery( document ).ready(function( $ ) { 6 jQuery( document ).ready(function( $ ) {
7 <% actions.each_with_index do |action, index| %> 7 <% actions.each_with_index do |action, index| %>
8 - <%= "siteTourPlugin.add('#{j action[:group_name]}','#{j action[:selector]}', '#{j action[:description]}', #{index + 1});" %> 8 + <%= "siteTourPlugin.add('#{j action[:group_name]}', '#{j action[:selector]}', '#{j action[:description]}', #{index + 1});" %>
9 <% end %> 9 <% end %>
  10 +
  11 + <% (group_triggers||[]).each_with_index do |group, index| %>
  12 + <%= "siteTourPlugin.addGroupTrigger('#{j group[:group_name]}', '#{j group[:selector]}', '#{j group[:event]}');" %>
  13 + <% end %>
  14 +
10 }); 15 });
11 </script> 16 </script>
12 <% end %> 17 <% end %>