-
Arnaud Levy authoredArnaud Levy authored
base.rb 3.75 KiB
class Communication::Block::Template::Base
class_attribute :components_descriptions,
:layouts,
:element_class
attr_reader :block
def self.has_string(property)
has_component property, :string
end
def self.has_text(property)
has_component property, :text
end
def self.has_rich_text(property)
has_component property, :rich_text
end
def self.has_select(property, **args)
has_component property, :select
end
def self.has_image(property)
has_component property, :image
end
def self.has_layouts(list)
self.layouts = list
has_component :layout, :layout
end
def self.has_elements(element_class)
self.element_class = element_class
end
def self.has_component(property, kind)
self.components_descriptions ||= []
self.components_descriptions << { name: property, type: kind }
class_eval <<-CODE, __FILE__, __LINE__ + 1
def #{property}_component
@#{property}_component ||= Communication::Block::Component::#{kind.to_s.classify}.new(:#{property}, self)
end
def #{property}
#{property}_component.data
end
def #{property}=(value)
#{property}_component.data = value
end
CODE
end
# It can be initialized with no data, for a full block
# or with data provided, for nested elements
def initialize(block, json)
@block = block
@elements = []
self.data = json
end
# Transforms raw json into ruby objects, based on components
def data=(value)
if value.is_a? String
json = JSON.parse(value)
elsif value.is_a? Hash
json = value
else
json = default_data
end
components.each do |component|
next unless json.has_key? component.property
component.data = json[component.property]
end
return unless has_elements?
# Objects are initialized from the database,
# then data from the form replaces data from the db.
# We need to reset elements, otherwise it's never deleted.
@elements = []
json['elements'].each do |json|
@elements << default_element(json)
end
end
# Reads the data from the components
def data
hash = default_data
components.each do |component|
hash[component.property] = component.data
end
if has_elements?
hash['elements'] = []
elements.each do |element|
hash['elements'] << element.data
end
end
hash
end
def git_dependencies
unless @git_dependencies
@git_dependencies = []
components.each do |component|
add_dependency component.git_dependencies
end
elements.each do |element|
add_dependency element.git_dependencies
end
@git_dependencies.uniq!
end
@git_dependencies
end
def active_storage_blobs
[]
end
def has_elements?
!self.class.element_class.nil?
end
def default_element(data = nil)
return unless has_elements?
self.class.element_class.new block, data
end
def elements
@elements
end
def default_layout
self.class.layouts&.first
end
def layout
data['layout']
end
def kind
block.template_kind
end
def blob_with_id(id)
university.active_storage_blobs.find id
end
def default_data
{
'layout' => default_layout,
'elements' => []
}
end
protected
def build_git_dependencies
end
def add_dependency(dependency)
if dependency.is_a? Array
@git_dependencies += dependency
else
@git_dependencies += [dependency]
end
end
def components
return [] if self.class.components_descriptions.nil?
self.class.components_descriptions.map do |component_description|
send "#{component_description[:name]}_component"
end
end
def university
block.university
end
end