app/models/mixins/custom_actions_mixin.rb
module CustomActionsMixin
extend ActiveSupport::Concern
included do
has_many :custom_button_sets, :as => :owner, :dependent => :destroy
has_many :custom_button_events, :foreign_key => :target_id, :dependent => :destroy
virtual_has_many :custom_buttons
virtual_has_one :custom_actions, :class_name => "Hash"
virtual_has_one :custom_action_buttons, :class_name => "Array"
end
def custom_actions(applies_to = self)
{
:buttons => serialize_buttons_if_visible(custom_buttons, applies_to),
:button_groups => custom_button_sets_with_generics.collect do |button_set|
button_set.serializable_hash.merge(
:buttons => serialize_buttons_if_visible(button_set.children, applies_to)
)
end.reject { |button_group| button_group[:buttons].empty? }
}
end
def custom_action_buttons(applies_to = self)
filter_by_visibility(custom_buttons + custom_button_sets_with_generics.collect(&:children).flatten, applies_to)
end
def generic_button_group
generic_custom_buttons.includes(:custom_button_sets)
.select { |button| button.custom_button_sets.present? }
end
def custom_button_sets_with_generics
custom_button_sets + generic_button_group.flat_map(&:custom_button_sets).uniq
end
def custom_buttons
generic_custom_buttons.includes(:custom_button_sets)
.select { |b| b.custom_button_sets.blank? } + direct_custom_buttons
end
def direct_custom_buttons
CustomButton.buttons_for(self).includes(:custom_button_sets)
.select { |b| b.custom_button_sets.blank? }
end
def filter_by_visibility(buttons, applies_to = self)
buttons.select { |b| b.evaluate_visibility_expression_for(target_for_expression(b, applies_to)) }
end
def serialize_button(button, applies_to = self)
obj = target_for_expression(button, applies_to)
button.expanded_serializable_hash.merge("enabled" => button.evaluate_enablement_expression_for(obj))
end
def generic_custom_buttons
CustomButton.buttons_for(self.class.base_model.name)
end
private
def serialize_buttons_if_visible(buttons, applies_to)
filter_by_visibility(buttons, applies_to).collect { |button| serialize_button(button, applies_to) }
end
def target_for_expression(button, applies_to)
button.applies_to_class == applies_to.class.base_model.name ? applies_to : self
end
end