Commit 1b944f750931d2865b7b24577f761f24f16fdd69

Authored by Daniela Feitosa
Committed by Antonio Terceiro
1 parent 868f9ba4

Added pagination to cms and to public view of folder

(ActionItem1689)
app/controllers/my_profile/cms_controller.rb
@@ -61,17 +61,24 @@ class CmsController < MyProfileController @@ -61,17 +61,24 @@ class CmsController < MyProfileController
61 61
62 def view 62 def view
63 @article = profile.articles.find(params[:id]) 63 @article = profile.articles.find(params[:id])
64 - @subitems = @article.children.reject {|item| item.folder? } 64 + conditions = []
65 if @article.blog? 65 if @article.blog?
66 - @subitems.reject! {|item| item.class == RssFeed } 66 + conditions = ['type != ?', 'RssFeed']
67 end 67 end
68 - @folders = @article.children.select {|item| item.folder? } 68 +
  69 + @articles = @article.children.find(
  70 + :all,
  71 + :order => "case when type = 'Folder' then 0 when type ='Blog' then 1 else 2 end, updated_at DESC",
  72 + :conditions => conditions
  73 + ).paginate(:per_page => per_page, :page => params[:npage])
69 end 74 end
70 75
71 def index 76 def index
72 @article = nil 77 @article = nil
73 - @subitems = profile.top_level_articles.reject {|item| item.folder? }  
74 - @folders = profile.top_level_articles.select {|item| item.folder?} 78 + @articles = profile.top_level_articles.find(
  79 + :all,
  80 + :order => "case when type = 'Folder' then 0 when type ='Blog' then 1 else 2 end, updated_at DESC"
  81 + ).paginate(:per_page => per_page, :page => params[:npage])
75 render :action => 'view' 82 render :action => 'view'
76 end 83 end
77 84
app/helpers/cms_helper.rb
@@ -27,4 +27,30 @@ module CmsHelper @@ -27,4 +27,30 @@ module CmsHelper
27 article_helper.custom_options_for_article(article) 27 article_helper.custom_options_for_article(article)
28 end 28 end
29 29
  30 + def link_to_article(article)
  31 + article_name = short_filename(article.name, 30)
  32 + if article.folder?
  33 + link_to article_name, :action => 'view', :id => article.id
  34 + else
  35 + link_to article_name, article.url
  36 + end
  37 + end
  38 +
  39 + def display_spread_button(profile, article)
  40 + if profile.person?
  41 + button_without_text :spread, _('Spread this'), :action => 'publish', :id => article.id
  42 + elsif profile.community? && environment.portal_community
  43 + button_without_text :spread, _('Spread this'), :action => 'publish_on_portal_community', :id => article.id
  44 + end
  45 + end
  46 +
  47 + def display_delete_button(article)
  48 + confirm_message = if article.folder?
  49 + _('Are you sure that you want to remove this folder? Note that all the items inside it will also be removed!')
  50 + else
  51 + _('Are you sure that you want to remove this item?')
  52 + end
  53 +
  54 + button_without_text :delete, _('Delete'), { :action => 'destroy', :id => article.id }, :method => :post, :confirm => confirm_message
  55 + end
30 end 56 end
app/helpers/folder_helper.rb
@@ -4,11 +4,12 @@ module FolderHelper @@ -4,11 +4,12 @@ module FolderHelper
4 4
5 def list_articles(articles, recursive = false) 5 def list_articles(articles, recursive = false)
6 if !articles.blank? 6 if !articles.blank?
7 - content_tag(  
8 - 'table',  
9 - content_tag('tr', content_tag('th', _('Title')) + content_tag('th', _('Last update'))) +  
10 - articles.sort_by { |article| article.updated_at }.reverse.map {|item| display_article_in_listing(item, recursive, 0)}.join('')  
11 - ) 7 + articles = articles.find(
  8 + :all,
  9 + :order => "updated_at DESC"
  10 + ).paginate(:per_page => 10, :page => params[:npage])
  11 +
  12 + render :file => 'shared/articles_list', :locals => {:articles => articles, :recursive => recursive}
