Commit e0543b0270b9802d9bf0f876564ea80e1e58385a

Authored by Joenio Costa
2 parents 76f04045 a58a143f

Merge branch 'rails235' into AI3037-block_filter_user

app/controllers/box_organizer_controller.rb
@@ -80,6 +80,22 @@ class BoxOrganizerController < ApplicationController @@ -80,6 +80,22 @@ class BoxOrganizerController < ApplicationController
80 render :action => 'edit', :layout => false 80 render :action => 'edit', :layout => false
81 end 81 end
82 82
  83 + def search_autocomplete
  84 + if request.xhr? and params[:query]
  85 + search = params[:query]
  86 + path_list = if boxes_holder.is_a?(Environment) && boxes_holder.enabled?('use_portal_community') && boxes_holder.portal_community
  87 + boxes_holder.portal_community.articles.find(:all, :conditions=>"name ILIKE '%#{search}%' or path ILIKE '%#{search}%'", :limit=>20).map { |content| "/{portal}/"+content.path }
  88 + elsif boxes_holder.is_a?(Profile)
  89 + boxes_holder.articles.find(:all, :conditions=>"name ILIKE '%#{search}%' or path ILIKE '%#{search}%'", :limit=>20).map { |content| "/{profile}/"+content.path }
  90 + else
  91 + []
  92 + end
  93 + render :json => path_list.to_json
  94 + else
  95 + redirect_to "/"
  96 + end
  97 + end
  98 +
83 def save 99 def save
84 @block = boxes_holder.blocks.find(params[:id]) 100 @block = boxes_holder.blocks.find(params[:id])
85 @block.update_attributes(params[:block]) 101 @block.update_attributes(params[:block])
app/controllers/public/content_viewer_controller.rb
@@ -111,6 +111,15 @@ class ContentViewerController < ApplicationController @@ -111,6 +111,15 @@ class ContentViewerController < ApplicationController
111 @comments = @plugins.filter(:unavailable_comments, @comments) 111 @comments = @plugins.filter(:unavailable_comments, @comments)
112 @comments_count = @comments.count 112 @comments_count = @comments.count
113 @comments = @comments.without_reply.paginate(:per_page => per_page, :page => params[:comment_page] ) 113 @comments = @comments.without_reply.paginate(:per_page => per_page, :page => params[:comment_page] )
  114 + @comment_order = params[:comment_order].nil? ? 'oldest' : params[:comment_order]
  115 +
  116 + if request.xhr? and params[:comment_order]
  117 + if @comment_order == 'newest'
  118 + @comments = @comments.reverse
  119 + end
  120 +
  121 + return render :partial => 'comment/comment', :collection => @comments
  122 + end
114 123
115 if params[:slideshow] 124 if params[:slideshow]
116 render :action => 'slideshow', :layout => 'slideshow' 125 render :action => 'slideshow', :layout => 'slideshow'
app/controllers/public/events_controller.rb
@@ -7,11 +7,11 @@ class EventsController < PublicController @@ -7,11 +7,11 @@ class EventsController < PublicController
7 @date = build_date(params[:year], params[:month], params[:day]) 7 @date = build_date(params[:year], params[:month], params[:day])
8 8
9 if !params[:year] && !params[:month] && !params[:day] 9 if !params[:year] && !params[:month] && !params[:day]
10 - @events = profile.events.next_events_from_month(@date) 10 + @events = profile.events.next_events_from_month(@date).paginate(:per_page => per_page, :page => params[:page])
11 end 11 end
12 12
13 if params[:year] || params[:month] 13 if params[:year] || params[:month]
14 - @events = profile.events.by_month(@date) 14 + @events = profile.events.by_month(@date).paginate(:per_page => per_page, :page => params[:page])
15 end 15 end
16 16
17 events_in_range = profile.events.by_range((@date - 1.month).at_beginning_of_month .. (@date + 1.month).at_end_of_month) 17 events_in_range = profile.events.by_range((@date - 1.month).at_beginning_of_month .. (@date + 1.month).at_end_of_month)
@@ -29,4 +29,7 @@ class EventsController < PublicController @@ -29,4 +29,7 @@ class EventsController < PublicController
29 29
30 include EventsHelper 30 include EventsHelper
31 31
  32 + def per_page
  33 + 20
  34 + end
32 end 35 end
app/controllers/public/search_controller.rb
@@ -99,14 +99,14 @@ class SearchController < PublicController @@ -99,14 +99,14 @@ class SearchController < PublicController
99 @events = [] 99 @events = []
100 if params[:day] || !params[:year] && !params[:month] 100 if params[:day] || !params[:year] && !params[:month]
101 @events = @category ? 101 @events = @category ?
102 - environment.events.by_day(@date).in_category(Category.find(@category_id)) :  
103 - environment.events.by_day(@date) 102 + environment.events.by_day(@date).in_category(Category.find(@category_id)).paginate(:per_page => per_page, :page => params[:page]) :
  103 + environment.events.by_day(@date).paginate(:per_page => per_page, :page => params[:page])
