Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: summarizable associations #3428

Merged
Merged
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
45 changes: 44 additions & 1 deletion app/controllers/avo/charts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,53 @@
module Avo
class ChartsController < BaseController
def distribution_chart
@values_summary = resource.model_class.group(params[:field_id]).reorder("count_all desc").count
@values_summary = summary_query.group(params[:field_id].to_sym).reorder("count_all desc").count

@field_id = params[:field_id]

render "avo/partials/distribution_chart", layout: "avo/blank"
end

private

def is_associated_summary
params[:via_record_id].present? &&
params[:via_resource_class].present? &&
params[:association_name].present?
end

def summary_query
is_associated_summary ? association_scope : resource.query_scope
end

def association_scope
parent_resource_class = Avo.resource_manager.get_resource(params[:via_resource_class])
parent_record = parent_resource_class.find_record(params[:via_record_id], params: params)

parent_resource = parent_resource_class.new(
record: parent_record,
# Explicitly hardcoding the view to 'show' as association summaries are processed solely within this context
view: Avo::ViewInquirer.new("show")
)

parent_resource.detect_fields

association_name = BaseResource.valid_association_name(parent_record, params[:association_name])

parent_field = find_association_field(resource: parent_resource, association: association_name)

association_query = parent_resource.authorization.apply_policy parent_record.send(association_name)
Dismissed Show dismissed Hide dismissed

if parent_field.scope.present?
association_query = Avo::ExecutionContext.new(
target: parent_field.scope,
query: association_query,
parent: parent_record,
parent_resource: parent_resource
).handle
end

association_query
end
end
end
18 changes: 10 additions & 8 deletions app/views/avo/partials/_table_header.html.erb
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
<%
# Currently there isn't a way to summarize records on associations.
# We'd love to support this feature so please send in a PR.
should_summarize = @parent_record.blank?
%>

<thead
data-component-name="avo/partials/table_header"
class="bg-white border-b border-gray-200 pb-1">
Expand Down Expand Up @@ -83,14 +77,22 @@
<%= field.table_header_label %>
<% end %>
<% end %>
<% if field.summarizable && should_summarize %>
<% if field.summarizable %>
<div id="summary-header-<%= field.id %>" class="<%= text_classes %> cursor-pointer" data-action="click->toggle#togglePanel">
<%= svg 'heroicons/solid/chart-bar', class: 'h-3 ml-1' %>
</div>
<turbo-frame
id="summary-frame-<%= field.id %>"
loading="lazy"
src="<%= distribution_chart_path(resource_name: field.resource.model_class, field_id: field.id) %>"
src="<%= distribution_chart_path(
{
resource_name: field.resource.model_class,
field_id: field.id,
via_record_id: @parent_record&.to_param,
via_resource_class: @parent_resource&.class&.to_s,
association_name: @field&.for_attribute || @field&.id
}.compact
) %>"
class="absolute inset-auto bg-white w-full sm:w-[400px] top-0 mt-6 p-4 z-40 shadow-modal rounded overflow-hidden hidden border border-gray-50"
data-toggle-target="panel"
>
Expand Down
37 changes: 37 additions & 0 deletions spec/features/avo/field_summarizing_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,42 @@
expect(page).not_to have_css 'th[data-table-header-field-id="progress"] div svg'
expect(page).not_to have_css 'th[data-table-header-field-id="description"] div svg'
end

context "when summarizing on association pages" do
let(:user) { create :user }
let!(:project) { create :project, status: :closed, users: [user] }

it "only shows values from associated record" do
visit avo.resources_user_path(user)

scroll_to first_tab_group
click_tab "Projects", within_target: first_tab_group

wait_for_turbo_frame_id("has_and_belongs_to_many_field_show_projects")

expect(page).to have_css "turbo-frame[id='summary-frame-status']", visible: false

find("#summary-header-status").click

expect(page).to have_css "turbo-frame[id='summary-frame-status']", visible: true

# I can't make the lazy loading work, looks like it's not triggered at all
wait_for_turbo_frame_id("summary-frame-status")

expect(page).to have_css "#status-summary", visible: true
expect(page).to have_css "#chart-status", visible: true

within "#status-summary" do
expect(page).to_not have_content "REJECTED\n3"
expect(page).to have_content "CLOSED\n1"
expect(page).to_not have_content "LOADING\n4"
end

find('th[data-table-header-field-id="status"] div svg').click

expect(page).not_to have_css "#status-summary"
expect(page).not_to have_css "#chart-status"
end
end
end
end
Loading