Module: Dbviewer::TableRenderingHelper

Included in:
ApplicationHelper
Defined in:
app/helpers/dbviewer/table_rendering_helper.rb

Instance Method Summary collapse

Instance Method Details

#render_action_cell(row_data, columns, metadata = nil) ⇒ Object

Render action buttons for a record



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'app/helpers/dbviewer/table_rendering_helper.rb', line 99

def render_action_cell(row_data, columns,  = nil)
  data_attributes = {}

  # Create a hash of column_name: value pairs for data attributes
  columns.each_with_index do |column_name, index|
    data_attributes[column_name] = row_data[index].to_s
  end

  (:td, class: "text-center action-column") do
    (:div, class: "d-flex gap-1 justify-content-center") do
      # View Record button (existing)
      view_button = button_tag(
        type: "button",
        class: "btn btn-sm btn-primary view-record-btn",
        title: "View Record Details",
        data: {
          bs_toggle: "modal",
          bs_target: "#recordDetailModal",
          record_data: data_attributes.to_json,
          foreign_keys:  && [:foreign_keys] ? [:foreign_keys].to_json : "[]",
          reverse_foreign_keys:  && [:reverse_foreign_keys] ? [:reverse_foreign_keys].to_json : "[]"
        }
      ) do
        (:i, "", class: "bi bi-eye")
      end

      # Copy FactoryBot button (new)
      copy_factory_button = button_tag(
        type: "button",
        class: "btn btn-sm btn-outline-secondary copy-factory-btn",
        title: "Copy to JSON",
        data: {
          record_data: data_attributes.to_json,
          table_name: @table_name
        },
        onclick: "copyToJson(this)"
      ) do
        (:i, "", class: "bi bi-clipboard")
      end

      # Concatenate both buttons
      view_button + copy_factory_button
    end
  end
end

#render_column_filters_row(form, records, columns, column_filters) ⇒ Object

Render the column filters row



28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'app/helpers/dbviewer/table_rendering_helper.rb', line 28

def render_column_filters_row(form, records, columns, column_filters)
  return (:tr) { (:th, "") } unless records&.columns

  (:tr, class: "column-filters") do
    filters = records.columns.map do |column_name|
      (:th, class: "p-0 border-bottom-0") do
        render_column_filter(form, column_name, columns, column_filters)
      end
    end

    filters.join.html_safe
  end
end

#render_sortable_header_row(records, order_by, order_direction, table_name, current_page, per_page, column_filters) ⇒ Object

Render a complete table header row with sortable columns



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'app/helpers/dbviewer/table_rendering_helper.rb', line 4

def render_sortable_header_row(records, order_by, order_direction, table_name, current_page, per_page, column_filters)
  return (:tr) { (:th, "No columns available") } unless records&.columns

  (:tr) do
    # Start with action column header (sticky first column)
    headers = [
      (:th, class: "px-3 py-2 text-center action-column action-column-header border-bottom-0", width: "60px", rowspan: 2) do
        (:span, "Actions")
      end
    ]

    # Add all data columns
    headers += records.columns.map do |column_name|
      is_sorted = order_by == column_name
      (:th, class: "px-3 py-2 sortable-column border-bottom-0 #{is_sorted ? 'sorted' : ''}") do
        sortable_column_header(column_name, order_by, order_direction, table_name, current_page, per_page, column_filters)
      end
    end

    headers.join.html_safe
  end
end

#render_table_body(records, metadata) ⇒ Object

Render the entire table body with rows



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'app/helpers/dbviewer/table_rendering_helper.rb', line 80

def render_table_body(records, )
  if records.nil? || records.rows.nil? || records.empty?
    (:tbody) do
      (:tr) do
        # Adding +1 to account for the action column
        total_columns = records&.columns&.size.to_i + 1
        (:td, "No records found or table is empty.", colspan: total_columns, class: "text-center")
      end
    end
  else
    (:tbody) do
      records.rows.map do |row|
        render_table_row(row, records, )
      end.join.html_safe
    end
  end
end

#render_table_cell(cell, column_name, metadata) ⇒ Object

Render a cell that may include a foreign key link



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'app/helpers/dbviewer/table_rendering_helper.rb', line 43

def render_table_cell(cell, column_name, )
  cell_value = format_cell_value(cell)
  foreign_key =  && [:foreign_keys] ?
                [:foreign_keys].find { |fk| fk[:column] == column_name } :
                nil

  if foreign_key && !cell.nil?
    fk_params = { column_filters: { foreign_key[:primary_key] => cell } }
    fk_params = fk_params.merge(common_params.except(:column_filters))

    (:td, title: "#{cell_value} (Click to view referenced record)") do
      link_to(cell_value, table_path(foreign_key[:to_table], fk_params),
              class: "text-decoration-none foreign-key-link") +
      (:i, "", class: "bi bi-link-45deg text-muted small")
    end
  else
    (:td, cell_value, title: cell_value)
  end
end

#render_table_row(row, records, metadata) ⇒ Object

Render a table row with cells



64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'app/helpers/dbviewer/table_rendering_helper.rb', line 64

def render_table_row(row, records, )
  (:tr) do
    # Start with action column (sticky first column)
    cells = [ render_action_cell(row, records.columns, ) ]

    # Add all data cells
    cells += row.each_with_index.map do |cell, cell_index|
      column_name = records.columns[cell_index]
      render_table_cell(cell, column_name, )
    end

    cells.join.html_safe
  end
end