104 end 104 end
105 105
106 if params[:year] || params[:month] 106 if params[:year] || params[:month]
107 @events = @category ? 107 @events = @category ?
108 - environment.events.by_month(@date).in_category(Category.find(@category_id)) :  
109 - environment.events.by_month(@date) 108 + environment.events.by_month(@date).in_category(Category.find(@category_id)).paginate(:per_page => per_page, :page => params[:page]) :
  109 + environment.events.by_month(@date).paginate(:per_page => per_page, :page => params[:page])
110 end 110 end
111 111
112 @scope = date_range && params[:action] == 'events' ? environment.events.by_range(date_range) : environment.events 112 @scope = date_range && params[:action] == 'events' ? environment.events.by_range(date_range) : environment.events
@@ -139,7 +139,7 @@ class SearchController < PublicController @@ -139,7 +139,7 @@ class SearchController < PublicController
139 139
140 def events_by_day 140 def events_by_day
141 @date = build_date(params[:year], params[:month], params[:day]) 141 @date = build_date(params[:year], params[:month], params[:day])
142 - @events = environment.events.by_day(@date) 142 + @events = environment.events.by_day(@date).paginate(:per_page => per_page, :page => params[:page])
143 render :partial => 'events/events' 143 render :partial => 'events/events'
144 end 144 end
145 145
@@ -224,4 +224,8 @@ class SearchController < PublicController @@ -224,4 +224,8 @@ class SearchController < PublicController
224 @environment.send(klass.name.underscore.pluralize).visible.includes(relations) 224 @environment.send(klass.name.underscore.pluralize).visible.includes(relations)
225 end 225 end
226 226
  227 + def per_page
  228 + 20
  229 + end
  230 +
227 end 231 end
app/helpers/token_helper.rb
@@ -27,7 +27,7 @@ module TokenHelper @@ -27,7 +27,7 @@ module TokenHelper
27 hintText: #{options[:hint_text].to_json}, 27 hintText: #{options[:hint_text].to_json},
28 noResultsText: #{options[:no_results_text].to_json}, 28 noResultsText: #{options[:no_results_text].to_json},
29 searchingText: #{options[:searching_text].to_json}, 29 searchingText: #{options[:searching_text].to_json},
30 - searchDelay: #{options[:serach_delay].to_json}, 30 + searchDelay: #{options[:search_delay].to_json},
31 preventDuplicates: #{options[:prevent_duplicates].to_json}, 31 preventDuplicates: #{options[:prevent_duplicates].to_json},
32 backspaceDeleteItem: #{options[:backspace_delete_item].to_json}, 32 backspaceDeleteItem: #{options[:backspace_delete_item].to_json},
33 queryParam: #{name.to_json}, 33 queryParam: #{name.to_json},
app/models/event.rb
@@ -38,15 +38,12 @@ class Event < Article @@ -38,15 +38,12 @@ class Event < Article
38 named_scope :next_events_from_month, lambda { |date| 38 named_scope :next_events_from_month, lambda { |date|
39 date_temp = date.strftime("%Y-%m-%d") 39 date_temp = date.strftime("%Y-%m-%d")
40 { :conditions => ["start_date >= ?","#{date_temp}"], 40 { :conditions => ["start_date >= ?","#{date_temp}"],
41 - :limit => 10,  
42 :order => 'start_date ASC' 41 :order => 'start_date ASC'
43 } 42 }
44 } 43 }
45 44
46 named_scope :by_month, lambda { |date| 45 named_scope :by_month, lambda { |date|
47 - date_temp = date.strftime("%Y-%m")  
48 { :conditions => ["EXTRACT(YEAR FROM start_date) = ? AND EXTRACT(MONTH FROM start_date) = ?",date.year,date.month], 46 { :conditions => ["EXTRACT(YEAR FROM start_date) = ? AND EXTRACT(MONTH FROM start_date) = ?",date.year,date.month],
49 - :limit => 10,  
50 :order => 'start_date ASC' 47 :order => 'start_date ASC'
51 } 48 }
52 } 49 }
app/models/link_list_block.rb
@@ -70,6 +70,8 @@ class LinkListBlock < Block @@ -70,6 +70,8 @@ class LinkListBlock < Block
70 def expand_address(address) 70 def expand_address(address)
71 add = if owner.respond_to?(:identifier) 71 add = if owner.respond_to?(:identifier)
72 address.gsub('{profile}', owner.identifier) 72 address.gsub('{profile}', owner.identifier)
  73 + elsif owner.is_a?(Environment) && owner.enabled?('use_portal_community') && owner.portal_community
  74 + address.gsub('{portal}', owner.portal_community.identifier)