12 else 13 else
13 content_tag('em', _('(empty folder)')) 14 content_tag('em', _('(empty folder)'))
14 end 15 end
app/models/article.rb
@@ -110,9 +110,9 @@ class Article < ActiveRecord::Base @@ -110,9 +110,9 @@ class Article < ActiveRecord::Base
110 110
111 # retrieves all articles belonging to the given +profile+ that are not 111 # retrieves all articles belonging to the given +profile+ that are not
112 # sub-articles of any other article. 112 # sub-articles of any other article.
113 - def self.top_level_for(profile)  
114 - self.find(:all, :conditions => [ 'parent_id is null and profile_id = ?', profile.id ])  
115 - end 113 + named_scope :top_level_for, lambda { |profile|
  114 + {:conditions => [ 'parent_id is null and profile_id = ?', profile.id ]}
  115 + }
116 116
117 # retrieves the latest +limit+ articles, sorted from the most recent to the 117 # retrieves the latest +limit+ articles, sorted from the most recent to the
118 # oldest. 118 # oldest.
app/views/cms/view.rhtml
@@ -46,51 +46,27 @@ @@ -46,51 +46,27 @@
46 </tr> 46 </tr>
47 <% end %> 47 <% end %>
48 48
49 - <%# folders %>  
50 - <% for folder in @folders %> 49 + <% @articles.each do |article| %>
51 <tr> 50 <tr>
52 <td> 51 <td>
53 - <%= image_tag(icon_for_article(folder)) %>  
54 - <%= link_to folder.name, :action => 'view', :id => folder.id %> 52 + <%= image_tag(icon_for_article(article)) %>
  53 + <%= link_to_article(article) %>
55 </td> 54 </td>
56 <td> 55 <td>
57 - <%= folder.class.short_description %> 56 + <%= article.class.short_description %>
58 </td> 57 </td>
59 <td class="article-controls"> 58 <td class="article-controls">
60 - <%= button_without_text :edit, _('Properties'), :action => 'edit', :id => folder.id %>  
61 - <%= button_without_text :eyes, _('Public view'), folder.url %> 59 + <%= button_without_text :edit, _('Edit'), :action => 'edit', :id => article.id %>
  60 + <%= button_without_text :eyes, _('Public view'), article.url %>
  61 + <%= display_spread_button(profile, article) unless article.folder? %>
62 <% if !environment.enabled?('cant_change_homepage') %> 62 <% if !environment.enabled?('cant_change_homepage') %>
63 - <%= button_without_text :home, _('Use as homepage'), { :action => 'set_home_page', :id => folder.id }, :method => :post %> 63 + <%= button_without_text :home, _('Use as homepage'), { :action => 'set_home_page', :id => article.id }, :method => :post %>
64 <% end %> 64 <% end %>
65 - <%= button_without_text :delete, _('Delete'), { :action => 'destroy', :id => folder.id }, :method => :post, :confirm => _('Are you sure that you want to remove this folder? Note that all the items inside it will also be removed!') %>  
66 - </td>  
67 - </tr>  
68 - <% end %>  
69 -  
70 - <%# non-folder subitems %>  
71 - <% for item in @subitems %>  
72 - <tr>  
73 - <td>  
74 - <%= image_tag(icon_for_article(item)) %>  
75 - <%= link_to short_filename(item.name,30), item.url %>  
76 - </td>  
77 - <td>  
78 - <%= item.class.short_description %>  
79 - </td>  
80 - <td class="article-controls">  
81 - <%= button_without_text :edit, _('Edit'), :action => 'edit', :id => item.id %>  
82 - <%= button_without_text :eyes, _('Public view'), item.url %>  
83 - <% if profile.person? %>  
84 - <%= button_without_text :spread, _('Spread this'), :action => 'publish', :id => item.id %>  
85 - <% elsif profile.community? && environment.portal_community %>  
86 - <%= button_without_text :spread, _('Spread this'), :action => 'publish_on_portal_community', :id => item.id %>  
87 - <% end %>  
88 - <% if !environment.enabled?('cant_change_homepage') %>  
89 - <%= button_without_text :home, _('Use as homepage'), { :action => 'set_home_page', :id => item.id }, :method => :post %>  
90 - <% end %>  
91 - <%= button_without_text :delete, _('Delete'), { :action => 'destroy', :id => item.id }, :method => :post, :confirm => _('Are you sure that you want to remove this item?') %> 65 + <%= display_delete_button(article) %>
92 </td> 66 </td>
93 </tr> 67 </tr>
94 <% end %> 68 <% end %>
95 69
96 </table> 70 </table>
  71 +
  72 +<%= pagination_links @articles, {:param_name => 'npage', :prev_label => '&laquo; ' + _('Previous'), :next_label => _('Next') + ' &raquo;', :page_links => true} %>
