Commit e8d4ea47c103cf812eec8cfb5c0190bbff91220d

Authored by Victor Costa
1 parent 41ccccb1

proposals_discussion: allow discussion without topics

lib/proposals_discussion_plugin.rb
... ... @@ -19,7 +19,7 @@ class ProposalsDiscussionPlugin < Noosfero::Plugin
19 19 parent = parent_id ? context.profile.articles.find(parent_id) : nil
20 20 types << ProposalsDiscussionPlugin::Discussion
21 21 types << ProposalsDiscussionPlugin::Topic if parent.kind_of?(ProposalsDiscussionPlugin::Discussion)
22   - types << ProposalsDiscussionPlugin::Proposal if parent.kind_of?(ProposalsDiscussionPlugin::Topic)
  22 + types << ProposalsDiscussionPlugin::Proposal if parent.kind_of?(ProposalsDiscussionPlugin::Topic) || ( parent.kind_of?(ProposalsDiscussionPlugin::Discussion) && !parent.allow_topics)
23 23 types
24 24 else
25 25 [ProposalsDiscussionPlugin::Discussion,
... ...
lib/proposals_discussion_plugin/discussion.rb
1   -class ProposalsDiscussionPlugin::Discussion < Folder
  1 +class ProposalsDiscussionPlugin::Discussion < ProposalsDiscussionPlugin::ProposalsHolder
2 2  
3 3 acts_as_having_posts
4 4  
5 5 has_many :topics, :class_name => 'ProposalsDiscussionPlugin::Topic', :foreign_key => 'parent_id'
6   - has_many :proposals, :class_name => 'ProposalsDiscussionPlugin::Proposal', :through => :children, :source => :children
7   - has_many :proposals_comments, :class_name => 'Comment', :through => :proposals, :source => :comments
  6 + has_many :topics_proposals, :class_name => 'ProposalsDiscussionPlugin::Proposal', :through => :children, :source => :children
  7 + has_many :topics_proposals_comments, :class_name => 'Comment', :through => :topics_proposals, :source => :comments
  8 + has_many :discussion_proposals, :class_name => 'ProposalsDiscussionPlugin::Proposal', :foreign_key => 'parent_id'
  9 + has_many :discussion_proposals_comments, :class_name => 'Comment', :through => :discussion_proposals, :source => :comments
  10 + has_many :proposals_authors, :class_name => 'Person', :through => :children, :source => :created_by
  11 +
  12 + def proposals
  13 + allow_topics ? topics_proposals : discussion_proposals
  14 + end
  15 +
  16 + def proposals_comments
  17 + allow_topics ? topics_proposals_comments : discussion_proposals_comments
  18 + end
8 19  
9 20 settings_items :custom_body_label, :type => :string, :default => _('Body')
  21 + settings_items :allow_topics, :type => :boolean, :default => false
10 22  
11   - attr_accessible :custom_body_label
  23 + attr_accessible :custom_body_label, :allow_topics
12 24  
13 25 def self.short_description
14 26 _("Discussion")
... ... @@ -21,22 +33,17 @@ class ProposalsDiscussionPlugin::Discussion &lt; Folder
21 33 def to_html(options = {})
22 34 discussion = self
23 35 proc do
24   - render :file => 'content_viewer/discussion', :locals => {:discussion => discussion}
  36 + if discussion.allow_topics
  37 + render :file => 'content_viewer/discussion_topics', :locals => {:discussion => discussion}
  38 + else
  39 + render :file => 'content_viewer/discussion', :locals => {:discussion => discussion}
  40 + end
25 41 end
26 42 end
27 43  
28   - def cache_key_with_person(params = {}, user = nil, language = 'en')
29   - cache_key_without_person + (user ? "-#{user.identifier}" : '')
30   - end
31   - alias_method_chain :cache_key, :person
32   -
33 44 def posts
34 45 #override posts method to list proposals in feed
35 46 ProposalsDiscussionPlugin::Proposal.from_discussion(self)
36 47 end
37 48  
38   - def accept_comments?
39   - accept_comments
40   - end
41   -
42 49 end
... ...
lib/proposals_discussion_plugin/proposal.rb
... ... @@ -3,7 +3,7 @@ class ProposalsDiscussionPlugin::Proposal &lt; TinyMceArticle
3 3 scope :private, lambda {|user| {:conditions => {:last_changed_by_id => user.id, :published => false}}}
4 4 scope :from_discussion, lambda {|discussion| joins(:parent).where(['parents_articles.parent_id = ?', discussion.id])}
5 5  
6   - alias :topic :parent
  6 + belongs_to :topic, :foreign_key => :parent_id, :class_name => 'ProposalsDiscussionPlugin::Topic'
7 7  
8 8 def self.short_description
9 9 _("Proposal")
... ... @@ -15,6 +15,9 @@ class ProposalsDiscussionPlugin::Proposal &lt; TinyMceArticle
15 15  
16 16 validates_presence_of :abstract
17 17  
  18 + def discussion
  19 + parent.kind_of?(ProposalsDiscussionPlugin::Discussion) ? parent : parent.discussion
  20 + end
18 21  
19 22 def to_html(options = {})
20 23 proposal = self
... ... @@ -35,8 +38,8 @@ class ProposalsDiscussionPlugin::Proposal &lt; TinyMceArticle
35 38 comments_count
36 39 end
37 40  
38   - def normalized_score(holder)
39   - (score/holder.max_score.to_f).round(2)
  41 + def normalized_score
  42 + (score/parent.max_score.to_f).round(2)
40 43 end
41 44  
42 45 def cache_key_with_person(params = {}, user = nil, language = 'en')
... ...
lib/proposals_discussion_plugin/proposals_holder.rb 0 → 100644
... ... @@ -0,0 +1,45 @@
  1 +class ProposalsDiscussionPlugin::ProposalsHolder < Folder
  2 +
  3 + def accept_comments?
  4 + accept_comments
  5 + end
  6 +
  7 + def max_score
  8 + @max ||= [1, proposals.maximum(:comments_count)].max
  9 + end
  10 +
  11 + def proposals_per_day
  12 + result = proposals.group("date(created_at)").count
  13 + fill_empty_days(result)
  14 + end
  15 +
  16 + def comments_per_day
  17 + result = proposals.joins(:comments).group('date(comments.created_at)').count('comments.id')
  18 + fill_empty_days(result)
  19 + end
  20 +
  21 + def most_active_participants
  22 + proposals_authors.group('profiles.id').order('count(articles.id) DESC').includes(:environment, :preferred_domain, :image)
  23 + end
  24 +
  25 + def fill_empty_days(result)
  26 + from = created_at.to_date
  27 + (from..Date.today).inject({}) do |h, date|
  28 + h[date.to_s] = result[date.to_s] || 0
  29 + h
  30 + end
  31 + end
  32 +
  33 + def proposal_tags
  34 + proposals.tag_counts.inject({}) do |memo,tag|
  35 + memo[tag.name] = tag.count
  36 + memo
  37 + end
  38 + end
  39 +
  40 + def cache_key_with_person(params = {}, user = nil, language = 'en')
  41 + cache_key_without_person + (user ? "-#{user.identifier}" : '')
  42 + end
  43 + alias_method_chain :cache_key, :person
  44 +
  45 +end
... ...
lib/proposals_discussion_plugin/topic.rb
1   -class ProposalsDiscussionPlugin::Topic < Folder
  1 +class ProposalsDiscussionPlugin::Topic < ProposalsDiscussionPlugin::ProposalsHolder
2 2  
3 3 alias :discussion :parent
4 4  
... ... @@ -18,10 +18,6 @@ class ProposalsDiscussionPlugin::Topic &lt; Folder
18 18 _('Container for proposals.')
19 19 end
20 20  
21   - def most_active_participants
22   - proposals_authors.group('profiles.id').order('count(articles.id) DESC').includes(:environment, :preferred_domain, :image)
23   - end
24   -
25 21 def to_html(options = {})
26 22 topic = self
27 23 proc do
... ... @@ -33,42 +29,4 @@ class ProposalsDiscussionPlugin::Topic &lt; Folder
33 29 true
34 30 end
35 31  
36   - def max_score
37   - @max ||= [1, proposals.maximum(:comments_count)].max
38   - end
39   -
40   - def proposal_tags
41   - proposals.tag_counts.inject({}) do |memo,tag|
42   - memo[tag.name] = tag.count
43   - memo
44   - end
45   - end
46   -
47   - def proposals_per_day
48   - result = proposals.group("date(created_at)").count
49   - fill_empty_days(result)
50   - end
51   -
52   - def comments_per_day
53   - result = proposals.joins(:comments).group('date(comments.created_at)').count('comments.id')
54   - fill_empty_days(result)
55   - end
56   -
57   - def fill_empty_days(result)
58   - from = created_at.to_date
59   - (from..Date.today).inject({}) do |h, date|
60   - h[date.to_s] = result[date.to_s] || 0
61   - h
62   - end
63   - end
64   -
65   - def cache_key_with_person(params = {}, user = nil, language = 'en')
66   - cache_key_without_person + (user ? "-#{user.identifier}" : '')
67   - end
68   - alias_method_chain :cache_key, :person
69   -
70   - def accept_comments?
71   - accept_comments
72   - end
73   -
74 32 end
... ...
lib/proposals_discussion_plugin/topic_helper.rb
1 1 module ProposalsDiscussionPlugin::TopicHelper
2 2  
3 3 def topic_title(topic)
  4 + return if topic.blank?
4 5 image_icon = topic.image ? image_tag(topic.image.public_filename(:thumb), :class => 'disable-zoom') : ''
5 6  
6 7 content_tag(:div, (
... ...
public/proposals_list.js
... ... @@ -10,7 +10,7 @@ jQuery(document).ready(function($) {
10 10 });
11 11  
12 12 function proposalsScroll() {
13   - var scroll = $('.article-body-proposals-discussion-plugin_topic .topic-content .proposals_list .proposals');
  13 + var scroll = $('.article-body-proposals-discussion-plugin_topic .topic-content .proposals_list .proposals, .article-body-proposals-discussion-plugin_discussion .proposals_list .proposals');
14 14 var nextSelector = 'div.more a';
15 15 if(scroll.data('jscroll')) scroll.data('jscroll', null);
16 16  
... ...
public/style.css
... ... @@ -149,13 +149,13 @@ form .proposals-discussion-plugin .body textarea {
149 149  
150 150 #content #article .topic-item h2, #content #article .article-body-proposals-discussion-plugin_topic h2,
151 151 #content #article .topic h2,
152   -#content .topic .topic-title h2 {
  152 +#content .topic-title h2 {
153 153 background-color: #BDBDBD;
154 154 margin: 0;
155 155 }
156 156  
157 157 #content .topic-item h2 a, #article .article-body-proposals-discussion-plugin_topic h2 a,
158   -#content .topic h2 a {
  158 +#content .topic-title h2 a {
159 159 text-decoration: none;
160 160 display: inline-block;
161 161 color: white;
... ... @@ -213,7 +213,8 @@ form .proposals-discussion-plugin .body textarea {
213 213 .article-body-proposals-discussion-plugin_topic .graph {
214 214 float: left;
215 215 }
216   -.article-body-proposals-discussion-plugin_topic .graph #proposals-time {
  216 +.article-body-proposals-discussion-plugin_topic .graph #proposals-time,
  217 +.article-body-proposals-discussion-plugin_discussion .graph #proposals-time {
217 218 height: 150px;
218 219 width: 300px;
219 220 }
... ...
test/functional/content_viewer_controller_test.rb
... ... @@ -18,4 +18,18 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
18 18 assert_tag :tag => 'div', :attributes => {:class => 'content'}, :content => 'Proposal Body'
19 19 end
20 20  
  21 + should 'display discussion with topics' do
  22 + discussion.allow_topics = true
  23 + discussion.save!
  24 + get :view_page, discussion.url
  25 + assert_template 'content_viewer/discussion_topics'
  26 + end
  27 +
  28 + should 'display discussion without topics' do
  29 + discussion.allow_topics = false
  30 + discussion.save!
  31 + get :view_page, discussion.url
  32 + assert_template 'content_viewer/discussion'
  33 + end
  34 +
21 35 end
... ...
test/functional/proposals_discussion_plugin_profile_controller_test.rb
... ... @@ -4,7 +4,7 @@ class ProposalsDiscussionPluginProfileControllerTest &lt; ActionController::TestCas
4 4  
5 5 def setup
6 6 @profile = fast_create(Community)
7   - @discussion = fast_create(ProposalsDiscussionPlugin::Discussion, :profile_id => @profile.id)
  7 + @discussion = ProposalsDiscussionPlugin::Discussion.create!(:profile => @profile, :name => 'discussion',:allow_topics => true)
8 8 @topic = fast_create(ProposalsDiscussionPlugin::Topic, :parent_id => @discussion.id, :profile_id => @profile.id)
9 9 @person = create_user_with_permission('testinguser', 'post_content')
10 10 login_as :testinguser
... ...
test/functional/proposals_discussion_plugin_public_controller_test.rb
... ... @@ -4,7 +4,7 @@ class ProposalsDiscussionPluginPublicControllerTest &lt; ActionController::TestCase
4 4  
5 5 def setup
6 6 @profile = fast_create(Community)
7   - @discussion = fast_create(ProposalsDiscussionPlugin::Discussion, :profile_id => @profile.id)
  7 + @discussion = ProposalsDiscussionPlugin::Discussion.create!(:profile => @profile, :allow_topics => true, :name => 'discussion')
8 8 @topic = fast_create(ProposalsDiscussionPlugin::Topic, :parent_id => @discussion.id, :profile_id => @profile.id)
9 9 end
10 10  
... ...
test/unit/discussion_test.rb
... ... @@ -21,7 +21,17 @@ class DiscussionTest &lt; ActiveSupport::TestCase
21 21 topic = fast_create(ProposalsDiscussionPlugin::Topic, :parent_id => discussion.id)
22 22 proposal1 = fast_create(ProposalsDiscussionPlugin::Proposal, :parent_id => topic.id)
23 23 proposal2 = fast_create(ProposalsDiscussionPlugin::Proposal, :parent_id => topic.id)
24   - assert_equivalent [proposal1, proposal2], discussion.proposals
  24 + assert_equivalent [proposal1, proposal2], discussion.topics_proposals
  25 + end
  26 +
  27 + should 'return max score' do
  28 + person = fast_create(Person)
  29 + discussion = ProposalsDiscussionPlugin::Discussion.create!(:profile => person, :name => 'discussion')
  30 + proposal1 = ProposalsDiscussionPlugin::Proposal.create!(:parent => discussion, :profile => profile, :name => "proposal1", :abstract => 'abstract')
  31 + proposal2 = ProposalsDiscussionPlugin::Proposal.create!(:parent => discussion, :profile => profile, :name => "proposal2", :abstract => 'abstract')
  32 + 10.times { Comment.create!(:source => proposal1, :body => "comment", :author => person) }
  33 + 5.times { Comment.create!(:source => proposal2, :body => "comment", :author => person) }
  34 + assert_equal 10, discussion.max_score
25 35 end
26 36  
27 37 end
... ...
test/unit/proposal_test.rb
... ... @@ -51,4 +51,14 @@ class ProposalTest &lt; ActiveSupport::TestCase
51 51 assert_equivalent [proposal1, proposal3], ProposalsDiscussionPlugin::Proposal.from_discussion(discussion)
52 52 end
53 53  
  54 + should 'return normalized score' do
  55 + discussion = ProposalsDiscussionPlugin::Discussion.create!(:profile => person, :name => 'discussion')
  56 + proposal1 = ProposalsDiscussionPlugin::Proposal.create!(:parent => discussion, :profile => profile, :name => "proposal1", :abstract => 'abstract')
  57 + proposal2 = ProposalsDiscussionPlugin::Proposal.create!(:parent => discussion, :profile => profile, :name => "proposal2", :abstract => 'abstract')
  58 + 10.times { Comment.create!(:source => proposal1, :body => "comment", :author => person) }
  59 + 5.times { Comment.create!(:source => proposal2, :body => "comment", :author => person) }
  60 + assert_equal 1, proposal1.reload.normalized_score
  61 + assert_equal 0.5, proposal2.reload.normalized_score
  62 + end
  63 +
54 64 end
... ...
test/unit/proposals_discussion_plugin_test.rb
... ... @@ -32,6 +32,12 @@ class ProposalsDiscussionPluginTest &lt; ActiveSupport::TestCase
32 32 assert_includes plugin.content_types, ProposalsDiscussionPlugin::Proposal
33 33 end
34 34  
  35 + should 'return Proposal as a content type if parent is a Discussion and allow_topic is false' do
  36 + parent = ProposalsDiscussionPlugin::Discussion.create!(:profile => @profile, :name => 'discussion', :allow_topics => false)
  37 + @params[:parent_id] = parent.id
  38 + assert_includes plugin.content_types, ProposalsDiscussionPlugin::Proposal
  39 + end
  40 +
35 41 should 'do not return Proposal as a content type if parent is nil' do
36 42 @params[:parent_id] = nil
37 43 assert_not_includes plugin.content_types, ProposalsDiscussionPlugin::Proposal
... ...
test/unit/topic_test.rb
... ... @@ -47,4 +47,13 @@ class TopicTest &lt; ActiveSupport::TestCase
47 47 assert_equal [author2, author1], topic.most_active_participants
48 48 end
49 49  
  50 + should 'return max score' do
  51 + person = fast_create(Person)
  52 + proposal1 = ProposalsDiscussionPlugin::Proposal.create!(:parent => topic, :profile => profile, :name => "proposal1", :abstract => 'abstract')
  53 + proposal2 = ProposalsDiscussionPlugin::Proposal.create!(:parent => topic, :profile => profile, :name => "proposal2", :abstract => 'abstract')
  54 + 10.times { Comment.create!(:source => proposal1, :body => "comment", :author => person) }
  55 + 5.times { Comment.create!(:source => proposal2, :body => "comment", :author => person) }
  56 + assert_equal 10, topic.max_score
  57 + end
  58 +
50 59 end
... ...
views/cms/proposals_discussion_plugin/_discussion.html.erb
1   -sdadasda
2 1 <%= required_fields_message %>
3 2  
4 3 <%= required f.text_field('name', :size => '64', :maxlength => 150) %>
... ... @@ -7,3 +6,4 @@ sdadasda
7 6 <%= labelled_form_field(_('Description:'), text_area(:article, :body, :rows => 3, :cols => 64)) %>
8 7  
9 8 <%= f.text_field(:custom_body_label) %>
  9 +<%= labelled_form_field check_box(:article, :allow_topics) + _('Allow topics'), '' %>
... ...
views/cms/proposals_discussion_plugin/_proposal.html.erb
... ... @@ -9,9 +9,7 @@
9 9  
10 10 <div class="proposals-discussion-plugin">
11 11  
12   - <div class="topic">
13   - <%= topic_title @article.topic %>
14   - </div>
  12 + <%= topic_title @article.topic %>
15 13  
16 14 <div class="title">
17 15 <%= required labelled_form_field _('Title'), limited_text_area(:article, :name, title_limit, 'title_textarea', :rows => 1) %>
... ... @@ -23,7 +21,7 @@
23 21  
24 22 <div class="body">
25 23 <% editor_type = 'mceEditor' %>
26   - <%= labelled_form_field(strip_tags(@article.topic.discussion.custom_body_label), text_area(:article, :body, :class => editor_type)) %>
  24 + <%= labelled_form_field(strip_tags(@article.discussion.custom_body_label), text_area(:article, :body, :class => editor_type)) %>
27 25 </div>
28 26 </div>
29 27  
... ...
views/content_viewer/_proposal_card.html.erb
1 1 <div class="proposal">
2 2 <div class="score">
3 3 <% if proposal_card.published? %>
4   - <% normalized_score = proposal_card.normalized_score(@holder) %>
  4 + <% normalized_score = proposal_card.normalized_score %>
5 5 <% pos = 26 * (normalized_score*4 - 1).round %>
6 6 <span title="<%= normalized_score %>" style="background-position-y: -<%= pos %>px">&nbsp;</span>
7 7 <% end %>
... ...
views/content_viewer/_statistics.html.erb 0 → 100644
... ... @@ -0,0 +1,32 @@
  1 +<div class="statistics">
  2 + <h5><%= _('Statistics') %></h5>
  3 +
  4 + <div class="graph">
  5 + <div id="proposals-time"></div>
  6 + </div>
  7 + <%= javascript_include_tag 'plugins/proposals_discussion/proposals_graph.js' %>
  8 + <script>load_proposals_graph('<%= holder.proposals_per_day.to_json %>', '<%= holder.comments_per_day.to_json %>', '<%= _('Proposals') %>', '<%= _('Comments') %>')</script>
  9 +
  10 + <div class="summary">
  11 + <div class="proposals-count">
  12 + <span class="label"><%= _('Number of Proposals: ') %></span>
  13 + <span class="content"><%= holder.proposals.count %></span>
  14 + </div>
  15 + <div class="participants-count">
  16 + <span class="label"><%= _('Number of Participants: ') %></span>
  17 + <span class="content"><%= holder.proposals_authors.count %></span>
  18 + </div>
  19 + <div class="comments-count">
  20 + <span class="label"><%= _('Number of Comments: ') %></span>
  21 + <span class="content"><%= holder.proposals_comments.count %></span>
  22 + </div>
  23 + <div class="active-participants">
  24 + <span class="label"><%= _('Most active: ') %></span>
  25 + <span class="content">
  26 + <% holder.most_active_participants.each do |author| %>
  27 + <%= link_to profile_image(author, :icon), author.url, :title => author.name %>
  28 + <% end %>
  29 + </span>
  30 + </div>
  31 + </div>
  32 +</div>
... ...
views/content_viewer/discussion.html.erb
... ... @@ -8,26 +8,20 @@
8 8  
9 9 <% if discussion.allow_create?(user) %>
10 10 <div class="actions">
11   - <%= link_to({:controller => 'cms', :action => 'new', :type => "ProposalsDiscussionPlugin::Topic", :parent_id => discussion.id}, :class => 'button with-text icon-add') do %>
12   - <strong><%= _("New Topic") %></strong>
13   - <% end %>
14 11 <%= link_to({:controller => :proposals_discussion_plugin_profile, :action => :export, :format => :csv, :article_id => discussion.id}, :class => 'button with-text icon-spread') do %>
15 12 <strong><%= _('Export') %></strong>
16 13 <% end %>
17 14 </div>
18 15 <% end %>
19 16  
20   -<div class="topics js-masonry" data-masonry-options='{ "itemSelector": ".topic-item", "columnWidth": 200 }'>
21   - <div class="actions topic-item">
22   - <div class="topic-color"></div>
23   - <%= link_to url_for({:controller => 'proposals_discussion_plugin_myprofile', :action => 'select_topic', :parent_id => discussion.id}), :class => 'button with-text icon-add' do %>
24   - <strong><%= _("Send your proposal!") %></strong>
25   - <% end %>
26   - </div>
27   - <% discussion.topics.includes(:profile).each do |topic| %>
28   - <div class="topic-item" id="topic-<%= topic.id %>">
29   - <%= render :file => 'content_viewer/topic', :locals => {:topic => topic, :list_view => true} %>
30   - </div>
31   - <% end %>
  17 +<%= link_to url_for({:controller => 'cms', :action => 'new', :type => "ProposalsDiscussionPlugin::Proposal", :parent_id => discussion.id}), :class => 'button with-text icon-add' do %>
  18 + <strong><%= _("Send your proposal!") %></strong>
  19 +<% end %>
  20 +
  21 +<%= render :partial => 'content_viewer/statistics', :locals => {:holder => discussion} %>
  22 +
  23 +<div class="tag_cloud">
  24 + <%= tag_cloud(discussion.proposal_tags, :tag, {:action => :tag, :controller => 'search'}, :max_size => 18, :min_size => 10) %>
32 25 </div>
33 26  
  27 +<%= render :partial => 'content_viewer/proposals_list', :locals => {:holder => discussion} %>
... ...
views/content_viewer/discussion_topics.html.erb 0 → 100644
... ... @@ -0,0 +1,33 @@
  1 +<%= javascript_include_tag 'plugins/proposals_discussion/proposals_list.js' %>
  2 +
  3 +<%= add_rss_feed_to_head(discussion.name, discussion.feed.url) if discussion.feed %>
  4 +
  5 +<div class="description">
  6 + <%= discussion.body %>
  7 +</div>
  8 +
  9 +<% if discussion.allow_create?(user) %>
  10 +<div class="actions">
  11 + <%= link_to({:controller => 'cms', :action => 'new', :type => "ProposalsDiscussionPlugin::Topic", :parent_id => discussion.id}, :class => 'button with-text icon-add') do %>
  12 + <strong><%= _("New Topic") %></strong>
  13 + <% end %>
  14 + <%= link_to({:controller => :proposals_discussion_plugin_profile, :action => :export, :format => :csv, :article_id => discussion.id}, :class => 'button with-text icon-spread') do %>
  15 + <strong><%= _('Export') %></strong>
  16 + <% end %>
  17 +</div>
  18 +<% end %>
  19 +
  20 +<div class="topics js-masonry" data-masonry-options='{ "itemSelector": ".topic-item", "columnWidth": 200 }'>
  21 + <div class="actions topic-item">
  22 + <div class="topic-color"></div>
  23 + <%= link_to url_for({:controller => 'proposals_discussion_plugin_myprofile', :action => 'select_topic', :parent_id => discussion.id}), :class => 'button with-text icon-add' do %>
  24 + <strong><%= _("Send your proposal!") %></strong>
  25 + <% end %>
  26 + </div>
  27 + <% discussion.topics.includes(:profile).each do |topic| %>
  28 + <div class="topic-item" id="topic-<%= topic.id %>">
  29 + <%= render :file => 'content_viewer/topic', :locals => {:topic => topic, :list_view => true} %>
  30 + </div>
  31 + <% end %>
  32 +</div>
  33 +
... ...
views/content_viewer/proposal.html.erb
... ... @@ -5,14 +5,12 @@
5 5 </span>
6 6  
7 7 <div class="discussion">
8   - <h5><%= proposal.topic.discussion.title %> </h5>
  8 + <h5><%= proposal.discussion.title %> </h5>
9 9 </div>
10 10  
11 11 <% extend ProposalsDiscussionPlugin::TopicHelper %>
12 12  
13   -<div class="topic">
14   - <%= topic_title proposal.topic %>
15   -</div>
  13 +<%= topic_title proposal.topic %>
16 14  
17 15 <div class="abstract">
18 16 <div class="content"><%= proposal.abstract %></div>
... ...
views/content_viewer/topic.html.erb
... ... @@ -16,38 +16,8 @@
16 16 <% unless list_view %>
17 17 <h4><%= topic.discussion.title %></h4>
18 18  
19   - <div class="statistics">
20   - <h5><%= _('Statistics') %></h5>
  19 + <%= render :partial => 'content_viewer/statistics', :locals => {:holder => topic} %>
21 20  
22   - <div class="graph">
23   - <div id="proposals-time"></div>
24   - </div>
25   - <%= javascript_include_tag 'plugins/proposals_discussion/proposals_graph.js' %>
26   - <script>load_proposals_graph('<%= topic.proposals_per_day.to_json %>', '<%= topic.comments_per_day.to_json %>', '<%= _('Proposals') %>', '<%= _('Comments') %>')</script>
27   -
28   - <div class="summary">
29   - <div class="proposals-count">
30   - <span class="label"><%= _('Number of Proposals: ') %></span>
31   - <span class="content"><%= topic.proposals.count %></span>
32   - </div>
33   - <div class="participants-count">
34   - <span class="label"><%= _('Number of Participants: ') %></span>
35   - <span class="content"><%= topic.proposals_authors.count %></span>
36   - </div>
37   - <div class="comments-count">
38   - <span class="label"><%= _('Number of Comments: ') %></span>
39   - <span class="content"><%= topic.proposals_comments.count %></span>
40   - </div>
41   - <div class="active-participants">
42   - <span class="label"><%= _('Most active: ') %></span>
43   - <span class="content">
44   - <% topic.most_active_participants.each do |author| %>
45   - <%= link_to profile_image(author, :icon), author.url, :title => author.name %>
46   - <% end %>
47   - </span>
48   - </div>
49   - </div>
50   - </div>
51 21 <div class="tag_cloud">
52 22 <%= tag_cloud(topic.proposal_tags, :tag, {:action => :tag, :controller => 'search'}, :max_size => 18, :min_size => 10) %>
53 23 </div>
... ...