73 else 75 else
74 address 76 address
75 end 77 end
app/views/box_organizer/_link_list_block.rhtml
  1 +<%= javascript_include_tag "edit-link-list.js" %>
  2 +
1 <strong><%= _('Links') %></strong> 3 <strong><%= _('Links') %></strong>
2 <div id='edit-link-list-block'> 4 <div id='edit-link-list-block'>
3 -<table id='links' class='noborder'>  
4 - <tr>  
5 - <th><%= _('Icon') %></th>  
6 - <th><%= _('Name') %></th>  
7 - <th><%= _('Address') %></th>  
8 - <th><%= _('Title') %></th>  
9 - <th><%= _('Target') %></th>  
10 - </tr>  
11 - <% for link in @block.links do %>  
12 - <tr>  
13 - <td><%= icon_selector(link['icon']) %></td>  
14 - <td><%= text_field_tag 'block[links][][name]', link[:name], :class => 'link-name', :maxlength => 20 %></td>  
15 - <td class='cel-address'><%= text_field_tag 'block[links][][address]', link[:address], :class => 'link-address' %></td>  
16 - <td><%= text_field_tag 'block[links][][title]', link[:title], :class => 'link-title' %></td>  
17 - <td><%= select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, link[:target])) %></td>  
18 - </tr>  
19 - <% end %>  
20 -</table> 5 + <ul class='link-list-header'>
  6 + <li class='link-list-icon'><%= _('Icon') %></li>
  7 + <li class='link-list-name'><%= _('Name') %></li>
  8 + <li class='link-list-address'><%= _('Address') %></li>
  9 + <li class='link-list-target'><%= _('Target') %></li>
  10 + </ul>
  11 + <ul id="dropable-link-list">
  12 + <% for link in @block.links do %>
  13 + <li>
  14 + <ul class="link-list-row">
  15 + <li>
  16 + <%= icon_selector(link['icon']) %>
  17 + </li>
  18 + <li>
  19 + <%= text_field_tag 'block[links][][name]', link[:name], :class => 'link-name', :maxlength => 20 %>
  20 + </li>
  21 + <li>
  22 + <%= text_field_tag 'block[links][][address]', link[:address], :class => 'link-address' %>
  23 + </li>
  24 + <li>
  25 + <%= select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, link[:target])) %>
  26 + </li>
  27 + <li>
  28 + <%= button_without_text(:delete, _('Delete'), "#" , :class=>"delete-link-list-row") %>
  29 + </li>
  30 + </ul>
  31 + </li>
  32 + <% end %>
  33 + </ul>
  34 + <input type="hidden" id="page_url" value="<%=url_for(:action=>'search_autocomplete')%>" />
