From 5cb4a3499cd566916de5b63dd723ad052d836172 Mon Sep 17 00:00:00 2001 From: "nida.ghuman" Date: Mon, 23 Dec 2024 14:43:44 -0500 Subject: [PATCH] Added logic to account for columns in column_definitions --- .../_advanced_table_column_headers.html.erb | 43 +++++++++++++++++ .../pb_advanced_table/docs/example.yml | 1 + .../playbook/pb_advanced_table/table_body.rb | 21 ++++++++- .../pb_advanced_table/table_header.html.erb | 32 ++++++++----- .../pb_advanced_table/table_header.rb | 47 +++++++++++++++++++ .../pb_advanced_table/table_row.html.erb | 1 + .../playbook/pb_advanced_table/table_row.rb | 3 ++ 7 files changed, 134 insertions(+), 14 deletions(-) create mode 100644 playbook/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_headers.html.erb diff --git a/playbook/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_headers.html.erb b/playbook/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_headers.html.erb new file mode 100644 index 0000000000..9e9d6c515c --- /dev/null +++ b/playbook/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_headers.html.erb @@ -0,0 +1,43 @@ +<% column_definitions = [ + { + accessor: "year", + label: "Year", + cellAccessors: ["quarter", "month", "day"], + }, + { + label: "Enrollment Data", + columns: [ + { + accessor: "newEnrollments", + label: "New Enrollments", + }, + { + accessor: "scheduledMeetings", + label: "Scheduled Meetings", + }, + ], + }, + { + label: "Performance Data", + columns: [ + { + accessor: "attendanceRate", + label: "Attendance Rate", + }, + { + accessor: "completedClasses", + label: "Completed Classes", + }, + { + accessor: "classCompletionRate", + label: "Class Completion Rate", + }, + { + accessor: "graduatedStudents", + label: "Graduated Students", + }, + ], + }, +] %> + +<%= pb_rails("advanced_table", props: { id: "beta_table_with_headers", table_data: @table_data, column_definitions: column_definitions }) %> diff --git a/playbook/app/pb_kits/playbook/pb_advanced_table/docs/example.yml b/playbook/app/pb_kits/playbook/pb_advanced_table/docs/example.yml index 1387c03272..c01df055be 100644 --- a/playbook/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +++ b/playbook/app/pb_kits/playbook/pb_advanced_table/docs/example.yml @@ -5,6 +5,7 @@ examples: - advanced_table_collapsible_trail_rails: Collapsible Trail - advanced_table_beta_sort: Enable Sorting - advanced_table_custom_cell_rails: Custom Components for Cells + - advanced_table_column_headers: Multi-Header Columns react: - advanced_table_default: Default (Required Props) diff --git a/playbook/app/pb_kits/playbook/pb_advanced_table/table_body.rb b/playbook/app/pb_kits/playbook/pb_advanced_table/table_body.rb index 0143ebaa90..64f0cd41e9 100644 --- a/playbook/app/pb_kits/playbook/pb_advanced_table/table_body.rb +++ b/playbook/app/pb_kits/playbook/pb_advanced_table/table_body.rb @@ -17,13 +17,32 @@ class TableBody < Playbook::KitBase prop :collapsible_trail, type: Playbook::Props::Boolean, default: true + def flatten_columns(columns) + columns.flat_map do |col| + if col[:columns] + flatten_columns(col[:columns]) + elsif col[:accessor].present? + col + end + end.compact + end + def render_row_and_children(row, column_definitions, current_depth, first_parent_child) + leaf_columns = flatten_columns(column_definitions) + output = ActiveSupport::SafeBuffer.new is_first_child_of_subrow = current_depth.positive? && first_parent_child && subrow_headers[current_depth - 1].present? output << pb_rails("advanced_table/table_subrow_header", props: { row: row, column_definitions: column_definitions, depth: current_depth, subrow_header: subrow_headers[current_depth - 1], collapsible_trail: collapsible_trail }) if is_first_child_of_subrow && enable_toggle_expansion == "all" - output << pb_rails("advanced_table/table_row", props: { id: id, row: row, column_definitions: column_definitions, depth: current_depth, collapsible_trail: collapsible_trail }) + # Pass only leaf_columns to table_row to account for multiple nested columns + output << pb_rails("advanced_table/table_row", props: { + id: id, + row: row, + column_definitions: leaf_columns, + depth: current_depth, + collapsible_trail: collapsible_trail, + }) if row[:children].present? output << content_tag(:div, class: "toggle-content", data: { advanced_table_content: row.object_id.to_s + id }) do diff --git a/playbook/app/pb_kits/playbook/pb_advanced_table/table_header.html.erb b/playbook/app/pb_kits/playbook/pb_advanced_table/table_header.html.erb index dd001da180..8542074ead 100644 --- a/playbook/app/pb_kits/playbook/pb_advanced_table/table_header.html.erb +++ b/playbook/app/pb_kits/playbook/pb_advanced_table/table_header.html.erb @@ -1,18 +1,24 @@ <%= pb_content_tag do %> - <%= pb_rails("table/table_row", props: { tag: "div" }) do %> - <% object.column_definitions.each_with_index do |item, index| %> - <%= pb_rails("table/table_header", props: { tag: "div", id: item[:accessor], classname: object.th_classname, sort_menu: item[:sort_menu] }) do %> - <%= pb_rails("flex", props:{ align: "center", justify: index.zero? ? "start" : "end", text_align: "end" }) do %> - <% if index.zero? && (object.enable_toggle_expansion == "header" || object.enable_toggle_expansion == "all") %> - - <% end %> - <%= item[:label] %> + <% object.header_rows.each_with_index do |header_row, row_index| %> + <%= pb_rails("table/table_row", props: { tag: "div" }) do %> + <% header_row.each_with_index do |cell, cell_index| %> + + <% header_id = cell[:accessor].present? ? cell[:accessor] : "header_#{row_index}_#{cell_index}" %> + + <%= pb_rails("table/table_header", props: { tag: "div", id: header_id, classname: object.th_classname, sort_menu: cell[:accessor] ? cell[:sort_menu] : nil }) do %> + <%= pb_rails("flex", props:{ align: "center", justify: row_index.zero? ? "start" : "end", text_align: "end" }) do %> + <% if cell_index.zero? && (object.enable_toggle_expansion == "header" || object.enable_toggle_expansion == "all") %> + <% end %> + <%= cell[:label] %> <% end %> - <% end %> <% end %> + + <% end %> + <% end %> + <% end %> <% end %> diff --git a/playbook/app/pb_kits/playbook/pb_advanced_table/table_header.rb b/playbook/app/pb_kits/playbook/pb_advanced_table/table_header.rb index 00b6b628e7..39245498d8 100644 --- a/playbook/app/pb_kits/playbook/pb_advanced_table/table_header.rb +++ b/playbook/app/pb_kits/playbook/pb_advanced_table/table_header.rb @@ -16,6 +16,53 @@ def classname def th_classname generate_classname("table-header-cells", separator: " ") end + + def header_rows + rows = [] + max_depth = compute_max_depth(column_definitions) + + max_depth.times { rows << [] } + + process_columns(column_definitions, rows, 0, max_depth) + + rows + end + + private + + def compute_max_depth(columns) + columns.map do |col| + col[:columns] ? 1 + compute_max_depth(col[:columns]) : 1 + end.max || 1 + end + + def process_columns(columns, rows, current_depth, max_depth) + columns.each do |col| + if col[:columns] + colspan = compute_leaf_columns(col[:columns]) + rowspan = 1 + rows[current_depth] << { label: col[:label], colspan: colspan, rowspan: rowspan } + + process_columns(col[:columns], rows, current_depth + 1, max_depth) + else + colspan = 1 + rowspan = max_depth - current_depth + rows[current_depth] << { + label: col[:label], + colspan: colspan, + rowspan: rowspan, + accessor: col[:accessor], + sort_menu: col[:sort_menu], + } + end + end + end + + def compute_leaf_columns(columns) + columns.reduce(0) do |sum, col| + col[:columns] ? sum + compute_leaf_columns(col[:columns]) : sum + 1 + end + end end end end diff --git a/playbook/app/pb_kits/playbook/pb_advanced_table/table_row.html.erb b/playbook/app/pb_kits/playbook/pb_advanced_table/table_row.html.erb index 66268817ad..7ca978bcae 100644 --- a/playbook/app/pb_kits/playbook/pb_advanced_table/table_row.html.erb +++ b/playbook/app/pb_kits/playbook/pb_advanced_table/table_row.html.erb @@ -1,5 +1,6 @@ <%= pb_content_tag do %> <% object.column_definitions.each_with_index do |column, index| %> + <% next unless column[:accessor].present? %> <%= pb_rails("table/table_cell", props: { tag:"div", classname:object.td_classname}) do %> <%= pb_rails("flex", props:{ align: "center", justify: index.zero? ? "start" : "end" }) do %> <% if collapsible_trail && index.zero? %> diff --git a/playbook/app/pb_kits/playbook/pb_advanced_table/table_row.rb b/playbook/app/pb_kits/playbook/pb_advanced_table/table_row.rb index 90dd238322..9c40da5bba 100644 --- a/playbook/app/pb_kits/playbook/pb_advanced_table/table_row.rb +++ b/playbook/app/pb_kits/playbook/pb_advanced_table/table_row.rb @@ -29,6 +29,8 @@ def depth_accessors private def custom_renderer_value(column, index) + return nil unless column[:accessor].present? + if index.zero? if depth.zero? row[column[:accessor].to_sym] @@ -37,6 +39,7 @@ def custom_renderer_value(column, index) key = item.to_sym return row[key] if depth - 1 == accessor_index end + nil end else row[column[:accessor].to_sym]