Class: EasyAdmin::CombinedFiltersComponent

Inherits:
Phlex::HTML
  • Object
show all
Defined in:
app/components/easy_admin/combined_filters_component.rb

Instance Method Summary collapse

Constructor Details

#initialize(resource_class:, current_params: {}, search_params: {}, current_period: nil) ⇒ CombinedFiltersComponent

Returns a new instance of CombinedFiltersComponent.



3
4
5
6
7
8
# File 'app/components/easy_admin/combined_filters_component.rb', line 3

def initialize(resource_class:, current_params: {}, search_params: {}, current_period: nil)
  @resource_class = resource_class
  @current_params = current_params
  @search_params = search_params || {}
  @current_period = current_period
end

Instance Method Details

#view_templateObject



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'app/components/easy_admin/combined_filters_component.rb', line 10

def view_template
  return unless has_any_filters?

  div(
    id: "combined-filters",
    class: "bg-white shadow rounded-lg mb-6",
    data: { controller: "collapsible-filters" }
  ) do
    # Header with collapse toggle
    div(
      class: "px-6 py-4 border-b border-gray-200 cursor-pointer hover:bg-gray-50 transition-colors duration-150",
      data: { action: "click->collapsible-filters#toggle" }
    ) do
      div(class: "flex items-center justify-between") do
        div(class: "flex items-center space-x-2") do
          h3(class: "text-lg font-medium text-gray-900") { "Filters" }
          if has_active_filters?
            span(class: "inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800") do
              active_filter_count.to_s
            end
          end
        end
        
        # Collapse/Expand icon
        div(data: { collapsible_filters_target: "icon" }) do
          unsafe_raw '<svg class="w-5 h-5 text-gray-400 transform transition-transform duration-200" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
          </svg>'
        end
      end
    end

    # Collapsible content
    div(
      class: "transition-all duration-300 ease-in-out",
      data: { collapsible_filters_target: "content" }
    ) do
      form(
        method: "get",
        action: route_helper.resources_path(@resource_class.route_key),
        class: "space-y-4"
      ) do
        # Preserve existing params (except filter params)
        preserve_params

        # Field Filters (Advanced)
        if @resource_class.filterable_fields.any?
          div(class: "px-6 pt-4") do
            label(class: "block text-sm font-medium text-gray-700 mb-3") { "Advanced Filters" }
            div(class: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4") do
              @resource_class.filterable_fields.each do |field|
                render_filter_field(field)
              end
            end
          end
        end

        # Quick Period Filters
        if has_quick_filters?
          div(class: "px-6 #{@resource_class.filterable_fields.any? ? 'pb-4' : 'py-4'}") do
            div(class: "mb-3") do
              label(class: "block text-sm font-medium text-gray-700 mb-2") { "Quick Filters" }
              render_quick_filters
            end
          end
        end

        # Action buttons
        div(class: "px-6 py-4 bg-gray-50 border-t border-gray-200") do
          div(class: "flex items-center justify-between") do
            # Clear filters button
            if has_active_filters?
              a(
                href: build_clear_filters_url,
                class: "text-sm text-red-600 hover:text-red-800 font-medium"
              ) { "Clear all filters" }
            else
              div # Empty div for spacing
            end

            # Apply button
            button(
              type: "submit",
              class: "inline-flex items-center px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
            ) do
              unsafe_raw '<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707v6.586l-4-4V9.414a1 1 0 00-.293-.707L3.293 6.293A1 1 0 013 5.586V4z"></path>
              </svg>'
              span { "Apply Filters" }
            end
          end
        end
      end
    end
  end
end