21 </div> 35 </div>
22 36
23 <%= link_to_function(_('New link'), nil, :class => 'button icon-add with-text') do |page| 37 <%= link_to_function(_('New link'), nil, :class => 'button icon-add with-text') do |page|
24 - page.insert_html :bottom, 'links', content_tag('tr',  
25 - content_tag('td', icon_selector('ok')) +  
26 - content_tag('td', text_field_tag('block[links][][name]', '', :maxlength => 20)) +  
27 - content_tag('td', text_field_tag('block[links][][address]', nil, :class => 'link-address'), :class => 'cel-address') +  
28 - content_tag('td', text_field_tag('block[links][][title]', '', :class => 'link-title')) +  
29 - content_tag('td', select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, '_self'))) 38 + page.insert_html :bottom, 'dropable-link-list', content_tag('li',
  39 + content_tag('ul',
  40 + content_tag('li', icon_selector('ok')) +
  41 + content_tag('li', text_field_tag('block[links][][name]', '', :maxlength => 20)) +
  42 + content_tag('li', text_field_tag('block[links][][address]', nil, :class => 'link-address')) +
  43 + content_tag('li', select_tag('block[links][][target]',
  44 + options_for_select(LinkListBlock::TARGET_OPTIONS, '_self'))) +
  45 + content_tag('li', button_without_text(:delete, _('Delete'), "#" , :class=>"delete-link-list-row")),
  46 + :class=>"link-list-row new_link_row")
30 ) + 47 ) +
31 - javascript_tag("$('edit-link-list-block').scrollTop = $('edit-link-list-block').scrollHeight") 48 + javascript_tag("new_link_action()")
32 end %> 49 end %>
app/views/content_viewer/view_page.rhtml
@@ -80,8 +80,26 @@ @@ -80,8 +80,26 @@
80 </h3> 80 </h3>
81 <% end %> 81 <% end %>
82 82
83 - <% if @page.accept_comments? && @comments.count > 1 %> 83 + <% if @page.accept_comments? && @comments_count > 1 %>
84 <%= link_to(_('Post a comment'), '#', :class => 'display-comment-form', :id => 'top-post-comment-button', :onclick => "jQuery('#page-comment-form .display-comment-form').first().click();") %> 84 <%= link_to(_('Post a comment'), '#', :class => 'display-comment-form', :id => 'top-post-comment-button', :onclick => "jQuery('#page-comment-form .display-comment-form').first().click();") %>
  85 +
  86 + <%= hidden_field_tag("page_url", url_for(:controller=>'content_viewer', :action=>'view_page', :profile=>profile.identifier)) %>
  87 + <%= javascript_include_tag "comment_order.js" %>
  88 + <div class="comment-order">
  89 + <% form_tag({:controller=>'content_viewer' , :action=>'view_page'}, {:method=>'get', :id=>"form_order"}) do %>
  90 + <%= select_tag 'comment_order', options_for_select({_('Oldest first')=>'oldest', _('Newest first')=>'newest'}, @comment_order) %>
  91 + <% end %>
  92 + </div>
  93 + <% end %>
  94 +
  95 + <% if @page.accept_comments? and @comments.count > 1 %>
  96 + <%= hidden_field_tag("page_url", url_for(:controller=>'content_viewer', :action=>'view_page', :profile=>profile.identifier)) %>
  97 + <%= javascript_include_tag "comment_order.js" %>
  98 + <div class="comment-order">
  99 + <% form_tag({:controller=>'content_viewer' , :action=>'view_page'}, {:method=>'get', :id=>"form_order"}) do %>
  100 + <%= select_tag 'comment_order', options_for_select({_('Oldest first')=>'oldest', _('Newest first')=>'newest'}, @comment_order) %>
  101 + <% end %>
  102 + </div>
85 <% end %> 103 <% end %>
86 104
87 <ul class="article-comments-list"> 105 <ul class="article-comments-list">
app/views/events/_events.rhtml
1 -<%= list_events(@date, @events) %>  
2 \ No newline at end of file 1 \ No newline at end of file
  2 +<%= list_events(@date, @events) %>
  3 +
  4 +<%= pagination_links @events, :param_name => 'page' %>
features/comment.feature
@@ -97,3 +97,41 @@ Feature: comment @@ -97,3 +97,41 @@ Feature: comment
97 Given I am on /booking/article-to-comment 97 Given I am on /booking/article-to-comment
98 And I follow "Post a comment" 98 And I follow "Post a comment"
99 Then "Post a comment" should not be visible within "#article" 99 Then "Post a comment" should not be visible within "#article"
  100 +
  101 + @selenium
  102 + Scenario: the newest post from a forum should be displayed first.
  103 + Given the following users
  104 + | login | name |
  105 + | joaosilva | Joao Silva |
  106 + And the following forums
  107 + | owner | name |
  108 + | joaosilva | Forum |
  109 + And the following articles
  110 + | owner | name | parent |
  111 + | joaosilva | Post one | Forum |
  112 + And the following comments
  113 + | article | author | title | body |
  114 + | Post one | joaosilva | Hi all | Hi all |
  115 + | Post one | joaosilva | Hello | Hello |
  116 + When I go to /joaosilva/forum/post-one
  117 + And I select "Newest first" from "comment_order" within ".comment-order"
  118 + Then I should see "Hello" within ".article-comment"
  119 +
  120 + @selenium
  121 + Scenario: the oldest post from a forum should be displayed first.
  122 + Given the following users
  123 + | login | name |
  124 + | joaosilva | Joao Silva |
  125 + And the following forums
  126 + | owner | name |
  127 + | joaosilva | Forum |
  128 + And the following articles
  129 + | owner | name | parent |
  130 + | joaosilva | Post one | Forum |
  131 + And the following comments
  132 + | article | author | title | body |
  133 + | Post one | joaosilva | Hi all | Hi all |
  134 + | Post one | joaosilva | Hello | Hello |
  135 + When I go to /joaosilva/forum/post-one
  136 + And I select "Oldest first" from "comment_order" within ".comment-order"
  137 + Then I should see "Hi all" within ".article-comment"
