| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- import type { Query as PiniaOrmQuery } from 'pinia-orm'
- import type { ApiFilter } from '~/types/data'
- import ApiResource from '~/models/ApiResource'
- import { SEARCH_STRATEGY } from '~/types/enum/data'
- export default class SearchFilter implements ApiFilter {
- field: string
- filterValue: Ref<string>
- mode: SEARCH_STRATEGY
- reactiveFilter: boolean
- /**
- * @param field
- * @param value
- * @param mode The 'search' strategy (exact [default], partial, start, end, word_start).
- * This strategy is defined API-side, but PiniaOrm needs to know how to handle this.
- * @see https://api-platform.com/docs/core/filters/
- * @param reactiveFilter Est-ce qu'on doit conserver la réactivité du filtre ? Concrètement, dans le cas d'une
- * recherche textuelle, si le filtre est réactif, le résultat de la query Pinia-ORM sera
- * filtré à chaque fois que le filtre est modifié (même sans refresh ou nouvel appel à
- * fetchCollection). Si reactiveFilter est false (comportement par défaut), le résultat
- * de la query ne sera mis à jour qu'en cas de nouvel appel à fetchCollection (ou à refresh()).
- */
- constructor(
- field: string,
- value: Ref<string>,
- mode: SEARCH_STRATEGY = SEARCH_STRATEGY.EXACT,
- reactiveFilter: boolean = false,
- ) {
- this.field = field
- this.filterValue = value
- this.mode = mode
- this.reactiveFilter = reactiveFilter
- }
- public applyToPiniaOrmQuery(
- query: PiniaOrmQuery<ApiResource>,
- ): PiniaOrmQuery<ApiResource> {
- const filterValue = this.reactiveFilter
- ? this.filterValue
- : ref(this.filterValue.value)
- if (!filterValue) {
- return query
- }
- let wordStartRx: RegExp | null = null
- if (this.mode === SEARCH_STRATEGY.WORD_START) {
- wordStartRx = new RegExp(`^${filterValue.value}|\\s${filterValue.value}`)
- }
- return query.where(this.field, (value: string) => {
- if (this.mode === SEARCH_STRATEGY.EXACT) {
- return value === filterValue.value
- } else if (this.mode === SEARCH_STRATEGY.IEXACT) {
- return value.toLowerCase() === filterValue.value.toLowerCase()
- } else if (this.mode === SEARCH_STRATEGY.PARTIAL) {
- return value.includes(filterValue.value)
- } else if (this.mode === SEARCH_STRATEGY.IPARTIAL) {
- return value.toLowerCase().includes(filterValue.value.toLowerCase())
- } else if (this.mode === SEARCH_STRATEGY.START) {
- return value.startsWith(filterValue.value)
- } else if (this.mode === SEARCH_STRATEGY.END) {
- return value.endsWith(filterValue.value)
- } else if (this.mode === SEARCH_STRATEGY.WORD_START) {
- return wordStartRx!.test(value)
- } else {
- throw new Error('Unrecognized mode')
- }
- })
- }
- public getApiQueryPart(): string {
- if (!this.filterValue.value) {
- return ''
- }
- return `${this.field}[]=${this.filterValue.value}`
- }
- }
|