Commit e8d4ea47c103cf812eec8cfb5c0190bbff91220d
1 parent
41ccccb1
Exists in
master
and in
11 other branches
proposals_discussion: allow discussion without topics
Showing
23 changed files
with
213 additions
and
124 deletions
Show diff stats
lib/proposals_discussion_plugin.rb
@@ -19,7 +19,7 @@ class ProposalsDiscussionPlugin < Noosfero::Plugin | @@ -19,7 +19,7 @@ class ProposalsDiscussionPlugin < Noosfero::Plugin | ||
19 | parent = parent_id ? context.profile.articles.find(parent_id) : nil | 19 | parent = parent_id ? context.profile.articles.find(parent_id) : nil |
20 | types << ProposalsDiscussionPlugin::Discussion | 20 | types << ProposalsDiscussionPlugin::Discussion |
21 | types << ProposalsDiscussionPlugin::Topic if parent.kind_of?(ProposalsDiscussionPlugin::Discussion) | 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 | types | 23 | types |
24 | else | 24 | else |
25 | [ProposalsDiscussionPlugin::Discussion, | 25 | [ProposalsDiscussionPlugin::Discussion, |
lib/proposals_discussion_plugin/discussion.rb
1 | -class ProposalsDiscussionPlugin::Discussion < Folder | 1 | +class ProposalsDiscussionPlugin::Discussion < ProposalsDiscussionPlugin::ProposalsHolder |
2 | 2 | ||
3 | acts_as_having_posts | 3 | acts_as_having_posts |
4 | 4 | ||
5 | has_many :topics, :class_name => 'ProposalsDiscussionPlugin::Topic', :foreign_key => 'parent_id' | 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 | settings_items :custom_body_label, :type => :string, :default => _('Body') | 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 | def self.short_description | 25 | def self.short_description |
14 | _("Discussion") | 26 | _("Discussion") |
@@ -21,22 +33,17 @@ class ProposalsDiscussionPlugin::Discussion < Folder | @@ -21,22 +33,17 @@ class ProposalsDiscussionPlugin::Discussion < Folder | ||
21 | def to_html(options = {}) | 33 | def to_html(options = {}) |
22 | discussion = self | 34 | discussion = self |
23 | proc do | 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 | end | 41 | end |
26 | end | 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 | def posts | 44 | def posts |
34 | #override posts method to list proposals in feed | 45 | #override posts method to list proposals in feed |
35 | ProposalsDiscussionPlugin::Proposal.from_discussion(self) | 46 | ProposalsDiscussionPlugin::Proposal.from_discussion(self) |
36 | end | 47 | end |
37 | 48 | ||
38 | - def accept_comments? | ||
39 | - accept_comments | ||
40 | - end | ||
41 | - | ||
42 | end | 49 | end |
lib/proposals_discussion_plugin/proposal.rb
@@ -3,7 +3,7 @@ class ProposalsDiscussionPlugin::Proposal < TinyMceArticle | @@ -3,7 +3,7 @@ class ProposalsDiscussionPlugin::Proposal < TinyMceArticle | ||
3 | scope :private, lambda {|user| {:conditions => {:last_changed_by_id => user.id, :published => false}}} | 3 | scope :private, lambda {|user| {:conditions => {:last_changed_by_id => user.id, :published => false}}} |
4 | scope :from_discussion, lambda {|discussion| joins(:parent).where(['parents_articles.parent_id = ?', discussion.id])} | 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 | def self.short_description | 8 | def self.short_description |
9 | _("Proposal") | 9 | _("Proposal") |
@@ -15,6 +15,9 @@ class ProposalsDiscussionPlugin::Proposal < TinyMceArticle | @@ -15,6 +15,9 @@ class ProposalsDiscussionPlugin::Proposal < TinyMceArticle | ||
15 | 15 | ||
16 | validates_presence_of :abstract | 16 | validates_presence_of :abstract |
17 | 17 | ||
18 | + def discussion | ||
19 | + parent.kind_of?(ProposalsDiscussionPlugin::Discussion) ? parent : parent.discussion | ||
20 | + end | ||
18 | 21 | ||
19 | def to_html(options = {}) | 22 | def to_html(options = {}) |
20 | proposal = self | 23 | proposal = self |
@@ -35,8 +38,8 @@ class ProposalsDiscussionPlugin::Proposal < TinyMceArticle | @@ -35,8 +38,8 @@ class ProposalsDiscussionPlugin::Proposal < TinyMceArticle | ||
35 | comments_count | 38 | comments_count |
36 | end | 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 | end | 43 | end |
41 | 44 | ||
42 | def cache_key_with_person(params = {}, user = nil, language = 'en') | 45 | def cache_key_with_person(params = {}, user = nil, language = 'en') |
@@ -0,0 +1,45 @@ | @@ -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 | alias :discussion :parent | 3 | alias :discussion :parent |
4 | 4 | ||
@@ -18,10 +18,6 @@ class ProposalsDiscussionPlugin::Topic < Folder | @@ -18,10 +18,6 @@ class ProposalsDiscussionPlugin::Topic < Folder | ||
18 | _('Container for proposals.') | 18 | _('Container for proposals.') |
19 | end | 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 | def to_html(options = {}) | 21 | def to_html(options = {}) |
26 | topic = self | 22 | topic = self |
27 | proc do | 23 | proc do |
@@ -33,42 +29,4 @@ class ProposalsDiscussionPlugin::Topic < Folder | @@ -33,42 +29,4 @@ class ProposalsDiscussionPlugin::Topic < Folder | ||
33 | true | 29 | true |
34 | end | 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 | end | 32 | end |
lib/proposals_discussion_plugin/topic_helper.rb
1 | module ProposalsDiscussionPlugin::TopicHelper | 1 | module ProposalsDiscussionPlugin::TopicHelper |
2 | 2 | ||
3 | def topic_title(topic) | 3 | def topic_title(topic) |
4 | + return if topic.blank? | ||
4 | image_icon = topic.image ? image_tag(topic.image.public_filename(:thumb), :class => 'disable-zoom') : '' | 5 | image_icon = topic.image ? image_tag(topic.image.public_filename(:thumb), :class => 'disable-zoom') : '' |
5 | 6 | ||
6 | content_tag(:div, ( | 7 | content_tag(:div, ( |
public/proposals_list.js
@@ -10,7 +10,7 @@ jQuery(document).ready(function($) { | @@ -10,7 +10,7 @@ jQuery(document).ready(function($) { | ||
10 | }); | 10 | }); |
11 | 11 | ||
12 | function proposalsScroll() { | 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 | var nextSelector = 'div.more a'; | 14 | var nextSelector = 'div.more a'; |
15 | if(scroll.data('jscroll')) scroll.data('jscroll', null); | 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,13 +149,13 @@ form .proposals-discussion-plugin .body textarea { | ||
149 | 149 | ||
150 | #content #article .topic-item h2, #content #article .article-body-proposals-discussion-plugin_topic h2, | 150 | #content #article .topic-item h2, #content #article .article-body-proposals-discussion-plugin_topic h2, |
151 | #content #article .topic h2, | 151 | #content #article .topic h2, |
152 | -#content .topic .topic-title h2 { | 152 | +#content .topic-title h2 { |
153 | background-color: #BDBDBD; | 153 | background-color: #BDBDBD; |
154 | margin: 0; | 154 | margin: 0; |
155 | } | 155 | } |
156 | 156 | ||
157 | #content .topic-item h2 a, #article .article-body-proposals-discussion-plugin_topic h2 a, | 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 | text-decoration: none; | 159 | text-decoration: none; |
160 | display: inline-block; | 160 | display: inline-block; |
161 | color: white; | 161 | color: white; |
@@ -213,7 +213,8 @@ form .proposals-discussion-plugin .body textarea { | @@ -213,7 +213,8 @@ form .proposals-discussion-plugin .body textarea { | ||
213 | .article-body-proposals-discussion-plugin_topic .graph { | 213 | .article-body-proposals-discussion-plugin_topic .graph { |
214 | float: left; | 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 | height: 150px; | 218 | height: 150px; |
218 | width: 300px; | 219 | width: 300px; |
219 | } | 220 | } |
test/functional/content_viewer_controller_test.rb
@@ -18,4 +18,18 @@ class ContentViewerControllerTest < ActionController::TestCase | @@ -18,4 +18,18 @@ class ContentViewerControllerTest < ActionController::TestCase | ||
18 | assert_tag :tag => 'div', :attributes => {:class => 'content'}, :content => 'Proposal Body' | 18 | assert_tag :tag => 'div', :attributes => {:class => 'content'}, :content => 'Proposal Body' |
19 | end | 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 | end | 35 | end |
test/functional/proposals_discussion_plugin_profile_controller_test.rb
@@ -4,7 +4,7 @@ class ProposalsDiscussionPluginProfileControllerTest < ActionController::TestCas | @@ -4,7 +4,7 @@ class ProposalsDiscussionPluginProfileControllerTest < ActionController::TestCas | ||
4 | 4 | ||
5 | def setup | 5 | def setup |
6 | @profile = fast_create(Community) | 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 | @topic = fast_create(ProposalsDiscussionPlugin::Topic, :parent_id => @discussion.id, :profile_id => @profile.id) | 8 | @topic = fast_create(ProposalsDiscussionPlugin::Topic, :parent_id => @discussion.id, :profile_id => @profile.id) |
9 | @person = create_user_with_permission('testinguser', 'post_content') | 9 | @person = create_user_with_permission('testinguser', 'post_content') |
10 | login_as :testinguser | 10 | login_as :testinguser |
test/functional/proposals_discussion_plugin_public_controller_test.rb
@@ -4,7 +4,7 @@ class ProposalsDiscussionPluginPublicControllerTest < ActionController::TestCase | @@ -4,7 +4,7 @@ class ProposalsDiscussionPluginPublicControllerTest < ActionController::TestCase | ||
4 | 4 | ||
5 | def setup | 5 | def setup |
6 | @profile = fast_create(Community) | 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 | @topic = fast_create(ProposalsDiscussionPlugin::Topic, :parent_id => @discussion.id, :profile_id => @profile.id) | 8 | @topic = fast_create(ProposalsDiscussionPlugin::Topic, :parent_id => @discussion.id, :profile_id => @profile.id) |
9 | end | 9 | end |
10 | 10 |
test/unit/discussion_test.rb
@@ -21,7 +21,17 @@ class DiscussionTest < ActiveSupport::TestCase | @@ -21,7 +21,17 @@ class DiscussionTest < ActiveSupport::TestCase | ||
21 | topic = fast_create(ProposalsDiscussionPlugin::Topic, :parent_id => discussion.id) | 21 | topic = fast_create(ProposalsDiscussionPlugin::Topic, :parent_id => discussion.id) |
22 | proposal1 = fast_create(ProposalsDiscussionPlugin::Proposal, :parent_id => topic.id) | 22 | proposal1 = fast_create(ProposalsDiscussionPlugin::Proposal, :parent_id => topic.id) |
23 | proposal2 = fast_create(ProposalsDiscussionPlugin::Proposal, :parent_id => topic.id) | 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 | end | 35 | end |
26 | 36 | ||
27 | end | 37 | end |
test/unit/proposal_test.rb
@@ -51,4 +51,14 @@ class ProposalTest < ActiveSupport::TestCase | @@ -51,4 +51,14 @@ class ProposalTest < ActiveSupport::TestCase | ||
51 | assert_equivalent [proposal1, proposal3], ProposalsDiscussionPlugin::Proposal.from_discussion(discussion) | 51 | assert_equivalent [proposal1, proposal3], ProposalsDiscussionPlugin::Proposal.from_discussion(discussion) |
52 | end | 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 | end | 64 | end |
test/unit/proposals_discussion_plugin_test.rb
@@ -32,6 +32,12 @@ class ProposalsDiscussionPluginTest < ActiveSupport::TestCase | @@ -32,6 +32,12 @@ class ProposalsDiscussionPluginTest < ActiveSupport::TestCase | ||
32 | assert_includes plugin.content_types, ProposalsDiscussionPlugin::Proposal | 32 | assert_includes plugin.content_types, ProposalsDiscussionPlugin::Proposal |
33 | end | 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 | should 'do not return Proposal as a content type if parent is nil' do | 41 | should 'do not return Proposal as a content type if parent is nil' do |
36 | @params[:parent_id] = nil | 42 | @params[:parent_id] = nil |
37 | assert_not_includes plugin.content_types, ProposalsDiscussionPlugin::Proposal | 43 | assert_not_includes plugin.content_types, ProposalsDiscussionPlugin::Proposal |
test/unit/topic_test.rb
@@ -47,4 +47,13 @@ class TopicTest < ActiveSupport::TestCase | @@ -47,4 +47,13 @@ class TopicTest < ActiveSupport::TestCase | ||
47 | assert_equal [author2, author1], topic.most_active_participants | 47 | assert_equal [author2, author1], topic.most_active_participants |
48 | end | 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 | end | 59 | end |
views/cms/proposals_discussion_plugin/_discussion.html.erb
1 | -sdadasda | ||
2 | <%= required_fields_message %> | 1 | <%= required_fields_message %> |
3 | 2 | ||
4 | <%= required f.text_field('name', :size => '64', :maxlength => 150) %> | 3 | <%= required f.text_field('name', :size => '64', :maxlength => 150) %> |
@@ -7,3 +6,4 @@ sdadasda | @@ -7,3 +6,4 @@ sdadasda | ||
7 | <%= labelled_form_field(_('Description:'), text_area(:article, :body, :rows => 3, :cols => 64)) %> | 6 | <%= labelled_form_field(_('Description:'), text_area(:article, :body, :rows => 3, :cols => 64)) %> |
8 | 7 | ||
9 | <%= f.text_field(:custom_body_label) %> | 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 +9,7 @@ | ||
9 | 9 | ||
10 | <div class="proposals-discussion-plugin"> | 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 | <div class="title"> | 14 | <div class="title"> |
17 | <%= required labelled_form_field _('Title'), limited_text_area(:article, :name, title_limit, 'title_textarea', :rows => 1) %> | 15 | <%= required labelled_form_field _('Title'), limited_text_area(:article, :name, title_limit, 'title_textarea', :rows => 1) %> |
@@ -23,7 +21,7 @@ | @@ -23,7 +21,7 @@ | ||
23 | 21 | ||
24 | <div class="body"> | 22 | <div class="body"> |
25 | <% editor_type = 'mceEditor' %> | 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 | </div> | 25 | </div> |
28 | </div> | 26 | </div> |
29 | 27 |
views/content_viewer/_proposal_card.html.erb
1 | <div class="proposal"> | 1 | <div class="proposal"> |
2 | <div class="score"> | 2 | <div class="score"> |
3 | <% if proposal_card.published? %> | 3 | <% if proposal_card.published? %> |
4 | - <% normalized_score = proposal_card.normalized_score(@holder) %> | 4 | + <% normalized_score = proposal_card.normalized_score %> |
5 | <% pos = 26 * (normalized_score*4 - 1).round %> | 5 | <% pos = 26 * (normalized_score*4 - 1).round %> |
6 | <span title="<%= normalized_score %>" style="background-position-y: -<%= pos %>px"> </span> | 6 | <span title="<%= normalized_score %>" style="background-position-y: -<%= pos %>px"> </span> |
7 | <% end %> | 7 | <% end %> |
@@ -0,0 +1,32 @@ | @@ -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,26 +8,20 @@ | ||
8 | 8 | ||
9 | <% if discussion.allow_create?(user) %> | 9 | <% if discussion.allow_create?(user) %> |
10 | <div class="actions"> | 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 %> | 11 | <%= 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> | 12 | <strong><%= _('Export') %></strong> |
16 | <% end %> | 13 | <% end %> |
17 | </div> | 14 | </div> |
18 | <% end %> | 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 | </div> | 25 | </div> |
33 | 26 | ||
27 | +<%= render :partial => 'content_viewer/proposals_list', :locals => {:holder => discussion} %> |
@@ -0,0 +1,33 @@ | @@ -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,14 +5,12 @@ | ||
5 | </span> | 5 | </span> |
6 | 6 | ||
7 | <div class="discussion"> | 7 | <div class="discussion"> |
8 | - <h5><%= proposal.topic.discussion.title %> </h5> | 8 | + <h5><%= proposal.discussion.title %> </h5> |
9 | </div> | 9 | </div> |
10 | 10 | ||
11 | <% extend ProposalsDiscussionPlugin::TopicHelper %> | 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 | <div class="abstract"> | 15 | <div class="abstract"> |
18 | <div class="content"><%= proposal.abstract %></div> | 16 | <div class="content"><%= proposal.abstract %></div> |
views/content_viewer/topic.html.erb
@@ -16,38 +16,8 @@ | @@ -16,38 +16,8 @@ | ||
16 | <% unless list_view %> | 16 | <% unless list_view %> |
17 | <h4><%= topic.discussion.title %></h4> | 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 | <div class="tag_cloud"> | 21 | <div class="tag_cloud"> |
52 | <%= tag_cloud(topic.proposal_tags, :tag, {:action => :tag, :controller => 'search'}, :max_size => 18, :min_size => 10) %> | 22 | <%= tag_cloud(topic.proposal_tags, :tag, {:action => :tag, :controller => 'search'}, :max_size => 18, :min_size => 10) %> |
53 | </div> | 23 | </div> |