100 \ No newline at end of file 138 \ No newline at end of file
features/events.feature
@@ -244,3 +244,38 @@ Feature: events @@ -244,3 +244,38 @@ Feature: events
244 Given I am on /profile/josesilva/events/2009/10 244 Given I am on /profile/josesilva/events/2009/10
245 When I follow "Oktoberfest" 245 When I follow "Oktoberfest"
246 Then I should see "Oktoberfest" 246 Then I should see "Oktoberfest"
  247 +
  248 + Scenario: list events paginated for a specific profile for the month
  249 + Given I am logged in as admin
  250 + And the following users
  251 + | login |
  252 + | josemanuel |
  253 + And I am logged in as "josemanuel"
  254 + And the following events
  255 + | owner | name | start_date |
  256 + | josemanuel | Event 5 | 2009-10-12 |
  257 + | josemanuel | Event 3 | 2009-10-15 |
  258 + | josemanuel | Test Event | 2009-10-15 |
  259 + | josemanuel | Oktoberfest | 2009-10-19 |
  260 + | josemanuel | WikiSym | 2009-10-21 |
  261 + | josemanuel | Free Software | 2009-10-22 |
  262 + | josemanuel | Rachel Birthday | 2009-10-23 |
  263 + | josemanuel | Manuel Birthday | 2009-10-24 |
  264 + | josemanuel | Michelle Birthday | 2009-10-25 |
  265 + | josemanuel | Lecture Allien 10 | 2009-10-26 |
  266 + | josemanuel | Lecture Allien 11 | 2009-10-26 |
  267 + | josemanuel | Lecture Allien 12 | 2009-10-26 |
  268 + | josemanuel | Lecture Allien 13 | 2009-10-26 |
  269 + | josemanuel | Lecture Allien 14 | 2009-10-26 |
  270 + | josemanuel | Lecture Allien 15 | 2009-10-26 |
  271 + | josemanuel | Lecture Allien 16 | 2009-10-26 |
  272 + | josemanuel | Lecture Allien 17 | 2009-10-26 |
  273 + | josemanuel | Lecture Allien 18 | 2009-10-26 |
  274 + | josemanuel | Lecture Allien 19 | 2009-10-26 |
  275 + | josemanuel | Lecture Allien 20 | 2009-10-26 |
  276 + | josemanuel | Party On | 2009-10-27 |
  277 +
  278 + When I am on /profile/josemanuel/events/2009/10
  279 + Then I should not see "Party On" within "#agenda-items"
  280 + When I follow "Next"
  281 + Then I should see "Party On" within "#agenda-items"
public/designs/themes/base/style.css
@@ -1275,6 +1275,11 @@ hr.pre-posts, hr.sep-posts { @@ -1275,6 +1275,11 @@ hr.pre-posts, hr.sep-posts {
1275 padding-right: 9px; 1275 padding-right: 9px;
1276 } 1276 }
1277 1277
  1278 +.comment-order {
  1279 + float: right;
  1280 + display: block;
  1281 +}
  1282 +
1278 .comment-from-owner .comment-created-at { 1283 .comment-from-owner .comment-created-at {
1279 color: #333; 1284 color: #333;
1280 } 1285 }
public/images/drag-and-drop.png 0 → 100644

1.11 KB

public/javascripts/application.js
@@ -1101,4 +1101,4 @@ jQuery(document).ready(function(){ @@ -1101,4 +1101,4 @@ jQuery(document).ready(function(){
1101 jQuery("#article_has_terms_of_use").click(function(){ 1101 jQuery("#article_has_terms_of_use").click(function(){
1102 showHideTermsOfUse(); 1102 showHideTermsOfUse();
1103 }); 1103 });
1104 -});  
1105 \ No newline at end of file 1104 \ No newline at end of file
  1105 +});
public/javascripts/comment_order.js 0 → 100644
@@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
  1 +function send_order(order, url) {
  2 + open_loading(DEFAULT_LOADING_MESSAGE);
  3 +
  4 + jQuery.ajax({
  5 + url:url,
  6 + data: {"comment_order":order},
  7 + success: function(response) {
  8 + close_loading();
  9 + jQuery(".article-comments-list").html(response);
  10 + },
  11 + error: function() { close_loading() }
  12 + });
  13 +}
  14 +
  15 +
  16 +jQuery(document).ready(function(){
  17 + jQuery("#comment_order").change(function(){
  18 + var url = jQuery("#page_url").val();
  19 + send_order(this.value, url);
  20 + });
  21 +});
