[virtualcollection] Provide a better way to declare filter
Opened this issue · 3 comments
blikblum commented
Should allow to define declarative filters, automatic updates on params change
Bonus: having a way to cache derived values used in filters like regex
Current patterns:
dedicated subclass
export class FilteredPatients extends VirtualCollection {
__params = {}
setParams(params = {}) {
Object.assign(this.__params, params)
if (this.parent) {
this.updateFilter()
}
}
acceptModel(model) {
const { name, shift, group, active } = this.__params
let accept = true
if (accept && shift) {
accept = model.get('shift') === shift
}
if (accept && group) {
accept = model.get('group') === group
}
if (accept && name) {
accept = (model.get('name') || '').search(new RegExp(name, 'i')) !== -1
}
if (accept && typeof active === 'boolean') {
accept = model.get('active') === active
}
return accept
}
}
filter option
class PatientSurveysPage extends Component {
@state
filteredPatients = new VirtualCollection(null, {
filter: (model) => {
if (!this.filterParams || !size(this.filterParams)) return true
let accept = true
const { nameRegex, groups, shifts, notResponded } = this.filterParams
if (accept && notResponded) {
accept = !this.hasRespondedSurvey(model.get('satisfaction'))
}
if (accept && groups) {
accept = groups.includes(model.get('group'))
}
if (accept && shifts) {
accept = shifts.includes(model.get('shift'))
}
if (accept && nameRegex) {
accept = (model.get('name') || '').match(nameRegex)
}
return accept
},
})
patients
@property({})
survey
@query('filter-params-bar')
filterParamsBar
connectedCallback() {
super.connectedCallback()
this.filteredPatients.parent = this.patients
}
filterParamsChange() {
const params = this.filterParamsBar.value
this.filterParams = { ...params }
if (params.name) {
this.filterParams.nameRegex = new RegExp(params.name, 'i')
}
this.filteredPatients.updateFilter()
}
}
blikblum commented
Proposal - define params option responsible to calling updateFilter when one of the params change
- batch changes
- use proxy like https://github.com/blikblum/nextbone-firestore/blob/affdcb9e02e3bb8e9e98b30b9c213e393fd4db90/src/collection.js#L46
- Check if param value changed before calling updateFilter
- Allow to pass params on constructor
blikblum commented
Proposal - allow to define filters individually
- accept an object in filter option where values are functions
- allow to cache a value derived from param
example:
const x = new VirtualCollection({
filter: {
name (model, value, params) {
return model.get('name') === value
}
}
})
const x = new VirtualCollection({
filter: {
name: {
prepare(value) {
return new Regexp(value)
}
test (model, value, params) {
return model.get('name').matches(value)
}
}
}
})
blikblum commented
Proposal - allow to customize the query logic
Currently the accept logic is require all params to be true
const x = new VirtualCollection({
query({name, cpf}) {
return name || birthDate
}
})