Created by: koppen
This adds the option to define a set of filters that can be triggered in order to reduce the number of resources listed on the index page of a dashboard. Currently the only way to trigger the filters is via the search field, using a syntax similar to the one used here on GitHub.
Why
Often we need to expose more detailed/involved queries than those currently capable via simple searches. Previously we'd have to add special actions that query the database correctly and customize the views with links to trigger those actions.
Example
For example, if we want to be able to find "inactive" customers (for some definition of inactive), we can add
COLLECTION_FILTERS = {
inactive: ->(resources) { resources.where("login_at < ?", 1.week.ago) }
}
to a dashboard. This way, we can query the resources of that dashboard by typing bob inactive:
in the search field to find users named "bob" who hasn't logged in the last week.
Credits
This is basically a reimplementation of @nando's work from #276, I merely took some of his thoughts and ideas and repackaged them in a way that makes sense for Administrate anno 2017.
Also in an effort to keep an otherwise huge pull request as small as possible, I haven't gone all the way that he did in the original pull request, so we're missing automatic filtering setup and exposing available filters in the UI.
Nor are the filters implemented here as flexible or powerful as those proposed in #276.
Further details
If you already had the inactive
scope you could define the filter like the following to take advantage of existing ActiveRecord scopes (and other class methods on the resource class).
COLLECTION_FILTERS = {
inactive: ->(resources) { resources.inactive }
}
While the chosen hash-based syntax is a bit more verbose than simply exposing already defined scopes like so:
# app/dashboards/customer_dashboard.rb
COLLECTION_FILTERS = [:inactive]
it allows us to define filters for use in Administrate without having to clutter the resource classes with scopes.
Future proofing
The chosen syntax should allow us to add the above mentioned simpler syntax in a backwards compatible way at some point down the line if we feel the need. For example it could end up looking like:
COLLECTION_FILTERS = {
vip: :vip, # This could call the method `vip` on resources
inactive: ->(resources) { resources.where("login_at < ?", 1.week.ago) }
}
but that's a step I am not ready to take just yet.
It also opens up for a way to have filters that take arguments, ie we could define:
COLLECTION_FILTERS = {
before: ->(resources, args) {
resources.where("created_at < ?", args)
}
}
and query it as before:2016-01-12
which, again, is a step I am not ready to take here and now.