0 \ No newline at end of file 22 \ No newline at end of file
public/javascripts/edit-link-list.js 0 → 100644
@@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
  1 +function send_ajax(source_url) {
  2 + jQuery(".link-address").autocomplete({
  3 + source : function(request, response){
  4 + jQuery.ajax({
  5 + type: "GET",
  6 + url: source_url,
  7 + data: {query: request.term},
  8 + success: function(result){
  9 + response(result);
  10 + },
  11 + error: function(ajax, stat, errorThrown) {
  12 + console.log('Link not found : ' + errorThrown);
  13 + }
  14 + });
  15 + },
  16 +
  17 + minLength: 3
  18 + });
  19 +}
  20 +
  21 +function new_link_action(){
  22 + send_ajax(jQuery("#page_url").val());
  23 +
  24 + jQuery(".delete-link-list-row").click(function(){
  25 + jQuery(this).parent().parent().remove();
  26 + return false;
  27 + });
  28 +
  29 + jQuery(document).scrollTop(jQuery('#dropable-link-list').scrollTop());
  30 +}
  31 +
  32 +jQuery(document).ready(function(){
  33 + new_link_action();
  34 +
  35 + jQuery("#dropable-link-list").sortable({
  36 + revert: true,
  37 + axis: "y"
  38 + });
  39 +});
0 \ No newline at end of file 40 \ No newline at end of file
public/stylesheets/application.css
@@ -1859,20 +1859,70 @@ a.button.disabled, input.disabled { @@ -1859,20 +1859,70 @@ a.button.disabled, input.disabled {
1859 text-decoration: none; 1859 text-decoration: none;
1860 } 1860 }
1861 /* ==> blocks/link-list-block.css <<= */ 1861 /* ==> blocks/link-list-block.css <<= */
1862 -  
1863 #edit-link-list-block { 1862 #edit-link-list-block {
1864 - width: 820px; 1863 + width: 620px;
  1864 + position: relative;
  1865 + left: -24px;
1865 } 1866 }
1866 -  
1867 -#edit-link-list-block table {  
1868 - width: auto;  
1869 - margin-bottom: 10px; 1867 +.link-list-header {
  1868 + width: 98%;
  1869 + height: 25px;
  1870 + padding: 10px 1px 10px 10px;
  1871 + margin-bottom: 5px;
  1872 + cursor: pointer;
1870 } 1873 }
1871 -#edit-link-list-block table .cel-address {  
1872 - width: 220px; 1874 +.link-list-header li {
  1875 + list-style-type: none;
  1876 + display: inline;
  1877 + font-weight: bold;
  1878 + font-size: 14px;
  1879 + text-align: center;
1873 } 1880 }
1874 -#edit-link-list-block table .cel-address input {  
1875 - width: 100%; 1881 +#dropable-link-list {
  1882 + padding-left: 23px;
  1883 + margin-top: -12px;
  1884 +}
  1885 +#dropable-link-list li {
  1886 + list-style-type: none;
  1887 +}
  1888 +.link-list-row {
  1889 + line-height: 25px;
  1890 + margin-bottom: 5px;
  1891 + padding: 10px 1px 10px 10px;
  1892 + cursor: pointer;
  1893 + width: 97%;
  1894 +}
  1895 +.link-list-row:hover {
  1896 + background: #ddd url(/images/drag-and-drop.png) no-repeat;
  1897 + background-position: 98% 15px;
  1898 +}
  1899 +.link-list-row li {
  1900 + list-style-type: none;
  1901 + display: inline;
  1902 + margin-left: 5px;
  1903 +}
  1904 +.link-list-row li div {
  1905 + float: left;
  1906 + margin-top: 4px;
  1907 +}
  1908 +.link-list-row li a {
  1909 + line-height: 27px !important;
  1910 + padding-right: 5px;
  1911 +}
  1912 +.link-list-icon {
  1913 + margin-left: 14px;
  1914 +}
  1915 +.link-list-name {
  1916 + margin-left: 40px;
  1917 +}
  1918 +.link-list-address {
  1919 + margin-left: 90px;
  1920 +}
  1921 +.link-list-target {
  1922 + margin-left: 77px;
  1923 +}
  1924 +.new_link_row li {
  1925 + margin-left: 7px;
1876 } 1926 }
1877 #content .link-list-block { 1927 #content .link-list-block {
1878 padding: 10px 0px 10px 10px; 1928 padding: 10px 0px 10px 10px;
@@ -3561,9 +3611,10 @@ div#article-parent { @@ -3561,9 +3611,10 @@ div#article-parent {
3561 } 3611 }
3562 #agenda .agenda-calendar { 3612 #agenda .agenda-calendar {
3563 width: 50%; 3613 width: 50%;
  3614 + display: inline-block;
