# frozen_string_literal: true module FComponents module Table class Component < Base renders_one :desktop_table, Table::Desktop::Component renders_one :mobile_table, Table::Mobile::Component def initialize(options) @options = options @values = {} @actions = [] @check_boxes = [] @main_column = nil @current_resource = nil @current_resource_index = 0 end def self.for(resources, **options, &block) table = new(options) table.build(resources, &block) table end def column(name, id: nil, main: false) if main @main_column = main.is_a?(Proc) ? main : name end @values[name] ||= [] return if @current_resource.blank? @values[name] << { id: id, column_index: @current_resource_index, cell_content: yield(@current_resource).to_s } end def check_box(name:, value:, checked: false, **options) value = value.(@current_resource) if value.respond_to? :call checked = checked.(@current_resource) if checked.respond_to? :call parsed_options = options options.each do |k, v| parsed_options[k] = v.(@current_resource) if v.respond_to? :call end parsed_options[:id] ||= "#{sanitize_to_id(name)}#{value}" @check_boxes << check_box_tag(name, value, checked, **parsed_options) end def action action = yield(@current_resource) @actions[@current_resource_index] ||= [] @actions[@current_resource_index] << action end def build(resources) @resources = resources.presence || [nil] @resources.each_with_index do |resource, i| @current_resource = resource @current_resource_index = i yield(self, @current_resource) end end private def columns @values.keys end def rows @values.values.transpose end # This was copied from Rails, since it's not a public API # Source: # https://github.com/rails/rails/blob/d305be07428a8e86e2736b57f839680c9e970293/actionview/lib/action_view/helpers/form_tag_helper.rb#L931 def sanitize_to_id(name) name.to_s.delete(']').tr('^-a-zA-Z0-9:.', '_') end end end end