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 10  
11 11 @settings = Noosfero::Plugin::Settings.new(environment, SiteTourPlugin, settings)
12 12 @settings.actions_csv = convert_to_csv(@settings.actions)
  13 + @settings.group_triggers_csv = convert_to_csv(@settings.group_triggers)
13 14  
14 15 if request.post?
15   - @settings.actions = convert_from_csv(settings[:actions_csv])
  16 + @settings.actions = convert_actions_from_csv(settings[:actions_csv])
16 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 22 @settings.save!
19 23 session[:notice] = 'Settings succefully saved.'
20 24 redirect_to :action => 'index'
... ... @@ -25,14 +29,22 @@ class SiteTourPluginAdminController < AdminController
25 29  
26 30 def convert_to_csv(actions)
27 31 CSV.generate do |csv|
28   - (@settings.actions||[]).each { |action| csv << action.values }
  32 + (actions||[]).each { |action| csv << action.values }
29 33 end
30 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 38 CSV.parse(actions_csv).map do |action|
34 39 {:language => action[0], :group_name => action[1], :selector => action[2], :description => action[3]}
35 40 end
36 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 50 end
... ...
plugins/site_tour/lib/site_tour_plugin.rb
... ... @@ -29,7 +29,7 @@ class SiteTourPlugin &lt; Noosfero::Plugin
29 29 settings = Noosfero::Plugin::Settings.new(environment, SiteTourPlugin)
30 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 33 end
34 34 end
35 35  
... ...
plugins/site_tour/lib/site_tour_plugin/tour_block.rb
1 1 class SiteTourPlugin::TourBlock < Block
2 2  
3 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 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 9 before_save do |block|
9 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 12 end
11 13  
12 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 7 margin-top: -12px;
5 8 }
6 9  
7   -#edit-tour-block #droppable-tour-actions li {
  10 +#edit-tour-block .droppable-items li {
8 11 list-style-type: none;
9 12 }
10 13  
11   -#edit-tour-block .action-row {
  14 +#edit-tour-block .item-row {
12 15 line-height: 25px;
13 16 margin-bottom: 5px;
14   - padding: 10px 1px 10px 10px;
  17 + padding: 0;
15 18 cursor: pointer;
16 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 24 background-position: 98% 15px;
22 25 }
23 26  
24   -#edit-tour-block .action-row li {
  27 +#edit-tour-block .item-row li {
25 28 list-style-type: none;
26 29 display: inline;
27 30 margin-left: 5px;
... ... @@ -30,7 +33,6 @@
30 33 #edit-tour-block {
31 34 width: 620px;
32 35 position: relative;
33   - left: -24px;
34 36 }
35 37  
36 38 #edit-tour-block #new-template {
... ... @@ -39,8 +41,7 @@
39 41  
40 42 #edit-tour-block .list-header {
41 43 width: 98%;
42   - height: 25px;
43   - padding: 10px 1px 10px 10px;
  44 + padding: 0 1px 10px 10px;
44 45 margin-bottom: 5px;
45 46 cursor: pointer;
46 47 }
... ... @@ -49,16 +50,16 @@
49 50 list-style-type: none;
50 51 display: inline;
51 52 font-weight: bold;
52   - font-size: 14px;
  53 + font-size: 12px;
53 54 text-align: center;
54 55 }
55 56  
56 57 #edit-tour-block .list-header .list-name {
57   - margin-left: 50px;
  58 + margin-left: 20px;
