Commit d75dc8aeea45cb8603cde9b08456d32d782354ce
1 parent
5db7c221
Exists in
theme-brasil-digital-from-staging
and in
9 other branches
site_tour: set triggers for groups
Showing
13 changed files
with
158 additions
and
53 deletions
Show diff stats
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 < 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 < 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 < 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 %> | ... | ... |