Skip to content

[virtualcollection] Provide a better way to declare filter #36

@blikblum

Description

@blikblum

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()
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions