Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions lib/notion/notion.rb
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,8 @@ def format_blocks(blocks)
block_type = block["type"]
block_data = block[block_type] || {}

next format_table_block(block, block_data) if block_type == "table"

{
type: block_type,
text: extract_block_text(block_data, block),
Expand All @@ -333,6 +335,59 @@ def format_blocks(blocks)
end
end

def format_table_block(block, block_data)
table_data = fetch_table_data(block["id"])
rows = table_data[:rows].map do |row|
Array(row.dig("table_row", "cells")).map { |cell| extract_rich_text(cell) }
end

table_width = block_data["table_width"].to_i
table_width = rows.map(&:length).max.to_i if table_width.zero?

{
type: "table",
table_width: table_width,
has_column_header: block_data["has_column_header"] == true,
has_row_header: block_data["has_row_header"] == true,
has_more_rows: table_data[:has_more],
rows: normalize_table_rows(rows, table_width)
}
end

def fetch_table_data(table_id)
@table_data ||= {}
@table_data[table_id] ||= begin
response = api_client.get_page_blocks(table_id, page_size: 100)
results = response.is_a?(Hash) ? response["results"] : nil

{
rows: Array(results).select { |block| block.is_a?(Hash) && block["type"] == "table_row" },
has_more: response.is_a?(Hash) && response["has_more"] == true
}
rescue StandardError => e
Rails.logger.error "Notion table API error: #{e.message}"
{ rows: [], has_more: false }
end
end

def normalize_table_rows(rows, table_width)
return [] if table_width.zero?

rows.map do |row|
normalized_row = row.first(table_width)
normalized_row.fill("", normalized_row.length...table_width)
end
end

def extract_rich_text(rich_text)
text = Array(rich_text).filter_map do |fragment|
next unless fragment.is_a?(Hash)

fragment["plain_text"] || fragment.dig("text", "content")
end.join
strip_emojis(text)
end

def extract_block_text(block_data, block)
caption = block_data.dig("caption", 0, "text", "content").presence

Expand Down
22 changes: 15 additions & 7 deletions lib/notion/views/full.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,30 @@
<% end %>
</div>
<% elsif display_type == "page" %>
<div class="layout layout--top">
<% if items && items[:blocks] && items[:blocks].any? %>
<div class="columns" data-overflow-max-cols="<%= multi_column_display %>" data-overflow-counter="false">
<div class="column">
<% if items && items[:blocks] && items[:blocks].any? %>
<% has_table = items[:blocks].any? { |block| block[:type] == "table" && Array(block[:rows]).any? && block[:table_width].to_i.positive? } %>
<div class="layout layout--top<%= " notion-table-layout" if has_table %>">
<% if has_table %>
<div class="notion-table-columns">
<div class="notion-table-column">
<% else %>
<div class="columns" data-overflow-max-cols="<%= multi_column_display %>" data-overflow-counter="false">
<div class="column">
<% end %>
<% items[:blocks].each_with_index do |block, idx| %>
<%= render 'plugins/notion/shared/page_block', block: block, index: idx, current_layout: "full", image_height: image_height %>
<% end %>
</div>
</div>
<% else %>
</div>
<% else %>
<div class="layout layout--top">
<%= render 'plugins/notion/shared/error_section',
title_class: "title",
title_text: "No Content Available",
description_text: "Check your Notion configuration and try again" %>
<% end %>
</div>
</div>
<% end %>
<% end %>

<%= render partial: 'plugins/notion/shared/title_bar', locals: { instance_name: instance_name } %>
Expand Down
22 changes: 15 additions & 7 deletions lib/notion/views/half_horizontal.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,30 @@
<% end %>
</div>
<% elsif display_type == "page" %>
<div class="layout layout--top">
<% if items && items[:blocks] && items[:blocks].any? %>
<div class="columns" data-overflow-max-cols="<%= multi_column_display %>" data-overflow-counter="false">
<div class="column">
<% if items && items[:blocks] && items[:blocks].any? %>
<% has_table = items[:blocks].any? { |block| block[:type] == "table" && Array(block[:rows]).any? && block[:table_width].to_i.positive? } %>
<div class="layout layout--top<%= " notion-table-layout" if has_table %>">
<% if has_table %>
<div class="notion-table-columns">
<div class="notion-table-column">
<% else %>
<div class="columns" data-overflow-max-cols="<%= multi_column_display %>" data-overflow-counter="false">
<div class="column">
<% end %>
<% items[:blocks].each_with_index do |block, idx| %>
<%= render 'plugins/notion/shared/page_block', block: block, index: idx, current_layout: "half_horizontal", image_height: image_height %>
<% end %>
</div>
</div>
<% else %>
</div>
<% else %>
<div class="layout layout--top">
<%= render 'plugins/notion/shared/error_section',
title_class: "title title--small",
title_text: "No Content",
description_text: "Check your Notion configuration" %>
<% end %>
</div>
</div>
<% end %>
<% end %>

<%= render partial: 'plugins/notion/shared/title_bar', locals: { instance_name: instance_name } %>
Expand Down
24 changes: 16 additions & 8 deletions lib/notion/views/half_vertical.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,31 @@
description_text: "Check your Notion configuration" %>
<% end %>
</div>
<% elsif display_type == "page" %>
<div class="layout layout--top">
<% if items && items[:blocks] && items[:blocks].any? %>
<div class="columns" data-overflow-max-cols="1" data-overflow-counter="false">
<div class="column">
<% elsif display_type == "page" %>
<% if items && items[:blocks] && items[:blocks].any? %>
<% has_table = items[:blocks].any? { |block| block[:type] == "table" && Array(block[:rows]).any? && block[:table_width].to_i.positive? } %>
<div class="layout layout--top<%= " notion-table-layout" if has_table %>">
<% if has_table %>
<div class="notion-table-columns">
<div class="notion-table-column">
<% else %>
<div class="columns" data-overflow-max-cols="1" data-overflow-counter="false">
<div class="column">
<% end %>
<% items[:blocks].each_with_index do |block, idx| %>
<%= render 'plugins/notion/shared/page_block', block: block, index: idx, current_layout: "half_vertical", image_height: image_height %>
<% end %>
</div>
</div>
<% else %>
</div>
<% else %>
<div class="layout layout--top">
<%= render 'plugins/notion/shared/error_section',
title_class: "title title--small",
title_text: "No Content",
description_text: "Check your Notion configuration" %>
<% end %>
</div>
</div>
<% end %>
<% end %>

<%= render partial: 'plugins/notion/shared/title_bar', locals: { instance_name: instance_name } %>
Expand Down
22 changes: 15 additions & 7 deletions lib/notion/views/quadrant.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,30 @@
<% end %>
</div>
<% elsif display_type == "page" %>
<div class="layout layout--top">
<% if items && items[:blocks] && items[:blocks].any? %>
<div class="columns" data-overflow-max-cols="1" data-overflow-counter="false">
<div class="column">
<% if items && items[:blocks] && items[:blocks].any? %>
<% has_table = items[:blocks].any? { |block| block[:type] == "table" && Array(block[:rows]).any? && block[:table_width].to_i.positive? } %>
<div class="layout layout--top<%= " notion-table-layout" if has_table %>">
<% if has_table %>
<div class="notion-table-columns">
<div class="notion-table-column">
<% else %>
<div class="columns" data-overflow-max-cols="1" data-overflow-counter="false">
<div class="column">
<% end %>
<% items[:blocks].each_with_index do |block, idx| %>
<%= render 'plugins/notion/shared/page_block', block: block, index: idx, current_layout: "quadrant", image_height: image_height %>
<% end %>
</div>
</div>
<% else %>
</div>
<% else %>
<div class="layout layout--top">
<%= render 'plugins/notion/shared/error_section',
title_class: "title title--small",
title_text: "No Content",
description_text: "Check config" %>
<% end %>
</div>
</div>
<% end %>
<% end %>

<%= render partial: 'plugins/notion/shared/title_bar', locals: { instance_name: instance_name } %>
Expand Down
4 changes: 3 additions & 1 deletion lib/notion/views/shared/_page_block.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<% if block[:type] == "divider" %>
<div style="border-top: 1px dotted #000000;"></div>
<% elsif ["table_of_contents", "table", "unsupported", "synced_block", "breadcrumb", "column_list"].include?(block[:type]) %>
<% elsif block[:type] == "table" %>
<%= render 'plugins/notion/shared/table', table: block, current_layout: current_layout %>
<% elsif ["table_of_contents", "unsupported", "synced_block", "breadcrumb", "column_list"].include?(block[:type]) %>
<% return %>
<% else %>
<div class="item">
Expand Down
Loading