# Adminpanel API # This file must be included on every adminpanel resource. module Adminpanel module Base extend ActiveSupport::Concern module ClassMethods FILE_FIELD_NAME = 'adminpanel_file_field' def mount_images(relation) has_many relation, dependent: :destroy, as: :model accepts_nested_attributes_for relation, allow_destroy: true after_save :destroy_unattached_images after_save :correlative_order_gallery, if: Proc.new { |model| model.class.has_sortable_gallery? } end # implementing cache by default. def belongs_to(name, scope = nil, options = {}) super(name, scope, options.reverse_merge!({touch: true})) end # The fields and the types that should be used to generate form # and display fields def form_attributes [] end # The name that is going to be shown in the new button and that is going # to be pluralized (if not overwritten) to generate collection_name def display_name 'please overwrite self.display_name' end # fontawesome icon to be used in the side-menu def icon 'truck' end # The word that is going to be shown in the side menu, routes and # breadcrumb. def collection_name display_name.pluralize(I18n.default_locale) end def get_attribute_label(field) form_attributes.each do |attribute| attribute.each do |name, properties| if name == field return properties['label'] end end end return field end # returns the attributes that should be shown in the correspondin view # (some attributes may be filtered from the index table, from the show # or even both) def display_attributes(type) display_attributes = [] form_attributes.each do |attribute| attribute.each do |_, properties| if ( properties['show'].nil? || properties['show'] == 'true' || ( properties['show'] == type && properties['type'] != FILE_FIELD_NAME #file fields get only displayed in form ) ) display_attributes << attribute end end end return display_attributes end # Check if this models has a gallery in its attributes # @return boolean def has_gallery? form_attributes.each do |fields| fields.each do |attribute, properties| if properties['type'] == FILE_FIELD_NAME return true end end end false end # Check if this models has a trix editor with a gallery in its attributes # @return boolean def has_trix_gallery? form_attributes.each do |fields| fields.each do |attribute, properties| if properties['type'] == 'wysiwyg_field' && properties['uploader'].present? return true end end end false end # Returns an array with all the adminpanel_file_field`s attributes found # in form_attributes # @return Hash # => { sectionfiles: Adminpanel::SectionFile, ... } def galleries galleries = {} form_attributes.each do |fields| fields.each do |relation, properties| if properties['type'] == FILE_FIELD_NAME galleries["#{relation.singularize}"] = "adminpanel/#{relation}".classify.constantize.to_s end end end return galleries end # Returns an array with all the adminpanel_file_field`s attributes who are # sortable found in form_attributes # @return Hash def sortable_galleries galleries = {} form_attributes.each do |fields| fields.each do |relation, properties| if properties['type'] == FILE_FIELD_NAME && "adminpanel/#{relation}".classify.constantize.is_sortable? galleries["#{relation.singularize}"] = "adminpanel/#{relation}".classify.constantize.to_s end end end galleries end # returns the attribute that should be namespaced to be the class # ex: returns 'productfiles', so class is Adminpanel::Productfile def gallery_relationship form_attributes.each do |fields| fields.each do |attribute, properties| if properties['type'] == FILE_FIELD_NAME return attribute end end end return false end # gets the class gallery and return it's class def gallery_class "adminpanel/#{gallery_relationship}".classify.constantize end # Search for a model attribute's that are of a given type # @return Array # Usage: # To get all classes of all belongs_to attributes: # @model.relationships_of('belongs_to') # # => ['Adminpanel::Category', Adminpanel::ModelBelongTo] def relationships_of(type_property) classes_of_relation = [] form_attributes.each do |fields| fields.each do |attribute, properties| if properties['type'] == type_property classes_of_relation << properties['model'].classify.constantize end end end return classes_of_relation end # routes options to be used when generating this model routes # @return Hash def routes_options { path: collection_name.parameterize } end def has_route?(route) if (!exclude_route?(route)) && include_route?(route) true else false end end def fb_share? false end # Additional member routes for this resource def member_routes [] end # Additional collection routes for this resource def collection_routes [] end def is_sortable? false end def has_sortable_gallery? !sortable_galleries.empty? end def to_controller_name to_s.demodulize.underscore.pluralize end def form_url self end private def exclude_route?(route) if routes_options[:except].nil? false elsif routes_options[:except].include?(route) true else false end end def include_route?(route) if routes_options[:only].nil? || routes_options[:only].include?(route) true else false end end end def destroy_unattached_images self.class.galleries.each{|gallery| gallery.last.constantize.where(model_id: nil).delete_all } end def correlative_order_gallery self.class.galleries.each do |gallery| self.send(gallery.first.pluralize).ordered.each_with_index{ |image, index| image.update(position: index + 1) } end end end end