TimeFilter.ts 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import type { Query as PiniaOrmQuery } from 'pinia-orm'
  2. import type { Ref } from 'vue'
  3. import type { ApiFilter } from '~/types/data'
  4. import type ApiResource from '~/models/ApiResource'
  5. import { TIME_STRATEGY } from '~/types/enum/data'
  6. import AbstractFilter from '~/services/data/Filters/AbstractFilter'
  7. import RefUtils from '~/services/utils/refUtils'
  8. import DateUtils from '~/services/utils/dateUtils'
  9. export default class TimeFilter extends AbstractFilter implements ApiFilter {
  10. field: string
  11. filterValue: Ref<string | null>
  12. mode: TIME_STRATEGY
  13. /**
  14. * @param field
  15. * @param value
  16. * @param mode The 'time' strategy (after, before, strictly_after, strictly_before).
  17. * This strategy is defined API-side, but PiniaOrm needs to know how to handle this.
  18. * @see https://api-platform.com/docs/core/filters/
  19. * @param reactiveFilter
  20. */
  21. constructor(
  22. field: string,
  23. value: Ref<string | null>,
  24. mode: TIME_STRATEGY,
  25. reactiveFilter: boolean = false,
  26. ) {
  27. super(reactiveFilter)
  28. this.field = field
  29. this.filterValue = value
  30. this.mode = mode
  31. }
  32. protected search(value: string, filterValue: Ref<string | null>): boolean {
  33. if (filterValue.value === null) {
  34. return false
  35. }
  36. switch (this.mode) {
  37. case TIME_STRATEGY.BEFORE:
  38. return DateUtils.isBefore(value, filterValue.value, false)
  39. case TIME_STRATEGY.AFTER:
  40. return DateUtils.isBefore(filterValue.value, value, false)
  41. case TIME_STRATEGY.STRICTLY_BEFORE:
  42. return DateUtils.isBefore(value, filterValue.value)
  43. case TIME_STRATEGY.STRICTLY_AFTER:
  44. return DateUtils.isBefore(filterValue.value, value)
  45. default:
  46. throw new Error('Unrecognized mode')
  47. }
  48. }
  49. public applyToPiniaOrmQuery<T extends ApiResource>(
  50. query: PiniaOrmQuery<T>,
  51. ): PiniaOrmQuery<T> {
  52. const filterValue = RefUtils.castToRef(
  53. this.filterValue,
  54. this.reactiveFilter,
  55. )
  56. if (!filterValue.value) {
  57. return query
  58. }
  59. return query.where(this.field, (value: string) =>
  60. this.search(value, filterValue),
  61. )
  62. }
  63. public getApiQueryPart(): string {
  64. if (!this.filterValue.value) {
  65. return ''
  66. }
  67. return `${this.field}[${this.mode}]=${this.filterValue.value}`
  68. }
  69. }