mirror of
https://github.com/discourse/discourse.git
synced 2026-03-03 23:54:20 +08:00
Following PR #36711 which enabled the refreshed review UI for all users, this commit removes the old feature flag infrastructure and cleans up legacy code that is no longer needed. Backend Changes: - Removed ReviewableActionLog model and its spec entirely - Removed CalculateFinalStatusFromLogs service and spec - Removed site settings: force_old_reviewable_ui, reviewable_old_moderator_actions - Simplified ReviewableActionBuilder — stripped out legacy action-building methods (build_user_actions_bundle, build_post_actions_bundle, build_new_separated_actions) - Cleaned up reviewable models (ReviewableFlaggedPost, ReviewablePost, ReviewableQueuedPost, ReviewableUser, Chat::ReviewableMessage, ReviewablePostVotingComment) — removed unused/legacy action definitions - Removed legacy specs for action builder, action logs, flagged post actions, post actions, user actions, and status-from-logs - Updated system tests and page objects to reflect the new UI structure Frontend Changes: - Deleted legacy components: reviewable-item.gjs, reviewable-user.gjs, review-index-legacy.gjs - Renamed reviewable-refresh/ → reviewable/ — moved all sub-components (created-by, flagged-post, item, post, queued-post, topic-link, user, etc.) out of the refresh directory into the canonical reviewable/ namespace - Simplified reviewable/item.gjs — removed feature flag conditionals and legacy code paths - Cleaned up review/index.gjs and review/show.gjs templates — removed branching between old/new UI - Updated plugin components (chat, AI, post-voting) to import from reviewable/ instead of reviewable-refresh/ - Removed acceptance tests (review-test.js) replaced by system tests - Renamed and updated integration tests from reviewable-refresh/* to reviewable/* Plan for next PRs: - Move plugins from Pages::RefreshedReview to Pages::Review - Move plugins to import from `reviewable/` and not `refreshed-reviewable/` - Move reviewable-user.js import in plugin to use `reviewable/user.js` - Remove unused settings like `reviewable_old_moderator_actions` from plugins - Delete `Pages::RefreshedReview` - Delete `reviewable-refresh/` directory - Delete `reviewable-user.js` component - Delete `reviewable_old_moderator_actions` site setting Plugins PRs: - https://github.com/discourse/discourse-akismet/pull/203 - https://github.com/discourse/discourse-antivirus/pull/98 - https://github.com/discourse/discourse-category-experts/pull/223
198 lines
4.8 KiB
Ruby
198 lines
4.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class ReviewableSerializer < ApplicationSerializer
|
|
class_attribute :_payload_for_serialization
|
|
|
|
attributes(
|
|
:id,
|
|
:type,
|
|
:type_source,
|
|
:topic_id,
|
|
:topic_url,
|
|
:target_type,
|
|
:target_id,
|
|
:target_url,
|
|
:target_created_at,
|
|
:target_deleted_at,
|
|
:topic_tags,
|
|
:category_id,
|
|
:created_at,
|
|
:can_edit,
|
|
:score,
|
|
:version,
|
|
:target_created_by_trust_level,
|
|
:created_from_flag?,
|
|
)
|
|
|
|
attribute :status_for_database, key: :status
|
|
|
|
has_one :created_by, serializer: UserWithCustomFieldsSerializer, root: "users"
|
|
has_one :target_created_by, root: "users"
|
|
has_one :target_deleted_by, serializer: BasicUserSerializer, root: "users"
|
|
has_one :topic, serializer: ListableTopicSerializer
|
|
has_many :editable_fields, serializer: ReviewableEditableFieldSerializer, embed: :objects
|
|
has_many :reviewable_scores, serializer: ReviewableScoreSerializer
|
|
has_many :bundled_actions, serializer: ReviewableBundledActionSerializer
|
|
has_many :reviewable_notes, serializer: ReviewableNoteSerializer
|
|
has_many :reviewable_histories, serializer: ReviewableHistorySerializer
|
|
has_one :claimed_by, serializer: ReviewableClaimedTopicSerializer
|
|
|
|
# Used to keep track of our payload attributes
|
|
class_attribute :_payload_for_serialization
|
|
|
|
def bundled_actions
|
|
args = {}
|
|
args[:claimed_by] = claimed_by if @options[:claimed_topics]
|
|
object.actions_for(scope, args).bundles
|
|
end
|
|
|
|
def editable_fields
|
|
args = {}
|
|
args[:claimed_by] = claimed_by if @options[:claimed_topics]
|
|
object.editable_for(scope, args).to_a
|
|
end
|
|
|
|
def can_edit
|
|
editable_fields.present?
|
|
end
|
|
|
|
def claimed_by
|
|
return nil if @options[:claimed_topics].blank?
|
|
@options[:claimed_topics][object.topic_id]
|
|
end
|
|
|
|
def include_claimed_by?
|
|
@options[:claimed_topics]
|
|
end
|
|
|
|
def self.create_attribute(name, field)
|
|
attribute(name)
|
|
|
|
class_eval <<~RUBY
|
|
def #{name}
|
|
#{field}
|
|
end
|
|
|
|
def include_#{name}?
|
|
#{name}.present?
|
|
end
|
|
RUBY
|
|
end
|
|
|
|
# This is easier than creating an AMS method for each attribute
|
|
def self.target_attributes(*attributes)
|
|
attributes.each { |a| create_attribute(a, "object.target&.#{a}") }
|
|
end
|
|
|
|
def self.payload_attributes(*attributes)
|
|
self._payload_for_serialization ||= []
|
|
self._payload_for_serialization += attributes.map(&:to_s)
|
|
end
|
|
|
|
def attributes
|
|
super.tap do |data|
|
|
data[:removed_topic_id] = object.topic_id unless object.topic
|
|
|
|
if object.target.present?
|
|
# Automatically add the target id as a "good name" for example a target_type of `User`
|
|
# becomes `user_id`
|
|
data[:"#{object.target_type.downcase}_id"] = object.target_id
|
|
end
|
|
|
|
if self.class._payload_for_serialization.present?
|
|
data[:payload] = (object.payload || {}).slice(*self.class._payload_for_serialization)
|
|
end
|
|
end
|
|
end
|
|
|
|
def created_from_flag?
|
|
false
|
|
end
|
|
|
|
def topic_tags
|
|
object.topic.tags.map { |t| { id: t.id, name: t.name, slug: t.slug } }
|
|
end
|
|
|
|
def include_topic_tags?
|
|
object.topic.present? && SiteSetting.tagging_enabled?
|
|
end
|
|
|
|
def target_created_at
|
|
object.target&.created_at
|
|
end
|
|
|
|
def include_target_created_at?
|
|
object.target_type == "Post"
|
|
end
|
|
|
|
def target_url
|
|
if object.target.is_a?(Post) && object.target.present?
|
|
return Discourse.base_url + object.target.url
|
|
end
|
|
topic_url
|
|
end
|
|
|
|
def include_target_url?
|
|
target_url.present?
|
|
end
|
|
|
|
def topic_url
|
|
object.topic&.url
|
|
end
|
|
|
|
def include_topic_url?
|
|
topic_url.present?
|
|
end
|
|
|
|
def include_topic_id?
|
|
object.topic_id.present?
|
|
end
|
|
|
|
def include_category_id?
|
|
object.category_id.present?
|
|
end
|
|
|
|
def target_created_by_trust_level
|
|
object&.target_created_by&.trust_level
|
|
end
|
|
|
|
def target_deleted_at
|
|
target = target_post_with_deleted
|
|
return target.deleted_at if target&.deleted_at.present?
|
|
target.revisions.order(created_at: :desc).pick(:created_at) if target&.user_deleted?
|
|
end
|
|
|
|
def include_target_deleted_at?
|
|
include_target_deleted_by? && target_deleted_at.present?
|
|
end
|
|
|
|
def target_deleted_by
|
|
target = target_post_with_deleted
|
|
target&.deleted_by || (target if target&.user_deleted?)&.user
|
|
end
|
|
|
|
def include_target_deleted_by?
|
|
return false unless object.target_type == "Post"
|
|
target = target_post_with_deleted
|
|
target&.deleted_by_id.present? || target&.user_deleted?
|
|
end
|
|
|
|
def target_post_with_deleted
|
|
return @target_post_with_deleted if defined?(@target_post_with_deleted)
|
|
@target_post_with_deleted =
|
|
object.target_type == "Post" ? Post.with_deleted.find_by(id: object.target_id) : nil
|
|
end
|
|
|
|
def target_created_by
|
|
user =
|
|
if object.target_type == "User"
|
|
object.target
|
|
else
|
|
object.target_created_by
|
|
end
|
|
|
|
return if user.blank?
|
|
|
|
FlaggedUserSerializer.new(user, scope: scope, root: false)
|
|
end
|
|
end
|