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
17 changes: 9 additions & 8 deletions app/services/event_dashboard.rb
Original file line number Diff line number Diff line change
Expand Up @@ -221,17 +221,18 @@ def organization_registrant_ids
@organization_registrant_ids ||= organization_registrant_ids_by_org.values.flat_map(&:to_a).uniq
end

# Organization names per registrant id (Person id), for registrant tooltips.
# Built from the same snapshot + active-affiliation data as the organizations
# breakdown, so the names match the Organizations count.
# Organization names per registrant id (Person id), for labeling and tooltips
# in the registrant list. Built from the same snapshot + active-affiliation data
# as the organizations breakdown, so the names match the Organizations count.
# Names are deduped and sorted; registrants with multiple orgs get all of them.
def organization_names_by_registrant
@organization_names_by_registrant ||= begin
names_by_id = organizations.index_by(&:id)
names_by_org = organizations.index_by(&:id)
organization_registrant_ids_by_org.each_with_object(Hash.new { |hash, key| hash[key] = [] }) do |(organization_id, person_ids), map|
organization = names_by_id[organization_id]
next unless organization
person_ids.each { |person_id| map[person_id] << organization.name }
end
name = names_by_org[organization_id]&.name
next unless name
person_ids.each { |person_id| map[person_id] << name }
end.transform_values { |names| names.uniq.sort }
end

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 From Claude: Reuses the snapshot + active-affiliation map already built for the Organizations card, so labeling registrants adds no queries beyond the org-name lookup. transform_values returns a plain hash (no default block), so a registrant with no org reads as nil and is simply skipped.

end

Expand Down
17 changes: 9 additions & 8 deletions app/views/events/dashboard.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,8 @@
<% end %>

<%# Headcount cards — each expands to reveal its full list %>
<div class="grid grid-cols-2 lg:grid-cols-4 gap-3 sm:gap-4">
<details class="bg-white rounded-xl border <%= DomainTheme.border_class_for(:people, intensity: 200) %> p-4 shadow-sm">
<div class="grid grid-cols-2 lg:grid-cols-12 gap-3 sm:gap-4">
<details class="bg-white rounded-xl border <%= DomainTheme.border_class_for(:people, intensity: 200) %> p-4 shadow-sm lg:col-span-4">
<summary class="cursor-pointer select-none list-none [&::-webkit-details-marker]:hidden">
<div class="flex items-center justify-between gap-2">
<h3 class="flex items-center gap-1.5 min-w-0 text-lg sm:text-xl font-bold <%= DomainTheme.text_class_for(:people, intensity: 700) %>">
Expand All @@ -238,10 +238,11 @@
<% if @dashboard.registrants.any? %>
<ul class="space-y-1 text-xs text-gray-700 max-h-64 overflow-y-auto">
<% @dashboard.registrants.each do |registrant| %>
<% org_names = @dashboard.organization_names_by_registrant[registrant.id] %>
<li>

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 From Claude: The full "Name (Org)" string is kept in the link title so hovering still reveals both even when the visible line truncates.

<%= link_to registrant.name, manage_event_path(@event, registrant_ids: registrant.id),
title: [ registrant.name, *@dashboard.organization_names_by_registrant[registrant.id] ].join(" · "),
class: "block truncate rounded px-1 -mx-1 py-0.5 hover:bg-gray-50" %>
<%= link_to manage_event_path(@event, registrant_ids: registrant.id), class: "block truncate rounded px-1 -mx-1 py-0.5 hover:bg-gray-50", title: [ registrant.name, org_names.present? ? "(#{org_names.join(", ")})" : nil ].compact.join(" ") do %>
<%= registrant.name %><% if org_names.present? %> <span class="text-gray-400">(<%= org_names.join(", ") %>)</span><% end %>
<% end %>
</li>
<% end %>
</ul>
Expand All @@ -251,7 +252,7 @@
</div>
</details>

<details class="bg-white rounded-xl border <%= DomainTheme.border_class_for(:organizations, intensity: 200) %> p-4 shadow-sm">
<details class="bg-white rounded-xl border <%= DomainTheme.border_class_for(:organizations, intensity: 200) %> p-4 shadow-sm lg:col-span-3">
<summary class="cursor-pointer select-none list-none [&::-webkit-details-marker]:hidden">
<div class="flex items-center justify-between gap-2">
<h3 class="flex items-center gap-1.5 min-w-0 text-lg sm:text-xl font-bold <%= DomainTheme.text_class_for(:organizations, intensity: 700) %>">
Expand Down Expand Up @@ -286,7 +287,7 @@
</div>
</details>

<details class="bg-white rounded-xl border <%= DomainTheme.border_class_for(:sectors, intensity: 200) %> p-4 shadow-sm">
<details class="bg-white rounded-xl border <%= DomainTheme.border_class_for(:sectors, intensity: 200) %> p-4 shadow-sm lg:col-span-3">
<summary class="cursor-pointer select-none list-none [&::-webkit-details-marker]:hidden">
<div class="flex items-center justify-between gap-2">
<h3 class="flex items-center gap-1.5 min-w-0 text-lg sm:text-xl font-bold <%= DomainTheme.text_class_for(:sectors, intensity: 700) %>">
Expand Down Expand Up @@ -318,7 +319,7 @@
</div>
</details>

<details class="bg-white rounded-xl border <%= DomainTheme.border_class_for(:addresses, intensity: 200) %> p-4 shadow-sm">
<details class="bg-white rounded-xl border <%= DomainTheme.border_class_for(:addresses, intensity: 200) %> p-4 shadow-sm lg:col-span-2">
<summary class="cursor-pointer select-none list-none [&::-webkit-details-marker]:hidden">
<div class="flex items-center justify-between gap-2">
<h3 class="flex items-center gap-1.5 min-w-0 text-lg sm:text-xl font-bold <%= DomainTheme.text_class_for(:addresses, intensity: 700) %>">
Expand Down
9 changes: 5 additions & 4 deletions spec/services/event_dashboard_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,11 @@
expect(map[org_c.id].to_a).to contain_exactly(person2.id)
end

it "maps each registrant id to its organization names (for tooltips)" do
map = dashboard.organization_names_by_registrant
expect(map[person1.id]).to contain_exactly("Alpha Org", "Beta Org")
expect(map[person2.id]).to contain_exactly("Gamma Org")
it "maps each registrant to its organization names, deduped and sorted" do
names = dashboard.organization_names_by_registrant
expect(names[person1.id]).to eq([ "Alpha Org", "Beta Org" ])
expect(names[person2.id]).to eq([ "Gamma Org" ])
expect(names).not_to have_key(cancelled_person.id)
end
end

Expand Down