Module: Hecks::Forms::RecordTable

Defined in:
lib/hecks/forms/record_table.rb

Overview

An array of Record (or anything answering #id/#state — a Runtime::Instance qualifies without wrapping) -> an HTML table. Shared by the aggregate index page (record_renderer.rb) and a query's own results (query_form_renderer.rb) — the same records read the same columns either way.

Class Method Summary collapse

Class Method Details

.cell(instance, name) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/hecks/forms/record_table.rb', line 48

def self.cell(instance, name)
  # `state` holds `Runtime::Value` wherever an attribute is a value
  # object, not a plain Hash — `.materialize` is the runtime's own
  # unwrap (value.rb), the same one a `to_h` read anywhere else in
  # this codebase goes through, so a table cell agrees with every
  # other reader about what a stored field actually contains.
  value = Runtime::Value.materialize(instance.state[name])
  case value
  when Hash then value.values.first
  when nil then ""
  else value
  end
end

.columns(aggregate) ⇒ Object



22
23
24
25
26
# File 'lib/hecks/forms/record_table.rb', line 22

def self.columns(aggregate)
  lifecycle = aggregate.lifecycle&.field
  scalars = aggregate.attributes.reject { |a| a.reference? || a.list? }.map(&:name)
  [*aggregate.identity_heads, lifecycle, *scalars].compact.uniq.first(7)
end

.render(aggregate, instances, domain:) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/hecks/forms/record_table.rb', line 28

def self.render(aggregate, instances, domain:)
  cols = columns(aggregate)
  head = (["id"] + cols).map { |name| "<th>#{Escape.html(Humanize.label(name.to_s))}</th>" }.join
  rows = instances.map { |instance| row(instance, aggregate, cols, domain) }
  return "<p><em>No records.</em></p>" if rows.empty?

  <<~HTML
    <div class="table-scroll"><table>
      <thead><tr>#{head}</tr></thead>
      <tbody>#{rows.join}</tbody>
    </table></div>
  HTML
end

.row(instance, aggregate, cols, domain) ⇒ Object



42
43
44
45
46
# File 'lib/hecks/forms/record_table.rb', line 42

def self.row(instance, aggregate, cols, domain)
  cells = cols.map { |name| "<td>#{Escape.html(cell(instance, name))}</td>" }.join
  href = "/#{domain}/#{aggregate.hecks_name}/#{instance.id}.html"
  "<tr><td><a href=\"#{Escape.attr(href)}\">#{Escape.html(instance.id)}</a></td>#{cells}</tr>"
end