mirror of
https://github.com/discourse/discourse.git
synced 2024-12-30 17:36:27 +08:00
8a89a77248
Followup c7e471d35a
It is currently possible to add a bundle (which is a collection
of actions used for a dropdown on the client) for a reviewable
via actions.add_bundle and then never add any actions to it.
This causes the client to explode, as seen in the referenced
commit, because of the way our store expects to resolve objects
referenced by ID that are passed down by the serializer, which
then causes Ember to have an unrecoverable render error.
Fixing this on the serializer level is not really possible because
of all the ActiveModel::Serializer magic that serializes
objects by ID reference when doing things like has_many.
`Reviewable#actions_for` is a better place to do this anyway,
because this is the main location where the bundles and actions
are built for every action via the serializer.
76 lines
2.0 KiB
Ruby
76 lines
2.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "reviewable/collection"
|
|
|
|
class Reviewable < ActiveRecord::Base
|
|
class Actions < Reviewable::Collection
|
|
attr_reader :bundles, :reviewable
|
|
|
|
def initialize(reviewable, guardian, args = nil)
|
|
super(reviewable, guardian, args)
|
|
@bundles = []
|
|
end
|
|
|
|
# Add common actions here to make them easier for reviewables to re-use. If it's a
|
|
# one off, add it manually.
|
|
def self.common_actions
|
|
{
|
|
approve: Action.new(:approve, "thumbs-up", "reviewables.actions.approve.title"),
|
|
reject: Action.new(:reject, "thumbs-down", "reviewables.actions.reject.title"),
|
|
delete: Action.new(:delete, "trash-can", "reviewables.actions.delete_single.title"),
|
|
}
|
|
end
|
|
|
|
class Bundle < Item
|
|
attr_accessor :icon, :label, :actions
|
|
|
|
def initialize(id, icon: nil, label: nil)
|
|
super(id)
|
|
@icon = icon
|
|
@label = label
|
|
@actions = []
|
|
end
|
|
|
|
def empty?
|
|
@actions.empty?
|
|
end
|
|
end
|
|
|
|
class Action < Item
|
|
attr_accessor :icon,
|
|
:button_class,
|
|
:label,
|
|
:description,
|
|
:confirm_message,
|
|
:client_action,
|
|
:require_reject_reason,
|
|
:custom_modal
|
|
|
|
def initialize(id, icon = nil, button_class = nil, label = nil)
|
|
super(id)
|
|
@icon, @button_class, @label = icon, button_class, label
|
|
end
|
|
|
|
def server_action
|
|
id.split("-").last
|
|
end
|
|
end
|
|
|
|
def add_bundle(id, icon: nil, label: nil)
|
|
bundle = Bundle.new(id, icon: icon, label: label)
|
|
@bundles << bundle
|
|
bundle
|
|
end
|
|
|
|
def add(id, bundle: nil)
|
|
id = [reviewable.target_type&.underscore, id].compact_blank.join("-")
|
|
action = Actions.common_actions[id] || Action.new(id)
|
|
yield action if block_given?
|
|
@content << action
|
|
|
|
bundle ||= add_bundle(id)
|
|
bundle.actions << action
|
|
end
|
|
end
|
|
end
|