3564 } 3615 }
3565 #agenda td, #agenda th { 3616 #agenda td, #agenda th {
3566 - padding: 15px; 3617 + padding: 10px;
3567 padding-right: 0px; 3618 padding-right: 0px;
3568 } 3619 }
3569 #agenda .agenda-calendar .previous-month td, #agenda .agenda-calendar .previous-month th, #agenda .agenda-calendar .next-month td, #agenda .agenda-calendar .next-month th { 3620 #agenda .agenda-calendar .previous-month td, #agenda .agenda-calendar .previous-month th, #agenda .agenda-calendar .next-month td, #agenda .agenda-calendar .next-month th {
@@ -3621,26 +3672,25 @@ div#article-parent { @@ -3621,26 +3672,25 @@ div#article-parent {
3621 vertical-align: middle; 3672 vertical-align: middle;
3622 } 3673 }
3623 #agenda .agenda-calendar .current-month caption { 3674 #agenda .agenda-calendar .current-month caption {
3624 - margin-bottom: 10px; 3675 + margin: 10px 0px;
3625 } 3676 }
3626 #agenda #events-of-the-day { 3677 #agenda #events-of-the-day {
3627 - position: absolute;  
3628 - left: 50%;  
3629 width: 45%; 3678 width: 45%;
3630 - top: 0px;  
3631 height: 100%; 3679 height: 100%;
3632 padding-left: 20px; 3680 padding-left: 20px;
  3681 + display: inline-block;
  3682 + vertical-align: top;
3633 } 3683 }
3634 #agenda #events-of-the-day #agenda-items { 3684 #agenda #events-of-the-day #agenda-items {
3635 display: block; 3685 display: block;
3636 overflow: auto; 3686 overflow: auto;
3637 overflow-x: hidden; 3687 overflow-x: hidden;
3638 - height: 80%; 3688 + height: 250px;
3639 background: white; 3689 background: white;
3640 border: none; 3690 border: none;
3641 } 3691 }
3642 #agenda-toolbar { 3692 #agenda-toolbar {
3643 - float: right; 3693 + text-align: right;
3644 font-variant: normal; 3694 font-variant: normal;
3645 font-weight: normal; 3695 font-weight: normal;
3646 } 3696 }
@@ -3663,6 +3713,9 @@ h1#agenda-title { @@ -3663,6 +3713,9 @@ h1#agenda-title {
3663 display: block; 3713 display: block;
3664 margin-top: 10px; 3714 margin-top: 10px;
3665 } 3715 }
  3716 +#agenda .pagination {
  3717 + margin-top: 15px;
  3718 +}
3666 /* ==> public/stylesheets/controller_favorite_enterprises.css <== */ 3719 /* ==> public/stylesheets/controller_favorite_enterprises.css <== */
3667 3720
3668 /* ==> @import url(manage_contacts_list.css); <== */ 3721 /* ==> @import url(manage_contacts_list.css); <== */
test/functional/environment_design_controller_test.rb
@@ -379,4 +379,38 @@ class EnvironmentDesignControllerTest &lt; ActionController::TestCase @@ -379,4 +379,38 @@ class EnvironmentDesignControllerTest &lt; ActionController::TestCase
379 end 379 end
380 end 380 end
381 381
  382 + should 'return a list of paths from portal related to the words used in the query search' do
  383 + env = Environment.default
  384 + login_as(create_admin_user(env))
  385 + community = fast_create(Community, :environment_id => env)
  386 + env.portal_community = community
  387 + env.enable('use_portal_community')
  388 + env.save
  389 + @controller.stubs(:boxes_holder).returns(env)
  390 + article1 = fast_create(Article, :profile_id => community.id, :name => "Some thing")
  391 + article2 = fast_create(Article, :profile_id => community.id, :name => "Some article")
  392 + article3 = fast_create(Article, :profile_id => community.id, :name => "Not an article")
  393 +
  394 + xhr :get, :search_autocomplete, :query => 'Some'
  395 +
  396 + json_response = ActiveSupport::JSON.decode(@response.body)
  397 +
  398 + assert_response :success
  399 + assert_equal json_response.include?("/{portal}/"+article1.path), true
  400 + assert_equal json_response.include?("/{portal}/"+article2.path), true
  401 + assert_equal json_response.include?("/{portal}/"+article3.path), false
  402 + end
  403 +
  404 + should 'return empty if portal not configured' do
  405 + env = Environment.default
  406 + login_as(create_admin_user(env))
  407 +
  408 + xhr :get, :search_autocomplete, :query => 'Some'
  409 +
  410 + json_response = ActiveSupport::JSON.decode(@response.body)
  411 +
  412 + assert_response :success
  413 + assert_equal json_response, []
  414 + end
  415 +
