# Use it like this:
# Avo::ItemGrapher.new(resource).render(view: :edit)
class Avo::ItemGrapher
attr_reader :item
def initialize(item)
@item = item
end
def decode_item(item)
result = ""
result << "──" * (item[:level])
result << "→"
result << item[:id]
if item[:items].present?
item[:items].each do |itm|
result << "
"
result << decode_item(itm)
end
end
result
end
def unwrap(i, level = 0, view: :show)
result = []
i.items.each do |item|
label = ""
label << item.class.name.demodulize
label << " "
if item.respond_to?(:name)
label << "{#{item.name}}"
label << " "
end
label << (item.hydrate(view: view).visible_in_view?(view: view) ? "visible" : "invisible")
if item.class.ancestors.include?(Avo::Concerns::HasItems)
if item.visible_items.present?
label << " | HAS_ITEMS #{item.visible_items.count} items"
# abort item.visible_items.inspect
label << item.visible_items.map(&:class).inspect
else
label << " | DOES_NOT_HAVE_ITEMS"
end
end
if item.respond_to?(:is_empty?)
label << " "
label << (item.is_empty? ? "[IS EMPTY!]" : "[#{item.visible_items.count}]")
end
payload = if item.respond_to?(:items) && item.items.present?
{
id: label,
items: unwrap(item, level + 1),
}
else
{
id: label
}
end
result << {
**payload,
level: level,
}
end
result
end
def render(**args)
result = unwrap(item, **args)
.map do |item|
decode_item(item)
end
.join("
")
"
#{result}".html_safe end end