app/views/content_viewer/folder.rhtml
@@ -8,5 +8,5 @@ @@ -8,5 +8,5 @@
8 <% if folder.children.empty? %> 8 <% if folder.children.empty? %>
9 <em><%= _('(empty folder)') %></em> 9 <em><%= _('(empty folder)') %></em>
10 <% else %> 10 <% else %>
11 - <%= list_articles(available_articles(folder.children, user)) %> 11 + <%= list_articles(folder.children) %>
12 <% end %> 12 <% end %>
app/views/shared/articles_list.rhtml 0 → 100644
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
  1 +<table>
  2 +
  3 + <tr>
  4 + <th><%= _('Title') %></th>
  5 + <th><%= _('Last update') %></th>
  6 + </tr>
  7 + <% articles.each do |article| %>
  8 + <% if article.display_to?(user) %>
  9 + <%= display_article_in_listing(article, recursive, 0) %>
  10 + <% end %>
  11 + <% end %>
  12 +</table>
  13 +
  14 +<p><%= pagination_links(articles, {:param_name => 'npage', :prev_label => '&laquo; ' + _('Previous'), :next_label => _('Next') + ' &raquo;', :page_links => true}) %></p>
test/functional/cms_controller_test.rb
@@ -34,7 +34,7 @@ class CmsControllerTest &lt; Test::Unit::TestCase @@ -34,7 +34,7 @@ class CmsControllerTest &lt; Test::Unit::TestCase
34 assert_template 'view' 34 assert_template 'view'
35 assert_equal profile, assigns(:profile) 35 assert_equal profile, assigns(:profile)
36 assert_nil assigns(:article) 36 assert_nil assigns(:article)
37 - assert_kind_of Array, assigns(:subitems) 37 + assert_kind_of Array, assigns(:articles)
38 end 38 end
39 39
40 should 'be able to view a particular document' do 40 should 'be able to view a particular document' do
@@ -46,9 +46,9 @@ class CmsControllerTest &lt; Test::Unit::TestCase @@ -46,9 +46,9 @@ class CmsControllerTest &lt; Test::Unit::TestCase
46 46
47 assert_template 'view' 47 assert_template 'view'
48 assert_equal a, assigns(:article) 48 assert_equal a, assigns(:article)
49 - assert_equal [], assigns(:subitems) 49 + assert_equal [], assigns(:articles)
50 50
51 - assert_kind_of Array, assigns(:subitems) 51 + assert_kind_of Array, assigns(:articles)
52 end 52 end
53 53
54 should 'be able to edit a document' do 54 should 'be able to edit a document' do
@@ -84,7 +84,7 @@ class CmsControllerTest &lt; Test::Unit::TestCase @@ -84,7 +84,7 @@ class CmsControllerTest &lt; Test::Unit::TestCase
84 end 84 end
85 85
86 should 'display set as home page link to non folder' do 86 should 'display set as home page link to non folder' do
87 - a = profile.articles.create!(:name => 'my new home page') 87 + a = fast_create(TextileArticle, :profile_id => profile.id, :updated_at => DateTime.now)
88 Article.stubs(:short_description).returns('bli') 88 Article.stubs(:short_description).returns('bli')
89 get :index, :profile => profile.identifier 89 get :index, :profile => profile.identifier
90 assert_tag :tag => 'a', :content => 'Use as homepage', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/set_home_page/#{a.id}" } 90 assert_tag :tag => 'a', :content => 'Use as homepage', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/set_home_page/#{a.id}" }
@@ -452,26 +452,27 @@ class CmsControllerTest &lt; Test::Unit::TestCase @@ -452,26 +452,27 @@ class CmsControllerTest &lt; Test::Unit::TestCase
452 assert_tag :tag => 'input', :attributes => { :name => 'parent_id', :value => profile.home_page.id } 452 assert_tag :tag => 'input', :attributes => { :name => 'parent_id', :value => profile.home_page.id }
453 end 453 end
454 454
455 - should 'list folders at top level' do  
456 - Folder.destroy_all  
457 - f1 = Folder.new(:name => 'f1'); profile.articles << f1; f1.save!  
458 - f2 = Folder.new(:name => 'f2'); profile.articles << f2; f2.save! 455 + should 'list folders before others' do
  456 + profile.articles.destroy_all
  457 +
  458 + folder1 = fast_create(Folder, :profile_id => profile.id, :updated_at => DateTime.now - 1.hour)
  459 + article = fast_create(TextileArticle, :profile_id => profile.id, :updated_at => DateTime.now)
  460 + folder2 = fast_create(Folder, :profile_id => profile.id, :updated_at => DateTime.now + 1.hour)
