From 21b1d00205a8a20a2691696b6806156b501d5c4b Mon Sep 17 00:00:00 2001 From: iagirre Date: Wed, 16 May 2018 13:03:56 +0200 Subject: [PATCH] Add backend for the moderators Add new routes for the proposal notifications edition and abilities to let moderators edit it (mark as ignored, hide, etc.). The notifications are not flaggable because they doesn't work like that, but in a similar way. The moderator/administrator is in charge of hidding them through the UI, so the normal users don't flag it as inappropriate. New controller Moderation::ProposalNotification to manage the moderators work. --- .../proposal_notifications_controller.rb | 30 +++++++++++++++++++ app/controllers/concerns/moderate_actions.rb | 2 +- app/controllers/concerns/polymorphic.rb | 2 +- .../proposal_notifications_controller.rb | 24 +++++++++++++++ app/controllers/proposals_controller.rb | 1 + app/models/abilities/moderation.rb | 11 +++++++ app/models/proposal_notification.rb | 28 ++++++++++++++++- app/models/user.rb | 2 ++ config/routes/admin.rb | 7 +++++ config/routes/moderation.rb | 5 ++++ 10 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 app/controllers/admin/proposal_notifications_controller.rb create mode 100644 app/controllers/moderation/proposal_notifications_controller.rb diff --git a/app/controllers/admin/proposal_notifications_controller.rb b/app/controllers/admin/proposal_notifications_controller.rb new file mode 100644 index 000000000..625e670fa --- /dev/null +++ b/app/controllers/admin/proposal_notifications_controller.rb @@ -0,0 +1,30 @@ +class Admin::ProposalNotificationsController < Admin::BaseController + + has_filters %w{without_confirmed_hide all with_confirmed_hide}, only: :index + + before_action :load_proposal, only: [:confirm_hide, :restore] + + def index + @proposal_notifications = ProposalNotification.only_hidden.send(@current_filter).order(hidden_at: :desc) + .page(params[:page]) + end + + def confirm_hide + @proposal_notification.confirm_hide + redirect_to request.query_parameters.merge(action: :index) + end + + def restore + @proposal_notification.restore + @proposal_notification.ignore_flag + Activity.log(current_user, :restore, @proposal_notification) + redirect_to request.query_parameters.merge(action: :index) + end + + private + + def load_proposal + @proposal_notification = ProposalNotification.with_hidden.find(params[:id]) + end + +end diff --git a/app/controllers/concerns/moderate_actions.rb b/app/controllers/concerns/moderate_actions.rb index 05aa0e97f..98e67bc2b 100644 --- a/app/controllers/concerns/moderate_actions.rb +++ b/app/controllers/concerns/moderate_actions.rb @@ -57,4 +57,4 @@ module ModerateActions :author_id end -end \ No newline at end of file +end diff --git a/app/controllers/concerns/polymorphic.rb b/app/controllers/concerns/polymorphic.rb index 6ac4b5c1c..8fd4ab312 100644 --- a/app/controllers/concerns/polymorphic.rb +++ b/app/controllers/concerns/polymorphic.rb @@ -26,4 +26,4 @@ module Polymorphic send("#{resource_name}_params") end -end \ No newline at end of file +end diff --git a/app/controllers/moderation/proposal_notifications_controller.rb b/app/controllers/moderation/proposal_notifications_controller.rb new file mode 100644 index 000000000..64a2cae5a --- /dev/null +++ b/app/controllers/moderation/proposal_notifications_controller.rb @@ -0,0 +1,24 @@ +class Moderation::ProposalNotificationsController < Moderation::BaseController + include ModerateActions + + has_filters %w{pending_review all ignored}, only: :index + has_orders %w{created_at moderated}, only: :index + + before_action :load_resources, only: [:index, :moderate] + + load_and_authorize_resource + + def hide + ProposalNotification.find(params[:id]).update(moderated: true) + end + + private + + def resource_name + 'proposal_notification' + end + + def resource_model + ProposalNotification + end +end diff --git a/app/controllers/proposals_controller.rb b/app/controllers/proposals_controller.rb index 7e679a05d..f43bc8ad9 100644 --- a/app/controllers/proposals_controller.rb +++ b/app/controllers/proposals_controller.rb @@ -24,6 +24,7 @@ class ProposalsController < ApplicationController def show super @notifications = @proposal.notifications + @notifications = @proposal.notifications.not_moderated @related_contents = Kaminari.paginate_array(@proposal.relationed_contents).page(params[:page]).per(5) redirect_to proposal_path(@proposal), status: :moved_permanently if request.path != proposal_path(@proposal) diff --git a/app/models/abilities/moderation.rb b/app/models/abilities/moderation.rb index f0f823de1..801e752ed 100644 --- a/app/models/abilities/moderation.rb +++ b/app/models/abilities/moderation.rb @@ -52,6 +52,17 @@ module Abilities can :block, User cannot :block, User, id: user.id + + can :hide, ProposalNotification, hidden_at: nil + cannot :hide, ProposalNotification, author_id: user.id + + can :ignore_flag, ProposalNotification, ignored_at: nil, hidden_at: nil + cannot :ignore_flag, ProposalNotification, author_id: user.id + + can :moderate, ProposalNotification + cannot :moderate, ProposalNotification, author_id: user.id + + can :index, ProposalNotification end end end diff --git a/app/models/proposal_notification.rb b/app/models/proposal_notification.rb index 590f19208..4d931d065 100644 --- a/app/models/proposal_notification.rb +++ b/app/models/proposal_notification.rb @@ -10,7 +10,19 @@ class ProposalNotification < ActiveRecord::Base validates :proposal, presence: true validate :minimum_interval - scope :public_for_api, -> { where(proposal_id: Proposal.public_for_api.pluck(:id)) } + scope :public_for_api, -> { where(proposal_id: Proposal.public_for_api.pluck(:id)) } + scope :sort_by_created_at, -> { reorder(created_at: :desc) } + scope :sort_by_moderated, -> { reorder(moderated: :desc) } + + scope :moderated, -> { where(moderated: true) } + scope :not_moderated, -> { where(moderated: false) } + scope :pending_review, -> { moderated.where(ignored_at: nil) } + scope :ignored, -> { moderated.where.not(ignored_at: nil) } + + acts_as_paranoid column: :hidden_at + include ActsAsParanoidAliases + + after_create :set_author def minimum_interval return true if proposal.try(:notifications).blank? @@ -25,4 +37,18 @@ class ProposalNotification < ActiveRecord::Base proposal end + def ignore_flag + update(ignored_at: Time.current) + end + + def ignored? + ignored_at.present? + end + + private + + def set_author + self.update(author_id: self.proposal.author_id) if self.proposal + end + end diff --git a/app/models/user.rb b/app/models/user.rb index aaec3e411..47e7f8c2c 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -182,12 +182,14 @@ class User < ActiveRecord::Base debates_ids = Debate.where(author_id: id).pluck(:id) comments_ids = Comment.where(user_id: id).pluck(:id) proposal_ids = Proposal.where(author_id: id).pluck(:id) + proposal_notification_ids = ProposalNotification.where(author_id: id).pluck(:id) hide Debate.hide_all debates_ids Comment.hide_all comments_ids Proposal.hide_all proposal_ids + ProposalNotification.hide_all proposal_notification_ids end def erase(erase_reason = nil) diff --git a/config/routes/admin.rb b/config/routes/admin.rb index 374b4512c..001456f6e 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -38,6 +38,13 @@ namespace :admin do get :summary, on: :collection end + resources :proposal_notifications, only: :index do + member do + put :restore + put :confirm_hide + end + end + resources :budgets do member do put :calculate_winners diff --git a/config/routes/moderation.rb b/config/routes/moderation.rb index 77eb0a216..90dc9be27 100644 --- a/config/routes/moderation.rb +++ b/config/routes/moderation.rb @@ -22,4 +22,9 @@ namespace :moderation do put :hide, on: :member put :moderate, on: :collection end + + resources :proposal_notifications, only: :index do + put :hide, on: :member + put :moderate, on: :collection + end end