382 end 416 end
test/functional/events_controller_test.rb
@@ -38,4 +38,12 @@ class EventsControllerTest &lt; ActionController::TestCase @@ -38,4 +38,12 @@ class EventsControllerTest &lt; ActionController::TestCase
38 assert_tag :tag =>'a', :attributes => {:href => "/profile/#{profile.identifier}/events/#{next_month.year}/#{next_month.month}"}, :content => next_month_name 38 assert_tag :tag =>'a', :attributes => {:href => "/profile/#{profile.identifier}/events/#{next_month.year}/#{next_month.month}"}, :content => next_month_name
39 end 39 end
40 40
  41 + should 'see the events paginated' do
  42 + 30.times do |i|
  43 + profile.events << Event.new(:name => "Lesson #{i}", :start_date => Date.today)
  44 + end
  45 + get :events, :profile => profile.identifier
  46 + assert_equal 20, assigns(:events).count
  47 + end
  48 +
41 end 49 end
test/functional/profile_design_controller_test.rb
@@ -325,6 +325,20 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase @@ -325,6 +325,20 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase
325 :descendant => {:tag => 'option', :attributes => {:value => 'except_home_page'}} 325 :descendant => {:tag => 'option', :attributes => {:value => 'except_home_page'}}
326 end 326 end
327 327
  328 + should 'return a list of paths related to the words used in the query search' do
  329 + article1 = fast_create(Article, :profile_id => @profile.id, :name => "Some thing")
  330 + article2 = fast_create(Article, :profile_id => @profile.id, :name => "Some article")
  331 + article3 = fast_create(Article, :profile_id => @profile.id, :name => "Not an article")
  332 +
  333 + xhr :get, :search_autocomplete, :profile => 'designtestuser' , :query => 'Some'
  334 +
  335 + json_response = ActiveSupport::JSON.decode(@response.body)
  336 +
  337 + assert_response :success
  338 + assert_equal json_response.include?("/{profile}/"+article1.path), true
  339 + assert_equal json_response.include?("/{profile}/"+article2.path), true
  340 + assert_equal json_response.include?("/{profile}/"+article3.path), false
  341 + end
328 342
329 ###################################################### 343 ######################################################
330 # END - tests for BoxOrganizerController features 344 # END - tests for BoxOrganizerController features
test/functional/search_controller_test.rb
@@ -370,6 +370,14 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -370,6 +370,14 @@ class SearchControllerTest &lt; ActionController::TestCase
370 assert_equal [ 'upcoming event 1' ], assigns(:searches)[:events][:results].map(&:name) 370 assert_equal [ 'upcoming event 1' ], assigns(:searches)[:events][:results].map(&:name)
371 end 371 end
372 372
  373 + should 'see the events paginated' do
  374 + 30.times do |i|
  375 + create_event(person, :name => "Event #{i}", :start_date => Date.today)
  376 + end
  377 + get :events
  378 + assert_equal 20, assigns(:events).count
  379 + end
  380 +
373 %w[ people enterprises articles events communities products ].each do |asset| 381 %w[ people enterprises articles events communities products ].each do |asset|
374 should "render asset-specific template when searching for #{asset}" do 382 should "render asset-specific template when searching for #{asset}" do
375 get "#{asset}" 383 get "#{asset}"
test/unit/link_list_block_test.rb
@@ -39,6 +39,32 @@ class LinkListBlockTest &lt; ActiveSupport::TestCase @@ -39,6 +39,32 @@ class LinkListBlockTest &lt; ActiveSupport::TestCase
39 assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => '/test_profile/address'} 39 assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => '/test_profile/address'}
40 end 40 end
41 41
  42 + should 'replace {portal} with environment portal identifier' do
  43 + env = Environment.default
  44 + env.enable('use_portal_community')
  45 + portal = fast_create(Community, :identifier => 'portal-community', :environment_id => env.id)
  46 + env.portal_community = portal
  47 + env.save
  48 +
  49 + stubs(:environment).returns(env)
  50 + l = LinkListBlock.new(:links => [{:name => 'categ', :address => '/{portal}/address'}])
  51 + l.stubs(:owner).returns(env)
  52 + assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => '/portal-community/address'}
  53 + end
  54 +
  55 + should 'not change address if no {portal} there' do
  56 + env = Environment.default
  57 + env.enable('use_portal_community')
  58 + portal = fast_create(Community, :identifier => 'portal-community', :environment_id => env.id)
  59 + env.portal_community = portal
  60 + env.save
  61 +
  62 + stubs(:environment).returns(env)
  63 + l = LinkListBlock.new(:links => [{:name => 'categ', :address => '/address'}])
  64 + l.stubs(:owner).returns(env)
  65 + assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => '/address'}
  66 + end
  67 +
42 should 'display options for icons' do 68 should 'display options for icons' do
43 l = LinkListBlock.new 69 l = LinkListBlock.new
44 l.icons_options.each do |option| 70 l.icons_options.each do |option|