From fd453c35b35357625cc759ccb6375d65346501c9 Mon Sep 17 00:00:00 2001
From: Ábner Silva de Oliveira
Date: Thu, 18 Jun 2015 15:26:06 -0300
Subject: [PATCH] moderação das propostas.
---
controllers/myprofile/proposals_discussion_plugin_evaluate_tasks_controller.rb | 41 +++++++++++++++++++++++++++++++++++++++++
controllers/myprofile/proposals_discussion_plugin_tasks_controller.rb | 35 +++++++++++++++++++++++++++++++++++
db/migrate/20150618100000_create_proposal_evaluation_table.rb | 23 +++++++++++++++++++++++
lib/proposals_discussion_plugin/proposal_evaluation.rb | 7 +++++++
lib/proposals_discussion_plugin/proposal_task.rb | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
public/images/approval.png | Bin 0 -> 414 bytes
public/images/reproval.png | Bin 0 -> 381 bytes
public/style.css | 30 ++++++++++++++++++++++++++++++
views/proposals_discussion_plugin_tasks/_task_accept_details.html.erb | 0
views/proposals_discussion_plugin_tasks/_task_reject_details.html.erb | 5 +++++
views/tasks/_task.html.erb | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
views/tasks/index.html.erb | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
views/tasks/proposals_discussion_plugin/_proposal_task_accept_details.html.erb | 4 ----
13 files changed, 463 insertions(+), 6 deletions(-)
create mode 100644 controllers/myprofile/proposals_discussion_plugin_evaluate_tasks_controller.rb
create mode 100644 controllers/myprofile/proposals_discussion_plugin_tasks_controller.rb
create mode 100644 db/migrate/20150618100000_create_proposal_evaluation_table.rb
create mode 100644 lib/proposals_discussion_plugin/proposal_evaluation.rb
create mode 100644 public/images/approval.png
create mode 100644 public/images/reproval.png
create mode 100644 views/proposals_discussion_plugin_tasks/_task_accept_details.html.erb
create mode 100644 views/proposals_discussion_plugin_tasks/_task_reject_details.html.erb
create mode 100644 views/tasks/_task.html.erb
create mode 100644 views/tasks/index.html.erb
delete mode 100644 views/tasks/proposals_discussion_plugin/_proposal_task_accept_details.html.erb
diff --git a/controllers/myprofile/proposals_discussion_plugin_evaluate_tasks_controller.rb b/controllers/myprofile/proposals_discussion_plugin_evaluate_tasks_controller.rb
new file mode 100644
index 0000000..1c8d394
--- /dev/null
+++ b/controllers/myprofile/proposals_discussion_plugin_evaluate_tasks_controller.rb
@@ -0,0 +1,41 @@
+class ProposalsDiscussionPluginEvaluateTasksController < MyProfileController
+
+ protect :view_tasks, :profile, :only => [:flag_approve_proposal, :flag_reject_proposal]
+
+ def flag_approve_proposal
+ if request.post? && params[:task_id]
+ result = {
+ success: false,
+ message: _('Error flagging proposal. Please, contact the system admin')
+ }
+
+ task = Task.to(profile).find_by_id params[:task_id]
+ save = task.flag_accept_proposal(current_person)
+
+ if save
+ result = {:success => true }
+ end
+ end
+
+ render json: result
+ end
+
+ def flag_reject_proposal
+ if request.post? && params[:task_id]
+ result = {
+ success: false,
+ message: _('Error flagging proposal. Please, contact the system admin')
+ }
+
+ task = Task.to(profile).find_by_id params[:task_id]
+ save = task.flag_reject_proposal(current_person)
+
+ if save
+ result = {:success => true }
+ end
+ end
+
+ render json: result
+ end
+
+end
diff --git a/controllers/myprofile/proposals_discussion_plugin_tasks_controller.rb b/controllers/myprofile/proposals_discussion_plugin_tasks_controller.rb
new file mode 100644
index 0000000..0f434eb
--- /dev/null
+++ b/controllers/myprofile/proposals_discussion_plugin_tasks_controller.rb
@@ -0,0 +1,35 @@
+class ProposalsDiscussionPluginTasksController < TasksController
+
+ def index
+ @email_templates = profile.email_templates.find_all_by_template_type(:task_rejection)
+
+ @filter_type = params[:filter_type].presence
+ @filter_text = params[:filter_text].presence
+ @filter_responsible = params[:filter_responsible]
+ @filter_tags = params[:filter_tags]
+
+ @view_only = !current_person.has_permission?(:perform_task, profile)
+
+ @task_tags = [OpenStruct.new(:name => _('All'), :id => nil) ] + Task.all_tags
+ @task_types = Task.pending_types_for(profile)
+
+ if @view_only
+ @tasks = Task.pending_all(profile, false, false).order_by('created_at', 'asc')
+ @tasks = @tasks.where(:responsible_id => current_person.id)
+ else
+
+ @tasks = ProposalsDiscussionPlugin::ProposalTask.pending_evaluated(profile, @filter_type, @filter_text).order_by('created_at', 'asc')
+ @tasks = @tasks.where(:responsible_id => @filter_responsible.to_i != -1 ? @filter_responsible : nil) if @filter_responsible.present?
+ @tasks = @tasks.tagged_with(@filter_tags, any: true) if @filter_tags.present?
+ end
+
+ @tasks = @tasks.paginate(:per_page => Task.per_page, :page => params[:page])
+
+ @failed = params ? params[:failed] : {}
+
+ @responsible_candidates = profile.members.by_role(profile.roles.reject {|r| !r.has_permission?('perform_task')}) if profile.organization?
+
+
+ end
+
+end
diff --git a/db/migrate/20150618100000_create_proposal_evaluation_table.rb b/db/migrate/20150618100000_create_proposal_evaluation_table.rb
new file mode 100644
index 0000000..0e95fdb
--- /dev/null
+++ b/db/migrate/20150618100000_create_proposal_evaluation_table.rb
@@ -0,0 +1,23 @@
+class CreateProposalEvaluationTable < ActiveRecord::Migration
+ def self.up
+ create_table :proposals_discussion_plugin_proposal_evaluations do |t|
+ t.integer "proposal_task_id"
+ t.integer "evaluator_id"
+ t.integer "flagged_status"
+ t.timestamps
+ end
+ add_index(
+ :proposals_discussion_plugin_proposal_evaluations,
+ [:proposal_task_id],
+ name: 'index_proposals_discussion_plugin_proposal_task_id'
+ )
+ add_index(
+ :proposals_discussion_plugin_proposal_evaluations,
+ [:evaluator_id],
+ name: 'index_proposals_discussion_plugin_proposal_evaluator_id'
+ )
+ end
+ def self.down
+ drop_table :proposals_discussion_plugin_proposal_evaluations
+ end
+end
diff --git a/lib/proposals_discussion_plugin/proposal_evaluation.rb b/lib/proposals_discussion_plugin/proposal_evaluation.rb
new file mode 100644
index 0000000..cb78e10
--- /dev/null
+++ b/lib/proposals_discussion_plugin/proposal_evaluation.rb
@@ -0,0 +1,7 @@
+class ProposalsDiscussionPlugin::ProposalEvaluation < Noosfero::Plugin::ActiveRecord
+ belongs_to :proposal_task
+ belongs_to :evaluated_by, :class_name => 'Person', :foreign_key => :evaluator_id
+
+ attr_accessor :flagged_status
+
+end
diff --git a/lib/proposals_discussion_plugin/proposal_task.rb b/lib/proposals_discussion_plugin/proposal_task.rb
index 3270786..bfbe558 100644
--- a/lib/proposals_discussion_plugin/proposal_task.rb
+++ b/lib/proposals_discussion_plugin/proposal_task.rb
@@ -10,6 +10,16 @@ class ProposalsDiscussionPlugin::ProposalTask < Task
settings_items :article, :type => Hash, :default => {}
settings_items :closing_statment, :article_parent_id
+
+ scope :pending_evaluated, lambda { |profile, filter_type, filter_text|
+ self
+ .to(profile)
+ .without_spam.pending
+ .of(filter_type)
+ .like('data', filter_text)
+ .where(:status => ProposalsDiscussionPlugin::ProposalTask::Status.evaluated_statuses)
+ }
+
before_create do |task|
if !task.target.nil?
organization = task.target
@@ -18,8 +28,80 @@ class ProposalsDiscussionPlugin::ProposalTask < Task
end
end
+ def unflagged?
+ ! flagged?
+ end
+
+ def flagged?
+ flagged_for_approval? || flagged_for_reproval?
+ end
+
+ def flagged_for_approval?
+ Status::FLAGGED_FOR_APPROVAL.eql?(self.status)
+ end
+
+ def flagged_for_reproval?
+ Status::FLAGGED_FOR_REPROVAL.eql?(self.status)
+ end
+
after_create :schedule_spam_checking
+ module Status
+ FLAGGED_FOR_APPROVAL = 5
+ FLAGGED_FOR_REPROVAL = 6
+
+ class << self
+ def names
+ [
+ nil,
+ N_('Active'), N_('Cancelled'), N_('Finished'),
+ N_('Hidden'), N_('Flagged for Approval'), N_('Flagged for Reproval')
+ ]
+ end
+
+ def evaluated_statuses
+ [
+ FLAGGED_FOR_APPROVAL,
+ FLAGGED_FOR_REPROVAL
+ ]
+ end
+ end
+ end
+
+
+ def flag_accept_proposal(evaluated_by)
+ transaction do
+ if evaluated_by
+ ProposalsDiscussionPlugin::ProposalEvaluation.new do |evaluation|
+ evaluation.evaluated_by = evaluated_by
+ evaluation.flagged_status = Status::FLAGGED_FOR_APPROVAL
+ evaluation.proposal_task = self
+ evaluation.save!
+ end
+ end
+ self.status = Status::FLAGGED_FOR_APPROVAL
+ self.save!
+ return true
+ end
+ end
+
+ def flag_reject_proposal(evaluated_by)
+ transaction do
+ if evaluated_by
+ ProposalsDiscussionPlugin::ProposalEvaluation.new do |evaluation|
+ evaluation.evaluated_by = evaluated_by
+ evaluation.flagged_status = Status::FLAGGED_FOR_REPROVAL
+ evaluation.proposal_task = self
+ evaluation.save!
+ end
+ end
+ self.status = Status::FLAGGED_FOR_REPROVAL
+ self.save!
+ return true
+ end
+ end
+
+
def schedule_spam_checking
self.delay.check_for_spam
end
@@ -65,7 +147,6 @@ class ProposalsDiscussionPlugin::ProposalTask < Task
article_abstract
end
-
def information
{:message => _("%{requestor} wants to send the following proposal.
%{abstract}"), :variables => {:abstract => abstract}}
end
@@ -90,7 +171,7 @@ class ProposalsDiscussionPlugin::ProposalTask < Task
# def article_title
# article ? article.title : _('(The original text was removed)')
# end
-
+
# def article
# Article.find_by_id data[:article_id]
# end
diff --git a/public/images/approval.png b/public/images/approval.png
new file mode 100644
index 0000000..be13a3e
Binary files /dev/null and b/public/images/approval.png differ
diff --git a/public/images/reproval.png b/public/images/reproval.png
new file mode 100644
index 0000000..bab6f37
Binary files /dev/null and b/public/images/reproval.png differ
diff --git a/public/style.css b/public/style.css
index 9d0e302..642def4 100644
--- a/public/style.css
+++ b/public/style.css
@@ -319,3 +319,33 @@ form .proposals-discussion-plugin .body textarea {
#content .article-body.article-body-proposals-discussion-plugin_proposal .discussion {
color: gray;
}
+
+.evaluation_bar {
+ width: 400px;
+}
+
+.evaluation_button {
+ cursor: pointer;
+}
+
+.evaluation_button img {
+ float:left;
+ width: 32px;
+ height:32px;
+ margin-left: 30px;
+}
+
+.evaluation_button span {
+ margin-left: 8px;
+ font-size: 24px;
+ width: auto;
+ float:left;
+}
+
+.evaluation_button.approval span {
+ color: green;
+}
+
+.evaluation_button.reproval span {
+ color: red;
+}
diff --git a/views/proposals_discussion_plugin_tasks/_task_accept_details.html.erb b/views/proposals_discussion_plugin_tasks/_task_accept_details.html.erb
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/views/proposals_discussion_plugin_tasks/_task_accept_details.html.erb
diff --git a/views/proposals_discussion_plugin_tasks/_task_reject_details.html.erb b/views/proposals_discussion_plugin_tasks/_task_reject_details.html.erb
new file mode 100644
index 0000000..6a0452c
--- /dev/null
+++ b/views/proposals_discussion_plugin_tasks/_task_reject_details.html.erb
@@ -0,0 +1,5 @@
+<% if @email_templates.present? %>
+
+ <%= labelled_form_field(_('Select a rejection email template:'), select_tag("tasks[#{task.id}][task][email_template_id]", options_from_collection_for_select(@email_templates, :id, :name), :include_blank => true, 'data-url' => url_for(:controller => 'email_templates', :action => 'show_parsed'))) %>
+
+<% end %>
diff --git a/views/tasks/_task.html.erb b/views/tasks/_task.html.erb
new file mode 100644
index 0000000..317049f
--- /dev/null
+++ b/views/tasks/_task.html.erb
@@ -0,0 +1,105 @@
+
+
+ <%= render :partial => 'task_icon', :locals => {:task => task} %>
+
+ <% if !@view_only && profile.organization? && @responsible_candidates.present? %>
+
+ <%= _('Assign to:') %>
+
+ <% change_responsible_url = url_for :action => :change_responsible, :controller => :tasks %>
+ <%= select_tag "tasks[#{task.id}][responsible]", options_from_collection_for_select(@responsible_candidates, :id, :name, task.responsible.present? ? task.responsible.id : nil), :include_blank => true, :onchange => "change_task_responsible(this);", 'data-old-responsible' => task.responsible.present? ? task.responsible.id : nil, 'data-task' => task.id, 'data-url' => change_responsible_url %>
+
+
+ <% end %>
+
+ <% if @view_only && task.responsible.present? %>
+
+ <%= _('Assigned to:') %>
+ <%= task.responsible.name %>
+
+ <% end %>
+
+
+ <% unless @view_only %>
+ <%=
+ labelled_radio_button(_("Accept"), "tasks[#{task.id}][decision]", 'finish', task.flagged_for_approval? || task.default_decision == 'accept',
+ :id => "decision-finish-#{task.id}",
+ :class => 'task_accept_radio',
+ :disabled => task.accept_disabled?,
+ :task_id => "#{task.id}") +
+ labelled_radio_button(_("Reject"), "tasks[#{task.id}][decision]", 'cancel', task.flagged_for_reproval? || task.default_decision == 'reject',
+ :id => "decision-cancel-#{task.id}",
+ :class => 'task_reject_radio',
+ :disabled => task.reject_disabled?,
+ :task_id => "#{task.id}") +
+ labelled_radio_button(_("Skip"), "tasks[#{task.id}][decision]", 'skip', task.default_decision == 'skip' && task.unflagged?,
+ :id => "decision-skip-#{task.id}",
+ :class => 'task_skip_radio',
+ :disabled => task.skip_disabled?,
+ :task_id => "#{task.id}")
+ %>
+ <% end %>
+
+
+
<%= show_time(task.created_at) %>
+
+ <%= render :partial => 'task_title', :locals => {:task => task} %>
+
+
+ <%= task_information(task) %>
+
+
+
+ <%= fields_for "tasks[#{task.id}][task]", task do |f| %>
+ <% if task.accept_details and !@view_only %>
+
+ <%= render :partial => partial_for_class(task.class, nil, :accept_details), :locals => {:task => task, :f => f} %>
+
+ <% end %>
+
+ <% if task.reject_details and !@view_only %>
+
+ <%= render :partial => partial_for_class(task.class, nil, :reject_details), :locals => {:task => task, :f => f} %>
+
+ <% end %>
+
+ <% if @view_only %>
+
+ <% end %>
+ <%#= select_tag "tasks[#{task.id}][setting][evaluation_flag]",
+ options_for_select(
+ [_('FLAGGED_FOR_APPROVAL'),_('FLAGGED_FOR_REPROVAL')],(task.flagged_status.present? ? task.flagged_status : nil)
+ ),
+ {
+ :include_blank => true,
+ :onchange => "change_flagged_status(this);",
+ 'data-old-responsible' => task.flagged_status.present? ? task.flagged_status.id : nil,
+ 'data-task' => task.id, 'data-url' => 'change_flagged_status_url'
+ } %>
+
+
+
+
+
+
+ <% end %>
+
+
diff --git a/views/tasks/index.html.erb b/views/tasks/index.html.erb
new file mode 100644
index 0000000..c21fe8e
--- /dev/null
+++ b/views/tasks/index.html.erb
@@ -0,0 +1,134 @@
+<%= stylesheet_link_tag 'tasks' %>
+
+<%= _("%s's pending tasks") % profile.name %>
+
+
+<%
+ type_collection = [[nil, _('All')]] + @task_types
+%>
+
+<% if !@failed.blank? %>
+
+ <% @failed.each do |error, tasks_descriptions|%>
+
<%= error %>
+
<%=_("This error happened with the following tasks: ")%>
+
+ <% tasks_descriptions.each do |description| %>
+ - <%= description %>
+ <% end %>
+
+ <% end %>
+
+<% end %>
+
+<% unless @view_only %>
+ <%= form_tag '#', :method => 'get' do %>
+ <%= field_set_tag _('Filter'), :class => 'filter_fields' do %>
+
+ <%= labelled_select(_('Type of task')+': ', :filter_type, :first, :last, @filter_type, type_collection, {:id => 'filter-type'}) %>
+
+
+ <%= labelled_text_field(_("Text filter")+': ', :filter_text, nil, {:id => 'filter-text',:value => @filter_text}) %>
+
+ <% if profile.organization? %>
+
+ <%= labelled_select(_('Assigned to')+': ', :filter_responsible, :id, :name, @filter_responsible, [OpenStruct.new(:name => _('All'), :id => nil), OpenStruct.new(:name => _('Unassigned'), :id => -1)] + @responsible_candidates, :class => 'filter_responsible') %>
+
+ <% end %>
+
+ <%= labelled_select(_('Tags')+': ', :filter_tags, :id, :name, @filter_tags, @task_tags, {:id => 'filter-add-tag'}) %>
+ <%= text_field_tag( :filter_tags, @filter_tags, :size => 36, :class => 'filter-tags' ) %>
+
+
+
+ <%= submit_button(:search, _('Search')) %>
+
+ <% end %>
+ <% end %>
+<% end %>
+<% if @tasks.empty? %>
+
+ <%= _('No pending tasks for %s') % profile.name %>
+
+<% else %>
+ <%= form_tag :action => 'close' do%>
+ <% button_bar(:class => 'task-actions') do %>
+ <%# FiXME button(:edit, _('View my requests'), :action => 'list_requested') %>
+ <%# FIXME button('menu-mail', _('Send request'), :action => 'new') %>
+ <%= submit_button :save, _("Apply!") %>
+ <%= button(:edit, _('View processed tasks'), :action => 'processed') %>
+ <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %>
+ <% end unless @view_only %>
+
+
+ <% unless @view_only %>
+
+ <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "up-set-all-tasks-to") %>
+
+ <% end %>
+
+
+ <%= render :partial => 'task', :collection => @tasks %>
+
+
+ <% unless @view_only %>
+
+ <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "down-set-all-tasks-to") %>
+
+ <% end %>
+
+
+
+
+ <%= pagination_links(@tasks)%>
+
+ <% button_bar(:class => 'task-actions') do %>
+ <%# FiXME button(:edit, _('View my requests'), :action => 'list_requested') %>
+ <%# FIXME button('menu-mail', _('Send request'), :action => 'new') %>
+ <%= submit_button :save, _("Apply!") %>
+ <%= button(:edit, _('View processed tasks'), :action => 'processed') %>
+ <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %>
+ <% end unless @view_only %>
+ <% end %>
+<% end %>
+
+
+
+<%= javascript_include_tag 'tasks' %>
+
+
diff --git a/views/tasks/proposals_discussion_plugin/_proposal_task_accept_details.html.erb b/views/tasks/proposals_discussion_plugin/_proposal_task_accept_details.html.erb
deleted file mode 100644
index f26767f..0000000
--- a/views/tasks/proposals_discussion_plugin/_proposal_task_accept_details.html.erb
+++ /dev/null
@@ -1,4 +0,0 @@
-<%= select_profile_folder(_('Select the folder where the article must be published'), "tasks[#{task.id}][task][article_parent_id]", task.target, task.article_parent_id) %>
-
-<%= labelled_form_field _('Comment for author'), f.text_field(:closing_statment, :style => 'width: 488px; height: 30px') %>
-
--
libgit2 0.21.2