views: add table builder abstraction.

This commit is contained in:
evazion
2019-11-17 22:14:17 -06:00
parent 43d0955b61
commit be5df37328
3 changed files with 64 additions and 0 deletions

View File

@@ -197,6 +197,11 @@ module ApplicationHelper
simple_form_for(:search, method: method, url: url, defaults: defaults, html: html_options, &block)
end
def table_for(*options, &block)
table = TableBuilder.new(*options, &block)
render "table_builder/table", table: table
end
def body_attributes(user = CurrentUser.user)
attributes = %i[id name level level_string theme] + User::BOOLEAN_ATTRIBUTES.map(&:to_sym)
attributes += User::Roles.map { |role| :"is_#{role}?" }

View File

@@ -0,0 +1,38 @@
class TableBuilder
class Column
attr_reader :attribute, :name, :block, :html_attributes
def initialize(attribute = nil, name: attribute.to_s.titleize, **html_attributes, &block)
@attribute = attribute
@html_attributes = html_attributes
@name = name
@block = block
end
def value(item)
if block.present?
block.call(item, self)
nil
else
item.send(attribute)
end
end
end
attr_reader :columns, :html_attributes, :items
def initialize(items, **html_attributes)
@items = items
@columns = []
@html_attributes = html_attributes
yield self if block_given?
end
def column(*options, &block)
@columns << Column.new(*options, &block)
end
def row_attributes(item)
{ id: "#{item.model_name.singular}-#{item.id}", "data-id": item.id }
end
end

View File

@@ -0,0 +1,21 @@
<%= tag.table table.html_attributes do %>
<thead>
<tr>
<% table.columns.each do |column| %>
<th><%= column.name %></th>
<% end %>
</tr>
</thead>
<tbody>
<% table.items.each do |item| %>
<%= tag.tr table.row_attributes(item) do %>
<% table.columns.each do |column| %>
<%= tag.td column.html_attributes do %>
<%= column.value(item) %>
<% end %>
<% end %>
<% end %>
<% end %>
</tbody>
<% end %>