Class: Maquina::Application::IndexTable

Inherits:
Phlex::HTML
  • Object
show all
Includes:
Maquina::ApplicationView, Phlex::Rails::Helpers::LinkTo
Defined in:
app/views/maquina/application/index_table.rb

Instance Method Summary collapse

Methods included from Maquina::ApplicationView

#attribute_human_name, #button_to, #image_tag, #link_to, #model_human_name, #svg_icon

Constructor Details

#initialize(collection: nil, pagination: nil, list_attributes: nil) ⇒ IndexTable

Returns a new instance of IndexTable.



12
13
14
15
16
# File 'app/views/maquina/application/index_table.rb', line 12

def initialize(collection: nil, pagination: nil, list_attributes: nil)
  @collection = collection
  @list_attributes = list_attributes
  @pagination = pagination
end

Instance Method Details

#asc_sort_iconObject



183
184
185
186
187
188
189
# File 'app/views/maquina/application/index_table.rb', line 183

def asc_sort_icon
  <<~SVG
    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="h-4 w-auto text-skin-dimmed">
      <path d="m5 12 7-7 7 7"></path><path d="M12 19V5"></path>
    </svg>
  SVG
end


136
137
138
139
140
# File 'app/views/maquina/application/index_table.rb', line 136

def attribute_to_link(item, attribute, value)
  return value if show_link.nil? || show_link != attribute

  link_to(value, resource_path(item), class: "link", data: {"turbo-frame": "_top"})
end

#attribute_value(item, attribute) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'app/views/maquina/application/index_table.rb', line 119

def attribute_value(item, attribute)
  value = item[attribute] || item.send(attribute)

  case value
  when TrueClass
    t("yes_value")
  when FalseClass
    t("no_value")
  when ActiveSupport::TimeWithZone, Date
    I18n.l value, format: :short
  when Money
    humanized_money_with_symbol(value)
  else
    value
  end
end

#desc_sort_iconObject



175
176
177
178
179
180
181
# File 'app/views/maquina/application/index_table.rb', line 175

def desc_sort_icon
  <<~SVG
    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="h-4 w-auto text-skin-dimmed">
              <path d="M12 5v14"></path><path d="m19 12-7 7-7-7"></path>
              </svg>
  SVG
end

#item_template(item) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'app/views/maquina/application/index_table.rb', line 82

def item_template(item)
  base_css = "whitespace-nowrap px-3 py-4 text-sm text-skin-muted"
  first_css = "whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-skin-base sm:pl-6"

  tr(class: "hover:bg-gray-50") do
    @list_attributes.each_with_index do |attribute, index|
      td(class: (index == 0) ? first_css : base_css, scope: "col") { attribute_to_link(item, attribute, attribute_value(item, attribute)) }
    end
    td(class: "relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6", scope: "col") do
      a(href: edit_resource_path(item), class: "text-skin-accented hover:text-skin-accented-hover") { t("index.edit") } if policy_class.blank? || allowed_to?(:edit?, item, with: policy_class)
    end
  end
end

#no_items_templateObject



72
73
74
75
76
77
78
79
80
# File 'app/views/maquina/application/index_table.rb', line 72

def no_items_template
  col_span = @list_attributes.size + 1

  tr do
    th(scope: "col", colspan: col_span, class: "whitespace-nowrap px-3 py-4 text-sm text-skin-dimmed") do
      t("index.no_items", model: model_human_name(plural: true).downcase)
    end
  end
end

#no_sort_iconObject



167
168
169
170
171
172
173
# File 'app/views/maquina/application/index_table.rb', line 167

def no_sort_icon
  <<~SVG
    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="h-4 w-auto text-skin-dimmed">
      <path d="m7 15 5 5 5-5"></path><path d="m7 9 5-5 5 5"></path>
    </svg>  
  SVG
end

#pagination_templateObject



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'app/views/maquina/application/index_table.rb', line 96

def pagination_template
  nav(class: "flex items-center justify-between border-t border-gray-200 bg-white px-4 py-3 sm:px-6", aria_label: "Pagination") do
    div(class: "hidden sm:block") do
      p(class: "text-sm text-skin-muted") do
        t("index.pagination.information", from: @pagination.from, to: @pagination.to, count: @pagination.count) if @collection.any? && @pagination.present?
      end
    end
    div(class: "flex flex-1 justify-between sm:justify-end") do
      if @pagination.present? && @pagination.prev.present?
        a(href: "#", class: "relative button") { t("index.pagination.previous") }
      else
        span(class: "relative button", disabled: true) { t("index.pagination.previous") }
      end

      if @pagination.present? && @pagination.next.present?
        a(href: "#", class: "relative ml-3 button") { t("index.pagination.next") }
      else
        span(class: "relative ml-3 button", disabled: true) { t("index.pagination.next") }
      end
    end
  end
end


142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'app/views/maquina/application/index_table.rb', line 142

def sort_link_params(attribute)
  current_params = params.dup.to_unsafe_h.except(:controller, :action)
  current_order = current_params[:order]
  current_dir = current_params[:dir]

  if current_order != attribute.to_s
    current_params[:order] = attribute
    current_params[:dir] = :desc
  elsif current_dir == "desc"
    current_params[:dir] = :asc
  elsif current_dir == "asc"
    current_params.except!(:order, :dir)
  else
    current_params[:order] = attribute
    current_params[:dir] = :desc
  end

  current_params
end

#sort_status(attribute) ⇒ Object



162
163
164
165
# File 'app/views/maquina/application/index_table.rb', line 162

def sort_status(attribute)
  return nil unless params[:order] == attribute.to_s
  (params[:dir] == "asc") ? :asc : :desc
end

#table_headers_templateObject



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
# File 'app/views/maquina/application/index_table.rb', line 43

def table_headers_template
  base_css = "px-1 py-3 text-left text-sm font-medium text-skin-base"
  first_css = "py-1 py-3 text-left text-sm font-medium text-skin-base sm:pl-6"

  @list_attributes.each_with_index do |attribute, index|
    current_css = if index == 0
      first_css
    else
      base_css
    end

    th(scope: :col, class: current_css) do
      if sortable.include?(attribute)
        link_to(collection_path(sort_link_params(attribute)), class: "inline-flex items-center justify-center gap-2 whitespace-nowrap hover:bg-gray-100 hover:cursor-pointer p-2 rounded-sm") do
          span { attribute_human_name(attribute) }
          unsafe_raw case sort_status(attribute)
          when :asc then asc_sort_icon
          when :desc then desc_sort_icon
          else
            no_sort_icon
          end
        end
      else
        span { attribute_human_name(attribute) }
      end
    end
  end
end

#view_templateObject



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'app/views/maquina/application/index_table.rb', line 18

def view_template
  div(class: "mt-8 flex flex-col") do
    div(class: "-my-2 -mx-4 overflow-x-auto sm:-mx-6 lg:-mx-8") do
      div(class: "inline-block min-w-full py-2 align-middle md:px-6 lg:px-8") do
        div(class: "overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg") do
          table(class: "min-w-full divide-y divide-gray-300") do
            thead(class: "bg-gray-50") do
              tr do
                table_headers_template
                th(scope: "col", class: "relative py-3.5 pl-3 pr-4 sm:pr-6") do
                  span(class: "sr-only") { "Edit" }
                end
              end
            end
            tbody class: "divide-y divide-gray-200 bg-white" do
              @collection.empty? ? no_items_template : @collection.each { |item| item_template(item) }
            end
          end
          pagination_template
        end
      end
    end
  end
end