mirror of
https://github.com/indentlabs/notebook.git
synced 2025-10-26 11:19:22 +00:00
127 lines
4.0 KiB
Ruby
127 lines
4.0 KiB
Ruby
class ContentSerializer
|
|
attr_accessor :id, :name, :user, :universe
|
|
|
|
attr_accessor :categories
|
|
attr_accessor :fields
|
|
attr_accessor :attribute_values
|
|
attr_accessor :page_tags
|
|
attr_accessor :documents
|
|
|
|
attr_accessor :raw_model
|
|
attr_accessor :class_name, :class_color, :class_icon
|
|
|
|
attr_accessor :data
|
|
# name: 'blah,
|
|
# categories: [
|
|
# {
|
|
# name: 'category one',
|
|
# fields: [{
|
|
# id: field.name,
|
|
# label: field.label,
|
|
# value: field.attribute_values.find_by(..)
|
|
# }]
|
|
# }
|
|
|
|
def initialize(content)
|
|
# One query per table; lets not muck with joins yet
|
|
# self.attribute_values = Attribute.where(entity_type: content.page_type, entity_id: content.id)
|
|
# self.fields = AttributeField.where(id: self.attribute_values.pluck(:attribute_field_id).uniq)
|
|
self.categories = content.class.attribute_categories(content.user)
|
|
self.fields = AttributeField.where(attribute_category_id: self.categories.map(&:id))
|
|
self.attribute_values = Attribute.where(attribute_field_id: self.fields.map(&:id), entity_type: content.page_type, entity_id: content.id)
|
|
|
|
self.id = content.id
|
|
self.name = content.name
|
|
self.user = content.user
|
|
self.universe = content.is_a?(Universe) ? self : content.universe
|
|
|
|
self.raw_model = content
|
|
|
|
self.class_name = content.class.name
|
|
self.class_color = content.class.color
|
|
self.class_icon = content.class.icon
|
|
|
|
self.page_tags = content.page_tags.pluck(:tag) || []
|
|
self.documents = content.documents || []
|
|
|
|
self.data = {
|
|
name: content.try(:name),
|
|
description: content.try(:description),
|
|
universe: self.universe.nil? ? nil : {
|
|
id: self.universe.id,
|
|
name: self.universe.try(:name)
|
|
},
|
|
categories: self.categories.map { |category|
|
|
{
|
|
name: category.name,
|
|
label: category.label,
|
|
icon: category.icon,
|
|
hidden: !!category.hidden,
|
|
fields: self.fields.select { |field| field.attribute_category_id == category.id }.map { |field|
|
|
{
|
|
id: field.name,
|
|
label: field.label,
|
|
type: field.field_type,
|
|
hidden: !!field.hidden,
|
|
position: field.position,
|
|
old_column_source: field.old_column_source,
|
|
value: value_for(field, content)
|
|
}
|
|
}.sort do |a, b|
|
|
if a[:position] && b[:position]
|
|
a[:position] <=> b[:position]
|
|
|
|
else
|
|
a_value = case a[:type]
|
|
when 'name' then 0
|
|
when 'universe' then 1
|
|
else 2 # 'text_area', 'link'
|
|
end
|
|
|
|
b_value = case b[:type]
|
|
when 'name' then 0
|
|
when 'universe' then 1
|
|
else 2
|
|
end
|
|
|
|
a_value <=> b_value
|
|
end
|
|
end
|
|
}
|
|
}
|
|
}
|
|
|
|
# Do a little number crunching
|
|
self.data[:categories].each do |category|
|
|
completed_fields = category[:fields].select { |field| field[:value].present? }.count.to_f
|
|
total_fields = category[:fields].count
|
|
|
|
if total_fields.zero?
|
|
category[:percent_complete] = nil
|
|
else
|
|
category[:percent_complete] = (completed_fields / total_fields * 100).round
|
|
end
|
|
end
|
|
|
|
self.data
|
|
end
|
|
|
|
def value_for(attribute_field, content)
|
|
case attribute_field.field_type
|
|
when 'link'
|
|
self.raw_model.send(attribute_field.old_column_source)
|
|
|
|
when 'tags'
|
|
self.raw_model.page_tags
|
|
|
|
else # text_area, name, universe, etc
|
|
#codesmell here: we shouldn't ever have multiple attribute values but for some reason we do sometimes (in collaboration?)
|
|
self.attribute_values.order('created_at desc').detect { |value|
|
|
value.entity_type == content.page_type &&
|
|
value.entity_id == content.id &&
|
|
value.attribute_field_id == attribute_field.id
|
|
}.try(:value) || ""
|
|
end
|
|
end
|
|
end
|