avo
avo copied to clipboard
[RFC] Dynamic filters 2.0
The Dynamic filters feature is a powerful and beautiful way of letting users query data.
We'd love to give the developer an API with which they can further customize the filters. Some of the things we'd like to have customizable:
- field (text, number, combobox, date)
- conditions (is, is not, is withing, etc.)
- suggestions (options)
- query logic. give the developer the raw power to make the query what they want.
Let's also change the API in which they are declared. It's clear to me that just calling filterable is not enough. It's a good "easy" way to do it, but we need more power.
Things to consider with this new API/DSL:
- should we build them on the resource?
- should we build them in a separate file?
### Related issues
- [ ] https://github.com/avo-hq/avo/issues/2802
- [ ] https://github.com/avo-hq/avo/issues/2634
- [ ] https://github.com/avo-hq/avo/issues/2621
Examples
Pseudo-API below. Not final.
field :name, as: :select, filterable: {
conditions: [:is, :is_not],
options: -> { User.states }
}
self.dynamic_filters = -> {
filters: [
{
attribute: :name,
type: :select,
conditions: [:is, :present, :blank, :nil],
field: {
type: :select,
options: [:one, :two, :three
}
}
]
}
Experiments
self.dynamic_filters = {
fields: [:status, :state],
filters: [
# hierarchy
# - database
# - field
# - dynamic_filters
avo_filter(attribute: :name, type: :select),
Avo::Filter.new(attribute: :name, type: :select),
Avo::Filter.new(attribute: :name, type: :select),
Avo::Filter.new(attribute: :name, type: :select),
Avo::Filter.new(attribute: :name, type: :select),
{
attribute: :name,
type: :select,
conditions: [:is, :present, :blank, :nil],
field: {
type: :select,
options: [:one, :two, :three]
},
# fields: [{
# id: :first_name,
# type: :select,
# options: [:one, :two, :three]
# },{
# id: :last_name,
# type: :select,
# options: [:one, :two, :three]
# }]
},
{
attribute: :last_name,
type: :select,
conditions: [:is, :present, :blank, :nil],
field: {
type: :select,
options: [:one, :two, :three]
}
}
]
}
filterable: Avo::Filter.new(attribute: :name, type: :select),
@adrianthedev do you plan for some lazy loading version? Or even a belongs-to type?
@adrianthedev do you plan for some lazy loading version? Or even a belongs-to type?
Yes @jetienne. Me and the team are going to talk about and build some kind of lazy-loaded select somehow which can be applied system-wide. We'll evaluate https://github.com/josefarias/hotwire_combobox. Looks promising.