From 590a63c422fe91c1cba08800757a719a2726db8e Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Mon, 10 Nov 2025 15:46:35 +0100 Subject: [PATCH 1/3] Move helpers salad to a presenter column when rendering the timeline --- app/helpers/events_helper.rb | 82 +++---------------- app/models/user/day_timeline.rb | 16 ++++ app/models/user/day_timeline/column.rb | 42 ++++++++++ app/views/events/_day_timeline.html.erb | 8 -- .../events/day_timeline/_column.html.erb | 14 ++-- .../events/day_timeline/_columns.html.erb | 6 +- app/views/events/event/_layout.html.erb | 2 +- 7 files changed, 81 insertions(+), 89 deletions(-) create mode 100644 app/models/user/day_timeline/column.rb delete mode 100644 app/views/events/_day_timeline.html.erb diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb index 94e6990d2..6437c33e8 100644 --- a/app/helpers/events_helper.rb +++ b/app/helpers/events_helper.rb @@ -1,74 +1,18 @@ module EventsHelper - def event_columns(event_type, day_timeline) - case event_type - when "added" - events = day_timeline.events.where(action: [ "card_published", "card_reopened" ]) - full_events_count = events.count - { - title: event_column_title("Added", full_events_count, day_timeline.day), - index: 1, - events: events.limit(100).load, - full_events_count: full_events_count - } - when "closed" - events = day_timeline.events.where(action: "card_closed") - full_events_count = events.count - { - title: event_column_title("Closed", full_events_count, day_timeline.day), - index: 3, - events: events.limit(100).load, - full_events_count: full_events_count - } + def event_action_icon(event) + case event.action + when "card_assigned" + "assigned" + when "card_unassigned" + "minus" + when "comment_created" + "comment" + when "card_title_changed" + "rename" + when "card_board_changed" + "move" else - events = day_timeline.events.where.not(action: [ "card_published", "card_closed", "card_reopened" ]) - full_events_count = events.count - { - title: event_column_title("Updated", full_events_count, day_timeline.day), - index: 2, - events: events.limit(100).load, - full_events_count: full_events_count - } + "person" end end - - private - def event_column_title(base_title, count, day) - date_tag = local_datetime_tag day, style: :agoorweekday - parts = [ base_title, date_tag ] - parts << tag.span("(#{count})", class: "font-weight-normal") if count > 0 - safe_join(parts, " ") - end - - def event_column(event) - case event.action - when "card_closed" - 3 - when "card_published", "card_reopened" - 1 - else - 2 - end - end - - def event_cluster_tag(hour, col, &) - row = 25 - hour - tag.div class: "events__time-block", style: "grid-area: #{row}/#{col}", & - end - - def event_action_icon(event) - case event.action - when "card_assigned" - "assigned" - when "card_unassigned" - "minus" - when "comment_created" - "comment" - when "card_title_changed" - "rename" - when "card_board_changed" - "move" - else - "person" - end - end end diff --git a/app/models/user/day_timeline.rb b/app/models/user/day_timeline.rb index 367eccdcb..54315f7d8 100644 --- a/app/models/user/day_timeline.rb +++ b/app/models/user/day_timeline.rb @@ -29,11 +29,27 @@ class User::DayTimeline day.yesterday.beginning_of_day end + def added_column + @added_column ||= build_column("Added", 1, events.where(action: %w[card_published card_reopened])) + end + + def updated_column + @updated_column ||= build_column("Updated", 2, events.where.not(action: %w[card_published card_closed card_reopened])) + end + + def closed_column + @closed_column ||= build_column("Closed", 3, events.where(action: "card_closed")) + end + def cache_key ActiveSupport::Cache.expand_cache_key [ user, filter, day.to_date, events ], "day-timeline" end private + def build_column(base_title, index, events) + Column.new(self, base_title, index, events) + end + TIMELINEABLE_ACTIONS = %w[ card_assigned card_unassigned diff --git a/app/models/user/day_timeline/column.rb b/app/models/user/day_timeline/column.rb new file mode 100644 index 000000000..fe42c68dc --- /dev/null +++ b/app/models/user/day_timeline/column.rb @@ -0,0 +1,42 @@ +class User::DayTimeline::Column + include ActionView::Helpers::TagHelper, ActionView::Helpers::OutputSafetyHelper, TimeHelper + + attr_reader :index + + def initialize(day_timeline, base_title, index, events) + @day_timeline = day_timeline + @base_title = base_title + @index = index + @events = events + end + + def title + date_tag = local_datetime_tag(day_timeline.day, style: :agoorweekday) + parts = [ base_title, date_tag ] + parts << tag.span("(#{full_events_count})", class: "font-weight-normal") if full_events_count > 0 + safe_join(parts, " ") + end + + def events_by_hour + limited_events.group_by { it.created_at.hour } + end + + def has_more_events? + limited_events.count < full_events_count + end + + def hidden_events_count + full_events_count - limited_events.count + end + + private + attr_reader :base_title, :day_timeline, :events + + def limited_events + @limited_events ||= events.limit(100).load + end + + def full_events_count + @full_events_count ||= events.count + end +end diff --git a/app/views/events/_day_timeline.html.erb b/app/views/events/_day_timeline.html.erb deleted file mode 100644 index 244414d2a..000000000 --- a/app/views/events/_day_timeline.html.erb +++ /dev/null @@ -1,8 +0,0 @@ -<% day_timeline.events.group_by { it.created_at.hour }.each do |hour, events_grouped_by_hour| %> - <% events_grouped_by_hour.group_by { event_column(it) }.each do |column, events| %> - <%= event_cluster_tag(hour, column) do %> - <%= render partial: "events/event", collection: events %> - <%= local_datetime_tag events.first.created_at, class: "event__timestamp txt-small translucent" %> - <% end %> - <% end %> -<% end %> diff --git a/app/views/events/day_timeline/_column.html.erb b/app/views/events/day_timeline/_column.html.erb index aefe9258e..b8b54935f 100644 --- a/app/views/events/day_timeline/_column.html.erb +++ b/app/views/events/day_timeline/_column.html.erb @@ -1,17 +1,15 @@ -<% column = event_columns(event_type, day_timeline) %> -
-

<%= column[:title] %>

- <% column[:events].group_by { it.created_at.hour }.each do |hour, events| %> - <%= event_cluster_tag(hour, column[:index]) do %> +

<%= column.title %>

+ <% column.events_by_hour.each do |hour, events| %> + <%= tag.div class: "events__time-block", style: "grid-area: #{25 - hour}/#{column.index}" do %> <%= render partial: "events/event", collection: events, cached: true %> <%= local_datetime_tag events.first.created_at, class: "event__timestamp txt-small translucent" %> <% end %> <% end %> - <% if column[:events].count < column[:full_events_count] %> - diff --git a/app/views/events/day_timeline/_columns.html.erb b/app/views/events/day_timeline/_columns.html.erb index 5391736e9..580c7312c 100644 --- a/app/views/events/day_timeline/_columns.html.erb +++ b/app/views/events/day_timeline/_columns.html.erb @@ -1,9 +1,9 @@ <% cache [ day_timeline.events ] do %> <% if day_timeline.has_activity? %>
- <%= render "events/day_timeline/column", event_type: "added", day_timeline: day_timeline %> - <%= render "events/day_timeline/column", event_type: "updated", day_timeline: day_timeline %> - <%= render "events/day_timeline/column", event_type: "closed", day_timeline: day_timeline %> + <%= render "events/day_timeline/column", column: day_timeline.added_column %> + <%= render "events/day_timeline/column", column: day_timeline.updated_column %> + <%= render "events/day_timeline/column", column: day_timeline.closed_column %>
<% end %> <% end %> diff --git a/app/views/events/event/_layout.html.erb b/app/views/events/event/_layout.html.erb index 0cd0fee07..03aeed470 100644 --- a/app/views/events/event/_layout.html.erb +++ b/app/views/events/event/_layout.html.erb @@ -18,7 +18,7 @@ - <% if event_column(event) == 2 %> + <% if event.action.in?(%w[ card_closed card_published card_reopened ]) %> <%= icon_tag event_action_icon(event) %> From 05ef07f77bfa08722f3b318032e0df3af38472a6 Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Mon, 10 Nov 2025 16:17:03 +0100 Subject: [PATCH 2/3] Extract helper for the container of events grouped by hour --- app/helpers/events_helper.rb | 4 ++++ app/views/events/day_timeline/_column.html.erb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb index 6437c33e8..501abf2dd 100644 --- a/app/helpers/events_helper.rb +++ b/app/helpers/events_helper.rb @@ -15,4 +15,8 @@ module EventsHelper "person" end end + + def events_at_hour_container(column, hour, &block) + tag.div class: "events__time-block", style: "grid-area: #{25 - hour}/#{column.index}", &block + end end diff --git a/app/views/events/day_timeline/_column.html.erb b/app/views/events/day_timeline/_column.html.erb index b8b54935f..6e036a412 100644 --- a/app/views/events/day_timeline/_column.html.erb +++ b/app/views/events/day_timeline/_column.html.erb @@ -1,7 +1,7 @@

<%= column.title %>

<% column.events_by_hour.each do |hour, events| %> - <%= tag.div class: "events__time-block", style: "grid-area: #{25 - hour}/#{column.index}" do %> + <%= events_at_hour_container(column, hour) do %> <%= render partial: "events/event", collection: events, cached: true %> <%= local_datetime_tag events.first.created_at, class: "event__timestamp txt-small translucent" %> <% end %> From f5440833a96a2993f98392c1e1c4525493d5f791 Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Mon, 10 Nov 2025 16:21:46 +0100 Subject: [PATCH 3/3] Order method --- app/models/user/day_timeline.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/models/user/day_timeline.rb b/app/models/user/day_timeline.rb index 54315f7d8..a5f98cb8a 100644 --- a/app/models/user/day_timeline.rb +++ b/app/models/user/day_timeline.rb @@ -46,10 +46,6 @@ class User::DayTimeline end private - def build_column(base_title, index, events) - Column.new(self, base_title, index, events) - end - TIMELINEABLE_ACTIONS = %w[ card_assigned card_unassigned @@ -86,6 +82,10 @@ class User::DayTimeline filtered_events.where(created_at: ...day.beginning_of_day).chronologically.last end + def build_column(base_title, index, events) + Column.new(self, base_title, index, events) + end + def window day.all_day end