Skip to content

Commit

Permalink
Add tooltip to search
Browse files Browse the repository at this point in the history
You can add collection filters to a dashboard and then use them in the
search bar on the index page. eg. `email:[email protected]`

However, these collection filters are not discoverable. You have to know
about them already to know how to use them.

This change introduces a tooltip which lists the available collection
filters, allowing all users to discover what is available.

Closes #2750
  • Loading branch information
jared-thoughtbot committed Jan 17, 2025
1 parent 2bd3037 commit 07bca42
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 9 deletions.
4 changes: 3 additions & 1 deletion app/controllers/administrate/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ def index
resources = order.apply(resources)
resources = paginate_resources(resources)
page = Administrate::Page::Collection.new(dashboard, order: order)
filters = Administrate::Search.new(scoped_resource, dashboard, search_term).valid_filters

render locals: {
resources: resources,
search_term: search_term,
page: page,
show_search_bar: show_search_bar?
show_search_bar: show_search_bar?,
filters: filters
}
end

Expand Down
13 changes: 13 additions & 0 deletions app/views/administrate/application/_index_header.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@
search_term: search_term,
resource_name: display_resource_name(page.resource_name)
) %>

<% if filters.any? %>
<button popovertarget="search-tooltip" class="button--alt" style="margin-right: 2rem;">?</button>

<div popover id="search-tooltip" role="tooltip" style="padding: 2rem;">
<p>Use filters to refine your search:</p>
<ul>
<% filters.keys.each do |filter_key| %>
<li><strong><%= filter_key %></strong>:&lt;value&gt;</li>
<% end %>
</ul>
</div>
<% end %>
<% end %>

<div>
Expand Down
1 change: 1 addition & 0 deletions app/views/administrate/application/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ It renders the `_table` partial to display details about the resources.
search_term: search_term,
page: page,
show_search_bar: show_search_bar,
filters: filters,
)
%>

Expand Down
16 changes: 8 additions & 8 deletions lib/administrate/search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ def run
end
end

def valid_filters
if @dashboard.class.const_defined?(:COLLECTION_FILTERS)
@dashboard.class.const_get(:COLLECTION_FILTERS).stringify_keys
else
{}
end
end

private

def apply_filter(filter, filter_param, resources)
Expand Down Expand Up @@ -116,14 +124,6 @@ def search_results(resources)
.where(query_template, *query_values)
end

def valid_filters
if @dashboard.class.const_defined?(:COLLECTION_FILTERS)
@dashboard.class.const_get(:COLLECTION_FILTERS).stringify_keys
else
{}
end
end

def attribute_types
@dashboard.class.const_get(:ATTRIBUTE_TYPES)
end
Expand Down
43 changes: 43 additions & 0 deletions spec/features/search_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,49 @@ def have_a_search_bar
end
end

describe "search bar tooltip" do
def have_a_search_tooltip
have_css("button[popovertarget=search-tooltip]")
end

it "is visible when the current dashboard has collection filters" do
visit admin_customers_path

expect(page).to have_a_search_tooltip
end

context "when clicked" do
it "shows a popover with the available filters" do
visit admin_customers_path
click_on "?"

expect(page).to have_content("Use filters to refine your search:")
expect(page).to have_content("vip:<value>")
expect(page).to have_content("kind:<value>")
end
end

it "is hidden when the current dashboard has no collection filters" do
CustomerDashboard::COLLECTION_FILTERS = {}.freeze

visit admin_customers_path

expect(page).not_to have_a_search_tooltip
end

it "is hidden when nothing is searchable in the current dashboard" do
CustomerDashboard::ATTRIBUTE_TYPES.each do |_name, field_class|
allow(field_class).to(
receive(:searchable?).and_return(false)
)
end

visit admin_customers_path

expect(page).not_to have_a_search_tooltip
end
end

scenario "admin searches for customer by email", :js do
query = "[email protected]"
perfect_match = create(:customer, email: "[email protected]")
Expand Down

0 comments on commit 07bca42

Please sign in to comment.