TimeFilter.ts 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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. // @ts-expect-error: l'erreur de typage de field et value est trop délicate à corriger, on ignore pour le moment
  60. return query.where(this.field, (value: string) =>
  61. this.search(value, filterValue),
  62. )
  63. }
  64. public getApiQueryPart(): string {
  65. if (!this.filterValue.value) {
  66. return ''
  67. }
  68. return `${this.field}[${this.mode}]=${this.filterValue.value}`
  69. }
  70. }