Commit 32ebb9f0dbb9bf2900d7f7268a5d4eb32ae7739c
1 parent
3ed0e3ac
Exists in
master
and in
11 other branches
proposals_discussion: added topic model
Showing
12 changed files
with
210 additions
and
54 deletions
Show diff stats
controllers/myprofile/proposals_discussion_plugin_myprofile_controller.rb
0 → 100644
@@ -0,0 +1,12 @@ | @@ -0,0 +1,12 @@ | ||
1 | +class ProposalsDiscussionPluginMyprofileController < MyProfileController | ||
2 | + | ||
3 | + def select_topic | ||
4 | + @discussion = profile.articles.find(params[:parent_id]) | ||
5 | + render :file => 'select_topic' | ||
6 | + end | ||
7 | + | ||
8 | + def new_proposal | ||
9 | + redirect_to :controller => 'cms', :action => 'new', :type => "ProposalsDiscussionPlugin::Proposal", :parent_id => params[:discussion][:topic] | ||
10 | + end | ||
11 | + | ||
12 | +end |
lib/proposals_discussion_plugin.rb
@@ -18,19 +18,26 @@ class ProposalsDiscussionPlugin < Noosfero::Plugin | @@ -18,19 +18,26 @@ class ProposalsDiscussionPlugin < Noosfero::Plugin | ||
18 | parent_id = context.params[:parent_id] | 18 | parent_id = context.params[:parent_id] |
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 unless parent | 20 | types << ProposalsDiscussionPlugin::Discussion unless parent |
21 | - types << ProposalsDiscussionPlugin::Proposal 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 | 23 | types |
23 | else | 24 | else |
24 | - [ProposalsDiscussionPlugin::Discussion, ProposalsDiscussionPlugin::Proposal] | 25 | + [ProposalsDiscussionPlugin::Discussion, |
26 | + ProposalsDiscussionPlugin::Topic, | ||
27 | + ProposalsDiscussionPlugin::Proposal] | ||
25 | end | 28 | end |
26 | end | 29 | end |
27 | 30 | ||
28 | def content_remove_new(page) | 31 | def content_remove_new(page) |
29 | - page.kind_of?(ProposalsDiscussionPlugin::Discussion) || page.kind_of?(ProposalsDiscussionPlugin::Proposal) | 32 | + page.kind_of?(ProposalsDiscussionPlugin::Discussion) || |
33 | + page.kind_of?(ProposalsDiscussionPlugin::Topic) || | ||
34 | + page.kind_of?(ProposalsDiscussionPlugin::Proposal) | ||
30 | end | 35 | end |
31 | 36 | ||
32 | def content_remove_upload(page) | 37 | def content_remove_upload(page) |
33 | - page.kind_of?(ProposalsDiscussionPlugin::Discussion) || page.kind_of?(ProposalsDiscussionPlugin::Proposal) | 38 | + page.kind_of?(ProposalsDiscussionPlugin::Discussion) || |
39 | + page.kind_of?(ProposalsDiscussionPlugin::Topic) || | ||
40 | + page.kind_of?(ProposalsDiscussionPlugin::Proposal) | ||
34 | end | 41 | end |
35 | 42 | ||
36 | end | 43 | end |
lib/proposals_discussion_plugin/discussion.rb
1 | class ProposalsDiscussionPlugin::Discussion < Folder | 1 | class ProposalsDiscussionPlugin::Discussion < Folder |
2 | 2 | ||
3 | + alias :topics :children | ||
4 | + | ||
5 | + has_many :proposals, :class_name => 'ProposalsDiscussionPlugin::Proposal', :through => :children, :source => :children | ||
6 | + | ||
3 | def self.short_description | 7 | def self.short_description |
4 | _("Discussion") | 8 | _("Discussion") |
5 | end | 9 | end |
6 | 10 | ||
7 | def self.description | 11 | def self.description |
8 | - _('Container for proposals.') | 12 | + _('Container for topics.') |
9 | end | 13 | end |
10 | 14 | ||
11 | def to_html(options = {}) | 15 | def to_html(options = {}) |
12 | - discussion = self | ||
13 | proc do | 16 | proc do |
14 | - render :file => 'content_viewer/discussion', :locals => {:discussion => discussion} | 17 | + render :file => 'content_viewer/discussion' |
15 | end | 18 | end |
16 | end | 19 | end |
17 | 20 |
lib/proposals_discussion_plugin/proposal.rb
1 | class ProposalsDiscussionPlugin::Proposal < TinyMceArticle | 1 | class ProposalsDiscussionPlugin::Proposal < TinyMceArticle |
2 | 2 | ||
3 | + alias :topic :parent | ||
4 | + | ||
3 | def self.short_description | 5 | def self.short_description |
4 | _("Proposal") | 6 | _("Proposal") |
5 | end | 7 | end |
@@ -10,4 +12,11 @@ class ProposalsDiscussionPlugin::Proposal < TinyMceArticle | @@ -10,4 +12,11 @@ class ProposalsDiscussionPlugin::Proposal < TinyMceArticle | ||
10 | 12 | ||
11 | validates_presence_of :abstract | 13 | validates_presence_of :abstract |
12 | 14 | ||
15 | + | ||
16 | + def to_html(options = {}) | ||
17 | + proc do | ||
18 | + render :file => 'content_viewer/proposal' | ||
19 | + end | ||
20 | + end | ||
21 | + | ||
13 | end | 22 | end |
@@ -0,0 +1,27 @@ | @@ -0,0 +1,27 @@ | ||
1 | +class ProposalsDiscussionPlugin::Topic < Folder | ||
2 | + | ||
3 | + alias :discussion :parent | ||
4 | + alias :proposals :children | ||
5 | + | ||
6 | + has_many :proposals_comments, :class_name => 'Comment', :through => :children, :source => :comments | ||
7 | + has_many :proposals_authors, :class_name => 'Person', :through => :children, :source => :created_by | ||
8 | + | ||
9 | + def self.short_description | ||
10 | + _("Discussion topic") | ||
11 | + end | ||
12 | + | ||
13 | + def self.description | ||
14 | + _('Container for proposals.') | ||
15 | + end | ||
16 | + | ||
17 | + def most_active_participants | ||
18 | + proposals_authors.group('profiles.id').order('count(articles.id) DESC').includes(:environment, :preferred_domain, :image) | ||
19 | + end | ||
20 | + | ||
21 | + def to_html(options = {}) | ||
22 | + proc do | ||
23 | + render :file => 'content_viewer/topic' | ||
24 | + end | ||
25 | + end | ||
26 | + | ||
27 | +end |
public/style.css
1 | .proposal { | 1 | .proposal { |
2 | background: rgb(236, 236, 236); | 2 | background: rgb(236, 236, 236); |
3 | - width: 31%; | 3 | + width: 100%; |
4 | min-width: 272px; | 4 | min-width: 272px; |
5 | - display: inline-block; | 5 | + display: table; |
6 | vertical-align: top; | 6 | vertical-align: top; |
7 | - margin: 5px 13px 5px 0; | 7 | + margin: 12px 13px 12px 0; |
8 | box-shadow: 5px 5px 5px -2px #ddd; | 8 | box-shadow: 5px 5px 5px -2px #ddd; |
9 | + padding: 5px; | ||
9 | } | 10 | } |
10 | 11 | ||
11 | -.proposal:hover { | 12 | +.article-body-proposals-discussion-plugin_discussion .actions, |
13 | +.article-body-proposals-discussion-plugin_topic .actions { | ||
14 | + margin: 10px 0 25px 0; | ||
15 | +} | ||
16 | + | ||
17 | +.proposal .content, .proposal .score, .proposal .topic { | ||
18 | + display: table-cell; | ||
19 | + border-right: 1px solid; | ||
20 | + border-color: rgb(201, 201, 201); | ||
21 | +} | ||
22 | +.proposal .topic { | ||
23 | + border-right: 0; | ||
24 | + text-align: center; | ||
25 | + width: 30%; | ||
26 | +} | ||
27 | +.proposal .score { | ||
28 | + width: 8%; | ||
29 | + text-align: center; | ||
30 | +} | ||
31 | + | ||
32 | +.proposal .content:hover, .proposal .topic:hover { | ||
12 | background: rgb(223, 223, 223); | 33 | background: rgb(223, 223, 223); |
13 | } | 34 | } |
14 | 35 | ||
15 | .proposal .title { | 36 | .proposal .title { |
16 | - background: rgba(0, 0, 0, 0.1); | ||
17 | font-weight: bold; | 37 | font-weight: bold; |
18 | font-size: 15px; | 38 | font-size: 15px; |
19 | } | 39 | } |
@@ -25,16 +45,12 @@ | @@ -25,16 +45,12 @@ | ||
25 | display: inline-block; | 45 | display: inline-block; |
26 | } | 46 | } |
27 | 47 | ||
28 | -#article .proposal .title { | ||
29 | - padding: 0px 5px; | ||
30 | -} | ||
31 | - | ||
32 | #article .proposal .title a { | 48 | #article .proposal .title a { |
33 | padding: 8px 0px; | 49 | padding: 8px 0px; |
34 | } | 50 | } |
35 | 51 | ||
36 | .proposal .content { | 52 | .proposal .content { |
37 | - padding: 5px; | 53 | + width: 60%; |
38 | color: rgb(83, 83, 83); | 54 | color: rgb(83, 83, 83); |
39 | } | 55 | } |
40 | 56 | ||
@@ -42,31 +58,6 @@ | @@ -42,31 +58,6 @@ | ||
42 | padding-top: 8px; | 58 | padding-top: 8px; |
43 | } | 59 | } |
44 | 60 | ||
45 | -.proposal .info { | ||
46 | - float: left; | ||
47 | -} | ||
48 | - | ||
49 | -.proposal .info .comments { | ||
50 | - background: url('/plugins/proposals_discussion/images/comments.gif') no-repeat left/15px; | ||
51 | - padding-left: 18px; | ||
52 | - display: inline; | ||
53 | - font-size: 10px; | ||
54 | - color: rgb(82, 82, 82); | ||
55 | - opacity: 0.6; | ||
56 | -} | ||
57 | - | ||
58 | -.proposal .actions { | ||
59 | - float: right; | ||
60 | -} | ||
61 | - | ||
62 | -.proposal .actions .vote-actions { | ||
63 | - position: static; | ||
64 | -} | ||
65 | - | ||
66 | -.proposal .actions .vote-actions .vote-action a { | ||
67 | - opacity: 0.6; | ||
68 | -} | ||
69 | - | ||
70 | form .proposals-discussion-plugin textarea { | 61 | form .proposals-discussion-plugin textarea { |
71 | width: 98%; | 62 | width: 98%; |
72 | } | 63 | } |
views/content_viewer/_proposal_card.html.erb
1 | <div class="proposal"> | 1 | <div class="proposal"> |
2 | - <div class="title"> | ||
3 | - <%= link_to proposal_card.name, proposal_card.view_url %> | ||
4 | - </div> | ||
5 | <div class="content"> | 2 | <div class="content"> |
6 | - <div class="info"> | ||
7 | - <div class="comments"><%= proposal_card.comments_count %></div> | ||
8 | - </div> | ||
9 | - <div class="actions"> | ||
10 | - <%= @plugins.dispatch(:article_header_extra_contents, proposal_card).collect { |content| instance_exec(&content) }.join("") %> | 3 | + <div class="title"> |
4 | + <%= link_to proposal_card.name, proposal_card.view_url %> | ||
11 | </div> | 5 | </div> |
12 | <div class="abstract"> | 6 | <div class="abstract"> |
13 | <%= link_to strip_tags(proposal_card.lead), proposal_card.view_url %> | 7 | <%= link_to strip_tags(proposal_card.lead), proposal_card.view_url %> |
14 | </div> | 8 | </div> |
15 | </div> | 9 | </div> |
10 | + <div class="score"> | ||
11 | + <%= proposal_card.comments_count %> | ||
12 | + </div> | ||
13 | + <div class="topic"> | ||
14 | + <%= link_to proposal_card.topic.title, proposal_card.topic.view_url %> | ||
15 | + </div> | ||
16 | </div> | 16 | </div> |
views/content_viewer/discussion.html.erb
@@ -2,11 +2,26 @@ | @@ -2,11 +2,26 @@ | ||
2 | <%= @page.body %> | 2 | <%= @page.body %> |
3 | </div> | 3 | </div> |
4 | 4 | ||
5 | -<%= link_to url_for({:controller => 'cms', :action => 'new', :type => "ProposalsDiscussionPlugin::Proposal", :parent_id => @page.id}), :class => 'button with-text icon-add' do %> | ||
6 | - <strong><%= _("New Proposal") %></strong> | 5 | +<% if @page.allow_create?(user) %> |
6 | +<div class="actions"> | ||
7 | + <%= link_to url_for({:controller => 'cms', :action => 'new', :type => "ProposalsDiscussionPlugin::Topic", :parent_id => @page.id}), :class => 'button with-text icon-add' do %> | ||
8 | + <strong><%= _("New Topic") %></strong> | ||
9 | + <% end %> | ||
10 | +</div> | ||
7 | <% end %> | 11 | <% end %> |
8 | 12 | ||
9 | -<div class="proposals"> | ||
10 | - <%= render :partial => 'content_viewer/proposal_card', :collection => discussion.children %> | 13 | +<div class="topics"> |
14 | + <h3><%= _('Discussion Topics') %></h3> | ||
15 | + <% @page.topics.includes(:profile).each do |topic| %> | ||
16 | + <div class="topic"><%= link_to topic.title, topic.view_url %></div> | ||
17 | + <% end %> | ||
11 | <div class="clear"></div> | 18 | <div class="clear"></div> |
12 | </div> | 19 | </div> |
20 | + | ||
21 | +<div class="actions"> | ||
22 | + <%= link_to url_for({:controller => 'proposals_discussion_plugin_myprofile', :action => 'select_topic', :parent_id => @page.id}), :class => 'button with-text icon-add' do %> | ||
23 | + <strong><%= _("Send my proposal") %></strong> | ||
24 | + <% end %> | ||
25 | +</div> | ||
26 | + | ||
27 | +<%= render :partial => 'content_viewer/proposals_list', :locals => {:holder => @page} %> |
@@ -0,0 +1,19 @@ | @@ -0,0 +1,19 @@ | ||
1 | +<div class="topic"> | ||
2 | + <h5><%= _('Discussion Topic') %></h5> | ||
3 | + <div class="content"><%= @page.topic.title %></div> | ||
4 | +</div> | ||
5 | + | ||
6 | +<div class="title"> | ||
7 | + <h5><%= _('Title') %></h4> | ||
8 | + <div class="content"><%= @page.title %></div> | ||
9 | +</div> | ||
10 | + | ||
11 | +<div class="abstract"> | ||
12 | + <h5><%= _('Abstract') %></h4> | ||
13 | + <div class="content"><%= @page.abstract %></div> | ||
14 | +</div> | ||
15 | + | ||
16 | +<div class="body"> | ||
17 | + <h5><%= _('Body') %></h4> | ||
18 | + <div class="content"><%= @page.body %></div> | ||
19 | +</div> |
@@ -0,0 +1,32 @@ | @@ -0,0 +1,32 @@ | ||
1 | +<div class="description"> | ||
2 | + <%= @page.body %> | ||
3 | +</div> | ||
4 | +<h4><%= @page.discussion.title %></h4> | ||
5 | + | ||
6 | +<div class="proposals-count"> | ||
7 | + <span class="label"><%= _('Number of Proposals: ') %></span> | ||
8 | + <span class="content"><%= @page.proposals.count %></span> | ||
9 | +</div> | ||
10 | +<div class="participants-count"> | ||
11 | + <span class="label"><%= _('Number of Participants: ') %></span> | ||
12 | + <span class="content"><%= @page.proposals_authors.count %></span> | ||
13 | +</div> | ||
14 | +<div class="comments-count"> | ||
15 | + <span class="label"><%= _('Number of Comments: ') %></span> | ||
16 | + <span class="content"><%= @page.proposals_comments.count %></span> | ||
17 | +</div> | ||
18 | +<div class="active-participants"> | ||
19 | + <span class="label"><%= _('Most active: ') %></span> | ||
20 | + <span class="content"> | ||
21 | + <% @page.most_active_participants.each do |author| %> | ||
22 | + <%= link_to profile_image(author, :icon), author.url, :title => author.name %> | ||
23 | + <% end %> | ||
24 | + </span> | ||
25 | +</div> | ||
26 | + | ||
27 | +<%= render :partial => 'content_viewer/proposals_list', :locals => {:holder => @page} %> | ||
28 | + | ||
29 | +<div class="proposals"> | ||
30 | + <%= render :partial => 'content_viewer/proposal_card', :collection => @page.proposals.includes(:parent, :profile) %> | ||
31 | + <div class="clear"></div> | ||
32 | +</div> |
@@ -0,0 +1,37 @@ | @@ -0,0 +1,37 @@ | ||
1 | +<script> | ||
2 | + jQuery(document).ready(function($){ | ||
3 | + $("#topics").accordion(); | ||
4 | + $('#topics input[type=radio],label').on('click',function(e){e.stopPropagation();}); | ||
5 | + $('#topics h4').click(function(e){ | ||
6 | + e.stopPropagation(); | ||
7 | + $(this).find('input:radio').prop('checked', true); | ||
8 | + }); | ||
9 | + }); | ||
10 | +</script> | ||
11 | + | ||
12 | +<div class="proposals-discussion-plugin select-topic"> | ||
13 | + <h1><%= @discussion.title %></h1> | ||
14 | + <%= form_for :discussion, :url => {:controller => 'proposals_discussion_plugin_myprofile', :action => 'new_proposal'} do %> | ||
15 | + | ||
16 | + <h3><%= _('Select topic') %></h3> | ||
17 | + <div id="topics"> | ||
18 | + | ||
19 | + <% @discussion.children.each do |topic| %> | ||
20 | + <h4> | ||
21 | + <%= radio_button_tag('discussion[topic]', topic.id) %> | ||
22 | + <%= topic.title %> | ||
23 | + </h4> | ||
24 | + <div class="content"> | ||
25 | + <%= topic.body %> | ||
26 | + </div> | ||
27 | + <% end %> | ||
28 | + | ||
29 | + <div class="clear"></div> | ||
30 | + </div> | ||
31 | + | ||
32 | + <div class="actions"> | ||
33 | + <%= submit_button(:next, _('Next')) %> | ||
34 | + <%= button :cancel, _('Cancel'), @discussion.view_url %> | ||
35 | + </div> | ||
36 | + <% end %> | ||
37 | +</div> |