459 461
460 get :index, :profile => profile.identifier 462 get :index, :profile => profile.identifier
461 - assert_equal [f1, f2], assigns(:folders)  
462 - assert_not_includes assigns(:subitems), f1  
463 - assert_not_includes assigns(:subitems), f2 463 + assert_equal [folder2, folder1, article], assigns(:articles)
464 end 464 end
465 465
466 should 'list folders inside another folder' do 466 should 'list folders inside another folder' do
467 - parent = Folder.new(:name => 'parent'); profile.articles << parent; parent.save!  
468 - f1 = Folder.new(:name => 'f1', :parent => parent); profile.articles << f1; f1.save!  
469 - f2 = Folder.new(:name => 'f2', :parent => parent); profile.articles << f2; f2.save! 467 + profile.articles.destroy_all
  468 +
  469 + parent = fast_create(Folder, :profile_id => profile.id)
  470 + folder1 = fast_create(Folder, :parent_id => parent.id, :profile_id => profile.id, :updated_at => DateTime.now - 1.hour)
  471 + article = fast_create(TextileArticle, :parent_id => parent.id, :profile_id => profile.id, :updated_at => DateTime.now)
  472 + folder2 = fast_create(Folder, :parent_id => parent.id, :profile_id => profile.id, :updated_at => DateTime.now + 1.hour)
