# frozen_string_literal: true class SolidusAdmin::UI::Table::RansackFilter::Component < SolidusAdmin::BaseComponent # @param presentation [String] The label for the filter. # @param search_param [String] The search parameter for the filter query. # @param combinator [String] The combining logic for filter options. # @param attribute [String] The database attribute the filter is based on. # @param predicate [String] The comparison logic for the filter (e.g., "eq" for equals). # @param options [Proc] A callable that returns filter options. # @param index [Integer] The index of the filter. # @param form [String] The form in which the filter resides. def initialize( presentation:, combinator:, attribute:, predicate:, options:, form:, index:, search_param: :q ) @presentation = presentation @group = "#{search_param}[g][#{index}]" @combinator = build(:combinator, combinator) @attribute = attribute @predicate = predicate @options = options @form = form @index = index end def before_render @selections = @options.map.with_index do |(label, value), opt_index| Selection.new( "#{stimulus_id}--#{label}-#{value}".parameterize, label, build(:attribute, @attribute, opt_index), build(:predicate, @predicate, opt_index), build(:option, value, opt_index), checked?(value) ) end end # Builds form attributes for filter options. # # @param type [Symbol] The type of the form attribute. # @param value [String] The value of the form attribute. # @param opt_index [Integer] The index of the option, if applicable. # @return [FormAttribute] The built form attribute. def build(type, value, opt_index = nil) suffix = SUFFIXES[type] % { index: opt_index || @index } Attribute.new("#{@group}#{suffix}", value) end # Determines if a given value should be checked based on the params. # # @param value [String] The value of the checkbox. # @return [Boolean] Returns true if the checkbox should be checked, false otherwise. def checked?(value) conditions = params.dig(:q, :g, @index.to_s, :c) conditions && conditions.values.any? { |c| c[:v]&.include?(value.to_s) } end SUFFIXES = { combinator: '[m]', attribute: '[c][%s][a][]', predicate: '[c][%s][p]', option: '[c][%s][v][]' } Selection = Struct.new(:id, :presentation, :attribute, :predicate, :option, :checked) Attribute = Struct.new(:name, :value) end