58 59 }
59 60 #edit-tour-block .list-header .list-selector {
60 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 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 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 10 jQuery(this).parent().parent().remove();
10 11 return false;
11 12 });
12 13  
13   - jQuery("#droppable-tour-actions").sortable({
  14 + jQuery("#edit-tour-block .droppable-items").sortable({
14 15 revert: true,
15 16 axis: "y"
16 17 });
... ...
plugins/site_tour/public/main.js
1 1 var siteTourPlugin = (function() {
2 2  
3 3 var actions = [];
  4 + var groupTriggers = [];
4 5 var userData = {};
  6 + var intro;
5 7  
6 8 function hasMark(name) {
7 9 return jQuery.cookie("_noosfero_.sitetour." + name) ||
... ... @@ -19,7 +21,7 @@ var siteTourPlugin = (function() {
19 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 25 clearAll();
24 26 for(var i=0; i<actions.length; i++) {
25 27 var action = actions[i];
... ... @@ -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 56 return {
42 57 add: function (name, selector, text, step) {
43 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 70 start: function(data, force) {
46   - force = typeof force !== 'undefined' ? force : false;
  71 + force = typeof force !== 'undefined' ? force : false || forceParam();
47 72 userData = data;
48 73  
49   - var intro = introJs();
  74 + intro = introJs();
50 75 intro.onafterchange(function(targetElement) {
51 76 var name = jQuery(targetElement).attr('data-intro-name');
52 77 mark(name);
53 78 });
54   - configureIntro(force);
  79 + configureIntro(force, actionsOnload());
55 80 intro.start();
56 81 },
57 82 force: function() {
... ... @@ -62,6 +87,6 @@ var siteTourPlugin = (function() {
62 87  
63 88 jQuery( document ).ready(function( $ ) {
64 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 17 assert_equal [{:language => 'en', :group_name => 'tour_plugin', :selector => '.tour-button', :description => 'Click'}], @settings.actions
18 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 27 should 'do not store actions_csv' do
21 28 actions_csv = "en,tour_plugin,.tour-button,Click"
22 29 post :index, :settings => {"actions_csv" => actions_csv}
... ... @@ -24,13 +31,29 @@ class SiteTourPluginAdminControllerTest &lt; ActionController::TestCase
24 31 assert_equal nil, @settings.settings[:actions_csv]
25 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 41 should 'convert actions array to csv to enable user edition' do
28 42 @settings = Noosfero::Plugin::Settings.new(environment.reload, SiteTourPlugin)
29 43 @settings.actions = [{:language => 'en', :group_name => 'tour_plugin', :selector => '.tour-button', :description => 'Click'}]
30 44 @settings.save!
31 45  
32 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 57 end
35 58  
36 59 end
... ...
plugins/site_tour/views/blocks/tour.html.erb
... ... @@ -7,5 +7,5 @@
7 7 <% edit_mode = controller.send(:boxes_editor?) && controller.send(:uses_design_blocks?) %>
8 8  
9 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 11 <% end %>
... ...
plugins/site_tour/views/box_organizer/site_tour_plugin/_tour_block.html.erb
... ... @@ -3,23 +3,41 @@
3 3  
4 4 <%= labelled_form_field check_box(:block, :display_button) + _('Display help button'), '' %>
5 5  
6   -<strong><%= _('Actions') %></strong>
7 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 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 @@
  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 1 <li>
2   - <ul class="action-row">
  2 + <ul class="item-row">
3 3 <li>
4 4 <%= text_field_tag 'block[actions][][group_name]', action[:group_name], :class => 'group-name', :maxlength => 20 %>
5 5 </li>
... ... @@ -10,7 +10,7 @@
10 10 <%= text_field_tag 'block[actions][][description]', action[:description], :class => 'description' %>
11 11 </li>
12 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 14 </li>
15 15 </ul>
16 16 </li>
... ...
plugins/site_tour/views/site_tour_plugin_admin/index.html.erb
... ... @@ -3,6 +3,7 @@
3 3 <%= form_for(:settings) do |f| %>
4 4  
5 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 8 <% button_bar do %>
8 9 <%= submit_button(:save, _('Save'), :cancel => {:controller => 'plugins', :action => 'index'}) %>
... ...
plugins/site_tour/views/tour_actions.html.erb
... ... @@ -5,8 +5,13 @@
5 5 <script>
6 6 jQuery( document ).ready(function( $ ) {
7 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 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 16 </script>
12 17 <% end %>
... ...