470 473
471 get :view, :profile => profile.identifier, :id => parent.id 474 get :view, :profile => profile.identifier, :id => parent.id
472 - assert_equal [f1, f2], assigns(:folders)  
473 - assert_not_includes assigns(:subitems), f1  
474 - assert_not_includes assigns(:subitems), f2 475 + assert_equal [folder2, folder1, article], assigns(:articles)
475 end 476 end
476 477
477 should 'offer to create new top-level folder' do 478 should 'offer to create new top-level folder' do
@@ -1190,7 +1191,7 @@ class CmsControllerTest &lt; Test::Unit::TestCase @@ -1190,7 +1191,7 @@ class CmsControllerTest &lt; Test::Unit::TestCase
1190 end 1191 end
1191 1192
1192 should "display 'Publish' when profile is a person" do 1193 should "display 'Publish' when profile is a person" do
1193 - a = profile.articles.create!(:name => 'my new home page') 1194 + a = fast_create(TextileArticle, :profile_id => profile.id, :updated_at => DateTime.now)
1194 Article.stubs(:short_description).returns('bli') 1195 Article.stubs(:short_description).returns('bli')
1195 get :index, :profile => profile.identifier 1196 get :index, :profile => profile.identifier
1196 assert_tag :tag => 'a', :attributes => {:href => "/myprofile/#{profile.identifier}/cms/publish/#{a.id}"} 1197 assert_tag :tag => 'a', :attributes => {:href => "/myprofile/#{profile.identifier}/cms/publish/#{a.id}"}
@@ -1200,7 +1201,7 @@ class CmsControllerTest &lt; Test::Unit::TestCase @@ -1200,7 +1201,7 @@ class CmsControllerTest &lt; Test::Unit::TestCase
1200 community = fast_create(Community) 1201 community = fast_create(Community)
1201 community.add_member(profile) 1202 community.add_member(profile)
1202 Environment.any_instance.stubs(:portal_community).returns(community) 1203 Environment.any_instance.stubs(:portal_community).returns(community)
1203 - a = community.articles.create!(:name => 'my new home page') 1204 + a = fast_create(TextileArticle, :profile_id => community.id, :updated_at => DateTime.now)
1204 Article.stubs(:short_description).returns('bli') 1205 Article.stubs(:short_description).returns('bli')
1205 get :index, :profile => community.identifier 1206 get :index, :profile => community.identifier
1206 assert_tag :tag => 'a', :attributes => {:href => "/myprofile/#{community.identifier}/cms/publish_on_portal_community/#{a.id}"} 1207 assert_tag :tag => 'a', :attributes => {:href => "/myprofile/#{community.identifier}/cms/publish_on_portal_community/#{a.id}"}
test/unit/cms_helper_test.rb
@@ -18,6 +18,74 @@ class CmsHelperTest &lt; Test::Unit::TestCase @@ -18,6 +18,74 @@ class CmsHelperTest &lt; Test::Unit::TestCase
18 assert_match /id="article\[accept_comments\]" name="article\[accept_comments\]" type="hidden" value="0"/, result 18 assert_match /id="article\[accept_comments\]" name="article\[accept_comments\]" type="hidden" value="0"/, result
19 end 19 end
20 20
  21 + should 'display link to folder content if article is folder' do
  22 + profile = fast_create(Profile)
  23 + folder = fast_create(Folder, :name => 'My folder', :profile_id => profile.id)
  24 + expects(:link_to).with('My folder', :action => 'view', :id => folder.id)
  25 +
  26 + result = link_to_article(folder)
  27 + end
  28 +
  29 + should 'display link to article if article is not folder' do
  30 + profile = fast_create(Profile)
  31 + article = fast_create(TinyMceArticle, :name => 'My article', :profile_id => profile.id)
  32 + expects(:link_to).with('My article', article.url)
  33 +
  34 + result = link_to_article(article)
  35 + end
  36 +
  37 + should 'display spread button when profile is a person' do
  38 + profile = fast_create(Person)
  39 + article = fast_create(TinyMceArticle, :name => 'My article', :profile_id => profile.id)
  40 + expects(:button_without_text).with(:spread, 'Spread this', :action => 'publish', :id => article.id)
  41 +
  42 + result = display_spread_button(profile, article)
  43 + end
  44 +
  45 + should 'display spread button when profile is a community and env has portal_community' do
  46 + env = fast_create(Environment)
  47 + env.expects(:portal_community).returns(true)
  48 + profile = fast_create(Community, :environment_id => env.id)
  49 + expects(:environment).returns(env)
  50 +
  51 + article = fast_create(TinyMceArticle, :name => 'My article', :profile_id => profile.id)
  52 +
  53 + expects(:button_without_text).with(:spread, 'Spread this', :action => 'publish_on_portal_community', :id => article.id)
  54 +
  55 + result = display_spread_button(profile, article)
  56 + end
  57 +
  58 + should 'not display spread button when profile is a community and env has not portal_community' do
  59 + env = fast_create(Environment)
  60 + env.expects(:portal_community).returns(nil)
  61 + profile = fast_create(Community, :environment_id => env.id)
  62 + expects(:environment).returns(env)
  63 +
  64 + article = fast_create(TinyMceArticle, :name => 'My article', :profile_id => profile.id)
  65 +
  66 + expects(:button_without_text).with(:spread, 'Spread this', :action => 'publish_on_portal_community', :id => article.id).never
  67 +
  68 + result = display_spread_button(profile, article)
  69 + end
  70 +
  71 + should 'display delete_button to folder' do
  72 + profile = fast_create(Profile)
  73 + folder = fast_create(Folder, :name => 'My folder', :profile_id => profile.id)
  74 + confirm_message = 'Are you sure that you want to remove this folder? Note that all the items inside it will also be removed!'
  75 + expects(:button_without_text).with(:delete, 'Delete', {:action => 'destroy', :id => folder.id}, :method => :post, :confirm => confirm_message)
  76 +
  77 + result = display_delete_button(folder)
  78 + end
  79 +
  80 + should 'display delete_button to article' do
  81 + profile = fast_create(Profile)
  82 + article = fast_create(TinyMceArticle, :name => 'My article', :profile_id => profile.id)
  83 + confirm_message = 'Are you sure that you want to remove this item?'
  84 + expects(:button_without_text).with(:delete, 'Delete', {:action => 'destroy', :id => article.id}, :method => :post, :confirm => confirm_message)
  85 +
  86 + result = display_delete_button(article)
  87 + end
  88 +
