mirror of
https://github.com/discourse/discourse.git
synced 2025-03-07 07:35:27 +08:00

We found score hard to understand. It is still there behind the scenes for sorting purposes, but it is no longer shown. You can now filter by minimum priority (low, med, high) instead of score.
197 lines
5.7 KiB
Ruby
197 lines
5.7 KiB
Ruby
class ReviewablesController < ApplicationController
|
|
requires_login
|
|
|
|
PER_PAGE = 10
|
|
|
|
before_action :version_required, only: [:update, :perform]
|
|
|
|
def index
|
|
offset = params[:offset].to_i
|
|
|
|
if params[:type].present?
|
|
raise Discourse::InvalidParameter.new(:type) unless Reviewable.valid_type?(params[:type])
|
|
end
|
|
|
|
status = (params[:status] || 'pending').to_sym
|
|
raise Discourse::InvalidParameter.new(:status) unless allowed_statuses.include?(status)
|
|
|
|
topic_id = params[:topic_id] ? params[:topic_id].to_i : nil
|
|
category_id = params[:category_id] ? params[:category_id].to_i : nil
|
|
|
|
filters = {
|
|
status: status,
|
|
category_id: category_id,
|
|
topic_id: topic_id,
|
|
priority: params[:priority],
|
|
username: params[:username],
|
|
type: params[:type]
|
|
}
|
|
|
|
total_rows = Reviewable.list_for(current_user, filters).count
|
|
reviewables = Reviewable.list_for(current_user, filters.merge(limit: PER_PAGE, offset: offset)).to_a
|
|
|
|
# This is a bit awkward, but ActiveModel serializers doesn't seem to serialize STI. Note `hash`
|
|
# is mutated by the serializer and contains the side loaded records which must be merged in the end.
|
|
hash = {}
|
|
json = {
|
|
reviewables: reviewables.map! do |r|
|
|
result = r.serializer.new(r, root: nil, hash: hash, scope: guardian).as_json
|
|
hash[:bundled_actions].uniq!
|
|
(hash['actions'] || []).uniq!
|
|
result
|
|
end,
|
|
meta: filters.merge(
|
|
total_rows_reviewables: total_rows, types: meta_types, reviewable_types: Reviewable.types,
|
|
reviewable_count: Reviewable.list_for(current_user).count
|
|
)
|
|
}
|
|
if (offset + PER_PAGE) < total_rows
|
|
json[:meta][:load_more_reviewables] = review_path(filters.merge(offset: offset + PER_PAGE))
|
|
end
|
|
json.merge!(hash)
|
|
|
|
render_json_dump(json, rest_serializer: true)
|
|
end
|
|
|
|
def topics
|
|
topic_ids = Set.new
|
|
|
|
stats = {}
|
|
unique_users = {}
|
|
|
|
# topics isn't indexed on `reviewable_score` and doesn't know what the current user can see,
|
|
# so let's query from the inside out.
|
|
pending = Reviewable.viewable_by(current_user).pending
|
|
pending = pending.where("score >= ?", Reviewable.min_score_for_priority)
|
|
|
|
pending.each do |r|
|
|
topic_ids << r.topic_id
|
|
|
|
meta = stats[r.topic_id] ||= { count: 0, unique_users: 0 }
|
|
users = unique_users[r.topic_id] ||= Set.new
|
|
|
|
r.reviewable_scores.each do |rs|
|
|
users << rs.user_id
|
|
meta[:count] += 1
|
|
end
|
|
meta[:unique_users] = users.size
|
|
end
|
|
|
|
topics = Topic.where(id: topic_ids).order('reviewable_score DESC')
|
|
render_serialized(topics, ReviewableTopicSerializer, root: 'reviewable_topics', stats: stats)
|
|
end
|
|
|
|
def show
|
|
reviewable = find_reviewable
|
|
|
|
render_serialized(
|
|
reviewable,
|
|
reviewable.serializer,
|
|
rest_serializer: true,
|
|
root: 'reviewable',
|
|
meta: {
|
|
types: meta_types
|
|
}
|
|
)
|
|
end
|
|
|
|
def destroy
|
|
reviewable = Reviewable.find_by(id: params[:reviewable_id], created_by: current_user)
|
|
raise Discourse::NotFound.new if reviewable.blank?
|
|
|
|
reviewable.perform(current_user, :delete)
|
|
|
|
render json: success_json
|
|
end
|
|
|
|
def update
|
|
reviewable = find_reviewable
|
|
editable = reviewable.editable_for(guardian)
|
|
raise Discourse::InvalidAccess.new unless editable.present?
|
|
|
|
# Validate parameters are all editable
|
|
edit_params = params[:reviewable] || {}
|
|
edit_params.each do |name, value|
|
|
if value.is_a?(ActionController::Parameters)
|
|
value.each do |pay_name, pay_value|
|
|
raise Discourse::InvalidAccess.new unless editable.has?("#{name}.#{pay_name}")
|
|
end
|
|
else
|
|
raise Discourse::InvalidAccess.new unless editable.has?(name)
|
|
end
|
|
end
|
|
|
|
begin
|
|
if reviewable.update_fields(edit_params, current_user, version: params[:version].to_i)
|
|
result = edit_params.merge(version: reviewable.version)
|
|
render json: result
|
|
else
|
|
render_json_error(reviewable.errors)
|
|
end
|
|
rescue Reviewable::UpdateConflict
|
|
return render_json_error(I18n.t('reviewables.conflict'), status: 409)
|
|
end
|
|
end
|
|
|
|
def perform
|
|
args = { version: params[:version].to_i }
|
|
|
|
begin
|
|
result = find_reviewable.perform(current_user, params[:action_id].to_sym, args)
|
|
rescue Reviewable::InvalidAction => e
|
|
# Consider InvalidAction an InvalidAccess
|
|
raise Discourse::InvalidAccess.new(e.message)
|
|
rescue Reviewable::UpdateConflict
|
|
return render_json_error(I18n.t('reviewables.conflict'), status: 409)
|
|
end
|
|
|
|
if result.success?
|
|
render_serialized(result, ReviewablePerformResultSerializer)
|
|
else
|
|
render_json_error(result)
|
|
end
|
|
end
|
|
|
|
def settings
|
|
raise Discourse::InvalidAccess.new unless current_user.admin?
|
|
|
|
post_action_types = PostActionType.where(id: PostActionType.flag_types.values).order('id')
|
|
data = { reviewable_score_types: post_action_types }
|
|
|
|
if request.put?
|
|
params[:bonuses].each do |id, bonus|
|
|
PostActionType.where(id: id).update_all(score_bonus: bonus.to_f)
|
|
end
|
|
end
|
|
|
|
render_serialized(data, ReviewableSettingsSerializer, rest_serializer: true)
|
|
end
|
|
|
|
protected
|
|
|
|
def find_reviewable
|
|
reviewable = Reviewable.viewable_by(current_user).where(id: params[:reviewable_id]).first
|
|
raise Discourse::NotFound.new if reviewable.blank?
|
|
reviewable
|
|
end
|
|
|
|
def allowed_statuses
|
|
@allowed_statuses ||= (%i[reviewed all] + Reviewable.statuses.keys)
|
|
end
|
|
|
|
def version_required
|
|
if params[:version].blank?
|
|
render_json_error(I18n.t('reviewables.missing_version'), status: 422)
|
|
end
|
|
end
|
|
|
|
def meta_types
|
|
{
|
|
created_by: 'user',
|
|
target_created_by: 'user',
|
|
reviewed_by: 'user'
|
|
}
|
|
end
|
|
|
|
end
|