diff --git a/lib/proposals_discussion_plugin.rb b/lib/proposals_discussion_plugin.rb index bb55542..98a2252 100644 --- a/lib/proposals_discussion_plugin.rb +++ b/lib/proposals_discussion_plugin.rb @@ -19,7 +19,7 @@ class ProposalsDiscussionPlugin < Noosfero::Plugin parent = parent_id ? context.profile.articles.find(parent_id) : nil types << ProposalsDiscussionPlugin::Discussion types << ProposalsDiscussionPlugin::Topic if parent.kind_of?(ProposalsDiscussionPlugin::Discussion) - types << ProposalsDiscussionPlugin::Proposal if parent.kind_of?(ProposalsDiscussionPlugin::Topic) + types << ProposalsDiscussionPlugin::Proposal if parent.kind_of?(ProposalsDiscussionPlugin::Topic) || ( parent.kind_of?(ProposalsDiscussionPlugin::Discussion) && !parent.allow_topics) types else [ProposalsDiscussionPlugin::Discussion, diff --git a/lib/proposals_discussion_plugin/discussion.rb b/lib/proposals_discussion_plugin/discussion.rb index f449aa4..f3024ba 100644 --- a/lib/proposals_discussion_plugin/discussion.rb +++ b/lib/proposals_discussion_plugin/discussion.rb @@ -1,14 +1,26 @@ -class ProposalsDiscussionPlugin::Discussion < Folder +class ProposalsDiscussionPlugin::Discussion < ProposalsDiscussionPlugin::ProposalsHolder acts_as_having_posts has_many :topics, :class_name => 'ProposalsDiscussionPlugin::Topic', :foreign_key => 'parent_id' - has_many :proposals, :class_name => 'ProposalsDiscussionPlugin::Proposal', :through => :children, :source => :children - has_many :proposals_comments, :class_name => 'Comment', :through => :proposals, :source => :comments + has_many :topics_proposals, :class_name => 'ProposalsDiscussionPlugin::Proposal', :through => :children, :source => :children + has_many :topics_proposals_comments, :class_name => 'Comment', :through => :topics_proposals, :source => :comments + has_many :discussion_proposals, :class_name => 'ProposalsDiscussionPlugin::Proposal', :foreign_key => 'parent_id' + has_many :discussion_proposals_comments, :class_name => 'Comment', :through => :discussion_proposals, :source => :comments + has_many :proposals_authors, :class_name => 'Person', :through => :children, :source => :created_by + + def proposals + allow_topics ? topics_proposals : discussion_proposals + end + + def proposals_comments + allow_topics ? topics_proposals_comments : discussion_proposals_comments + end settings_items :custom_body_label, :type => :string, :default => _('Body') + settings_items :allow_topics, :type => :boolean, :default => false - attr_accessible :custom_body_label + attr_accessible :custom_body_label, :allow_topics def self.short_description _("Discussion") @@ -21,22 +33,17 @@ class ProposalsDiscussionPlugin::Discussion < Folder def to_html(options = {}) discussion = self proc do - render :file => 'content_viewer/discussion', :locals => {:discussion => discussion} + if discussion.allow_topics + render :file => 'content_viewer/discussion_topics', :locals => {:discussion => discussion} + else + render :file => 'content_viewer/discussion', :locals => {:discussion => discussion} + end end end - def cache_key_with_person(params = {}, user = nil, language = 'en') - cache_key_without_person + (user ? "-#{user.identifier}" : '') - end - alias_method_chain :cache_key, :person - def posts #override posts method to list proposals in feed ProposalsDiscussionPlugin::Proposal.from_discussion(self) end - def accept_comments? - accept_comments - end - end diff --git a/lib/proposals_discussion_plugin/proposal.rb b/lib/proposals_discussion_plugin/proposal.rb index a0146c8..1e34eb9 100644 --- a/lib/proposals_discussion_plugin/proposal.rb +++ b/lib/proposals_discussion_plugin/proposal.rb @@ -3,7 +3,7 @@ class ProposalsDiscussionPlugin::Proposal < TinyMceArticle scope :private, lambda {|user| {:conditions => {:last_changed_by_id => user.id, :published => false}}} scope :from_discussion, lambda {|discussion| joins(:parent).where(['parents_articles.parent_id = ?', discussion.id])} - alias :topic :parent + belongs_to :topic, :foreign_key => :parent_id, :class_name => 'ProposalsDiscussionPlugin::Topic' def self.short_description _("Proposal") @@ -15,6 +15,9 @@ class ProposalsDiscussionPlugin::Proposal < TinyMceArticle validates_presence_of :abstract + def discussion + parent.kind_of?(ProposalsDiscussionPlugin::Discussion) ? parent : parent.discussion + end def to_html(options = {}) proposal = self @@ -35,8 +38,8 @@ class ProposalsDiscussionPlugin::Proposal < TinyMceArticle comments_count end - def normalized_score(holder) - (score/holder.max_score.to_f).round(2) + def normalized_score + (score/parent.max_score.to_f).round(2) end def cache_key_with_person(params = {}, user = nil, language = 'en') diff --git a/lib/proposals_discussion_plugin/proposals_holder.rb b/lib/proposals_discussion_plugin/proposals_holder.rb new file mode 100644 index 0000000..fe798bb --- /dev/null +++ b/lib/proposals_discussion_plugin/proposals_holder.rb @@ -0,0 +1,45 @@ +class ProposalsDiscussionPlugin::ProposalsHolder < Folder + + def accept_comments? + accept_comments + end + + def max_score + @max ||= [1, proposals.maximum(:comments_count)].max + end + + def proposals_per_day + result = proposals.group("date(created_at)").count + fill_empty_days(result) + end + + def comments_per_day + result = proposals.joins(:comments).group('date(comments.created_at)').count('comments.id') + fill_empty_days(result) + end + + def most_active_participants + proposals_authors.group('profiles.id').order('count(articles.id) DESC').includes(:environment, :preferred_domain, :image) + end + + def fill_empty_days(result) + from = created_at.to_date + (from..Date.today).inject({}) do |h, date| + h[date.to_s] = result[date.to_s] || 0 + h + end + end + + def proposal_tags + proposals.tag_counts.inject({}) do |memo,tag| + memo[tag.name] = tag.count + memo + end + end + + def cache_key_with_person(params = {}, user = nil, language = 'en') + cache_key_without_person + (user ? "-#{user.identifier}" : '') + end + alias_method_chain :cache_key, :person + +end diff --git a/lib/proposals_discussion_plugin/topic.rb b/lib/proposals_discussion_plugin/topic.rb index 4086018..fd31770 100644 --- a/lib/proposals_discussion_plugin/topic.rb +++ b/lib/proposals_discussion_plugin/topic.rb @@ -1,4 +1,4 @@ -class ProposalsDiscussionPlugin::Topic < Folder +class ProposalsDiscussionPlugin::Topic < ProposalsDiscussionPlugin::ProposalsHolder alias :discussion :parent @@ -18,10 +18,6 @@ class ProposalsDiscussionPlugin::Topic < Folder _('Container for proposals.') end - def most_active_participants - proposals_authors.group('profiles.id').order('count(articles.id) DESC').includes(:environment, :preferred_domain, :image) - end - def to_html(options = {}) topic = self proc do @@ -33,42 +29,4 @@ class ProposalsDiscussionPlugin::Topic < Folder true end - def max_score - @max ||= [1, proposals.maximum(:comments_count)].max - end - - def proposal_tags - proposals.tag_counts.inject({}) do |memo,tag| - memo[tag.name] = tag.count - memo - end - end - - def proposals_per_day - result = proposals.group("date(created_at)").count - fill_empty_days(result) - end - - def comments_per_day - result = proposals.joins(:comments).group('date(comments.created_at)').count('comments.id') - fill_empty_days(result) - end - - def fill_empty_days(result) - from = created_at.to_date - (from..Date.today).inject({}) do |h, date| - h[date.to_s] = result[date.to_s] || 0 - h - end - end - - def cache_key_with_person(params = {}, user = nil, language = 'en') - cache_key_without_person + (user ? "-#{user.identifier}" : '') - end - alias_method_chain :cache_key, :person - - def accept_comments? - accept_comments - end - end diff --git a/lib/proposals_discussion_plugin/topic_helper.rb b/lib/proposals_discussion_plugin/topic_helper.rb index 885c034..259b378 100644 --- a/lib/proposals_discussion_plugin/topic_helper.rb +++ b/lib/proposals_discussion_plugin/topic_helper.rb @@ -1,6 +1,7 @@ module ProposalsDiscussionPlugin::TopicHelper def topic_title(topic) + return if topic.blank? image_icon = topic.image ? image_tag(topic.image.public_filename(:thumb), :class => 'disable-zoom') : '' content_tag(:div, ( diff --git a/public/proposals_list.js b/public/proposals_list.js index 39307dc..b0bde48 100644 --- a/public/proposals_list.js +++ b/public/proposals_list.js @@ -10,7 +10,7 @@ jQuery(document).ready(function($) { }); function proposalsScroll() { - var scroll = $('.article-body-proposals-discussion-plugin_topic .topic-content .proposals_list .proposals'); + var scroll = $('.article-body-proposals-discussion-plugin_topic .topic-content .proposals_list .proposals, .article-body-proposals-discussion-plugin_discussion .proposals_list .proposals'); var nextSelector = 'div.more a'; if(scroll.data('jscroll')) scroll.data('jscroll', null); diff --git a/public/style.css b/public/style.css index 8241d62..ae3990f 100644 --- a/public/style.css +++ b/public/style.css @@ -149,13 +149,13 @@ form .proposals-discussion-plugin .body textarea { #content #article .topic-item h2, #content #article .article-body-proposals-discussion-plugin_topic h2, #content #article .topic h2, -#content .topic .topic-title h2 { +#content .topic-title h2 { background-color: #BDBDBD; margin: 0; } #content .topic-item h2 a, #article .article-body-proposals-discussion-plugin_topic h2 a, -#content .topic h2 a { +#content .topic-title h2 a { text-decoration: none; display: inline-block; color: white; @@ -213,7 +213,8 @@ form .proposals-discussion-plugin .body textarea { .article-body-proposals-discussion-plugin_topic .graph { float: left; } -.article-body-proposals-discussion-plugin_topic .graph #proposals-time { +.article-body-proposals-discussion-plugin_topic .graph #proposals-time, +.article-body-proposals-discussion-plugin_discussion .graph #proposals-time { height: 150px; width: 300px; } diff --git a/test/functional/content_viewer_controller_test.rb b/test/functional/content_viewer_controller_test.rb index 78cb446..48c35ea 100644 --- a/test/functional/content_viewer_controller_test.rb +++ b/test/functional/content_viewer_controller_test.rb @@ -18,4 +18,18 @@ class ContentViewerControllerTest < ActionController::TestCase assert_tag :tag => 'div', :attributes => {:class => 'content'}, :content => 'Proposal Body' end + should 'display discussion with topics' do + discussion.allow_topics = true + discussion.save! + get :view_page, discussion.url + assert_template 'content_viewer/discussion_topics' + end + + should 'display discussion without topics' do + discussion.allow_topics = false + discussion.save! + get :view_page, discussion.url + assert_template 'content_viewer/discussion' + end + end diff --git a/test/functional/proposals_discussion_plugin_profile_controller_test.rb b/test/functional/proposals_discussion_plugin_profile_controller_test.rb index 69642af..110bd0e 100644 --- a/test/functional/proposals_discussion_plugin_profile_controller_test.rb +++ b/test/functional/proposals_discussion_plugin_profile_controller_test.rb @@ -4,7 +4,7 @@ class ProposalsDiscussionPluginProfileControllerTest < ActionController::TestCas def setup @profile = fast_create(Community) - @discussion = fast_create(ProposalsDiscussionPlugin::Discussion, :profile_id => @profile.id) + @discussion = ProposalsDiscussionPlugin::Discussion.create!(:profile => @profile, :name => 'discussion',:allow_topics => true) @topic = fast_create(ProposalsDiscussionPlugin::Topic, :parent_id => @discussion.id, :profile_id => @profile.id) @person = create_user_with_permission('testinguser', 'post_content') login_as :testinguser diff --git a/test/functional/proposals_discussion_plugin_public_controller_test.rb b/test/functional/proposals_discussion_plugin_public_controller_test.rb index 822d151..927e17b 100644 --- a/test/functional/proposals_discussion_plugin_public_controller_test.rb +++ b/test/functional/proposals_discussion_plugin_public_controller_test.rb @@ -4,7 +4,7 @@ class ProposalsDiscussionPluginPublicControllerTest < ActionController::TestCase def setup @profile = fast_create(Community) - @discussion = fast_create(ProposalsDiscussionPlugin::Discussion, :profile_id => @profile.id) + @discussion = ProposalsDiscussionPlugin::Discussion.create!(:profile => @profile, :allow_topics => true, :name => 'discussion') @topic = fast_create(ProposalsDiscussionPlugin::Topic, :parent_id => @discussion.id, :profile_id => @profile.id) end diff --git a/test/unit/discussion_test.rb b/test/unit/discussion_test.rb index 80c975c..a1b05bd 100644 --- a/test/unit/discussion_test.rb +++ b/test/unit/discussion_test.rb @@ -21,7 +21,17 @@ class DiscussionTest < ActiveSupport::TestCase topic = fast_create(ProposalsDiscussionPlugin::Topic, :parent_id => discussion.id) proposal1 = fast_create(ProposalsDiscussionPlugin::Proposal, :parent_id => topic.id) proposal2 = fast_create(ProposalsDiscussionPlugin::Proposal, :parent_id => topic.id) - assert_equivalent [proposal1, proposal2], discussion.proposals + assert_equivalent [proposal1, proposal2], discussion.topics_proposals + end + + should 'return max score' do + person = fast_create(Person) + discussion = ProposalsDiscussionPlugin::Discussion.create!(:profile => person, :name => 'discussion') + proposal1 = ProposalsDiscussionPlugin::Proposal.create!(:parent => discussion, :profile => profile, :name => "proposal1", :abstract => 'abstract') + proposal2 = ProposalsDiscussionPlugin::Proposal.create!(:parent => discussion, :profile => profile, :name => "proposal2", :abstract => 'abstract') + 10.times { Comment.create!(:source => proposal1, :body => "comment", :author => person) } + 5.times { Comment.create!(:source => proposal2, :body => "comment", :author => person) } + assert_equal 10, discussion.max_score end end diff --git a/test/unit/proposal_test.rb b/test/unit/proposal_test.rb index 5813fff..b02785f 100644 --- a/test/unit/proposal_test.rb +++ b/test/unit/proposal_test.rb @@ -51,4 +51,14 @@ class ProposalTest < ActiveSupport::TestCase assert_equivalent [proposal1, proposal3], ProposalsDiscussionPlugin::Proposal.from_discussion(discussion) end + should 'return normalized score' do + discussion = ProposalsDiscussionPlugin::Discussion.create!(:profile => person, :name => 'discussion') + proposal1 = ProposalsDiscussionPlugin::Proposal.create!(:parent => discussion, :profile => profile, :name => "proposal1", :abstract => 'abstract') + proposal2 = ProposalsDiscussionPlugin::Proposal.create!(:parent => discussion, :profile => profile, :name => "proposal2", :abstract => 'abstract') + 10.times { Comment.create!(:source => proposal1, :body => "comment", :author => person) } + 5.times { Comment.create!(:source => proposal2, :body => "comment", :author => person) } + assert_equal 1, proposal1.reload.normalized_score + assert_equal 0.5, proposal2.reload.normalized_score + end + end diff --git a/test/unit/proposals_discussion_plugin_test.rb b/test/unit/proposals_discussion_plugin_test.rb index 1b1b235..4918fd8 100644 --- a/test/unit/proposals_discussion_plugin_test.rb +++ b/test/unit/proposals_discussion_plugin_test.rb @@ -32,6 +32,12 @@ class ProposalsDiscussionPluginTest < ActiveSupport::TestCase assert_includes plugin.content_types, ProposalsDiscussionPlugin::Proposal end + should 'return Proposal as a content type if parent is a Discussion and allow_topic is false' do + parent = ProposalsDiscussionPlugin::Discussion.create!(:profile => @profile, :name => 'discussion', :allow_topics => false) + @params[:parent_id] = parent.id + assert_includes plugin.content_types, ProposalsDiscussionPlugin::Proposal + end + should 'do not return Proposal as a content type if parent is nil' do @params[:parent_id] = nil assert_not_includes plugin.content_types, ProposalsDiscussionPlugin::Proposal diff --git a/test/unit/topic_test.rb b/test/unit/topic_test.rb index dccc0fa..4ffc07e 100644 --- a/test/unit/topic_test.rb +++ b/test/unit/topic_test.rb @@ -47,4 +47,13 @@ class TopicTest < ActiveSupport::TestCase assert_equal [author2, author1], topic.most_active_participants end + should 'return max score' do + person = fast_create(Person) + proposal1 = ProposalsDiscussionPlugin::Proposal.create!(:parent => topic, :profile => profile, :name => "proposal1", :abstract => 'abstract') + proposal2 = ProposalsDiscussionPlugin::Proposal.create!(:parent => topic, :profile => profile, :name => "proposal2", :abstract => 'abstract') + 10.times { Comment.create!(:source => proposal1, :body => "comment", :author => person) } + 5.times { Comment.create!(:source => proposal2, :body => "comment", :author => person) } + assert_equal 10, topic.max_score + end + end diff --git a/views/cms/proposals_discussion_plugin/_discussion.html.erb b/views/cms/proposals_discussion_plugin/_discussion.html.erb index 528d0ac..c9360bc 100644 --- a/views/cms/proposals_discussion_plugin/_discussion.html.erb +++ b/views/cms/proposals_discussion_plugin/_discussion.html.erb @@ -1,4 +1,3 @@ -sdadasda <%= required_fields_message %> <%= required f.text_field('name', :size => '64', :maxlength => 150) %> @@ -7,3 +6,4 @@ sdadasda <%= labelled_form_field(_('Description:'), text_area(:article, :body, :rows => 3, :cols => 64)) %> <%= f.text_field(:custom_body_label) %> +<%= labelled_form_field check_box(:article, :allow_topics) + _('Allow topics'), '' %> diff --git a/views/cms/proposals_discussion_plugin/_proposal.html.erb b/views/cms/proposals_discussion_plugin/_proposal.html.erb index 524ce58..96290c1 100644 --- a/views/cms/proposals_discussion_plugin/_proposal.html.erb +++ b/views/cms/proposals_discussion_plugin/_proposal.html.erb @@ -9,9 +9,7 @@