21 end 89 end
22 90
23 module RssFeedHelper 91 module RssFeedHelper
test/unit/folder_helper_test.rb
@@ -77,8 +77,16 @@ class FolderHelperTest &lt; Test::Unit::TestCase @@ -77,8 +77,16 @@ class FolderHelperTest &lt; Test::Unit::TestCase
77 should 'list subitems as HTML content' do 77 should 'list subitems as HTML content' do
78 profile = create_user('folder-owner').person 78 profile = create_user('folder-owner').person
79 folder = fast_create(Folder, {:name => 'Parent Folder', :profile_id => profile.id}) 79 folder = fast_create(Folder, {:name => 'Parent Folder', :profile_id => profile.id})
80 - article = fast_create(Article, {:name => 'Article1', :parent_id => folder.id, :profile_id => profile.id})  
81 - article = fast_create(Article, {:name => 'Article2', :parent_id => folder.id, :profile_id => profile.id}) 80 + article1 = fast_create(Article, {:name => 'Article1', :parent_id => folder.id, :profile_id => profile.id, :updated_at => DateTime.now })
  81 + article2 = fast_create(Article, {:name => 'Article2', :parent_id => folder.id, :profile_id => profile.id, :updated_at => DateTime.now })
  82 + self.stubs(:params).returns({:npage => nil})
  83 +
  84 + articles = folder.children.find(:all, :order => 'updated_at DESC').paginate(:per_page => 10, :page => params[:npage])
  85 + expects(:user).returns(profile).at_least_once
  86 + expects(:recursive).returns(false).at_least_once
  87 + expects(:pagination_links).with(anything, anything).returns('')
  88 + list = render 'shared/articles_list', binding
  89 + expects(:render).with(:file => 'shared/articles_list', :locals => { :articles => articles, :recursive => false}).returns(list)
82 90
83 result = list_articles(folder.children) 91 result = list_articles(folder.children)
84 92
test/unit/profile_test.rb
@@ -193,10 +193,10 @@ class ProfileTest &lt; Test::Unit::TestCase @@ -193,10 +193,10 @@ class ProfileTest &lt; Test::Unit::TestCase
193 193
194 list = profile.top_level_articles 194 list = profile.top_level_articles
195 same_list = profile.top_level_articles 195 same_list = profile.top_level_articles
196 - assert_same list, same_list 196 + assert_equal list.object_id, same_list.object_id
197 197
198 other_list = profile.top_level_articles(true) 198 other_list = profile.top_level_articles(true)
199 - assert_not_same list, other_list 199 + assert_not_equal list.object_id, other_list.object_id
200 end 200 end
201 201
202 should 'be able to find profiles by their names with ferret' do 202 should 'be able to find profiles by their names with ferret' do