mirror of
https://github.com/discourse/discourse.git
synced 2025-02-05 19:11:13 +00:00
8a89a77248
Followup c7e471d35a0d394899eda5af26de64511e199cc6 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
|