Query.ts 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import type { Query as PiniaOrmQuery } from 'pinia-orm'
  2. import type { ApiFilter } from '~/types/data'
  3. import type ApiResource from '~/models/ApiResource'
  4. import PageFilter from '~/services/data/Filters/PageFilter'
  5. import OrderBy from '~/services/data/Filters/OrderBy'
  6. /**
  7. * A Query to filter and sort ApiResources.
  8. * Pass it to the `fetchCollection` method of the EntityManager to apply these filters to both
  9. * API fetch and PiniaOrm query, which allow to maintain this collection reactivity.
  10. */
  11. export default class Query {
  12. protected filters: Array<ApiFilter> = []
  13. constructor(...filters: Array<ApiFilter>) {
  14. this.filters = filters
  15. }
  16. /**
  17. * Add an ApiFilter to the query
  18. *
  19. * @param filter
  20. */
  21. public add(filter: ApiFilter): this {
  22. this.filters.push(filter)
  23. return this
  24. }
  25. /**
  26. * Clear the query filters
  27. */
  28. public clear(): this {
  29. this.filters = []
  30. return this
  31. }
  32. /**
  33. * Returns the URL's query in the Api Platform format.
  34. *
  35. * @see https://api-platform.com/docs/core/filters/
  36. */
  37. public getUrlQuery(): string {
  38. const queryParts: string[] = []
  39. this.filters.forEach((filter) => {
  40. const queryPart = filter.getApiQueryPart()
  41. if (queryPart) {
  42. queryParts.push(queryPart)
  43. }
  44. })
  45. return queryParts.filter((p) => !!p).join('&')
  46. }
  47. /**
  48. * Apply this query to the pinia orm query and return it.
  49. *
  50. * @see https://pinia-orm.codedredd.de/guide/repository/retrieving-data
  51. * @param query
  52. */
  53. public applyToPiniaOrmQuery<T extends ApiResource>(
  54. query: PiniaOrmQuery<T>,
  55. ): PiniaOrmQuery<T> {
  56. // 'Where' filters shall be applied first, then orderBy filters, and finally pagination
  57. const where: ApiFilter[] = []
  58. const orderBy: ApiFilter[] = []
  59. const pagination: ApiFilter[] = []
  60. this.filters.forEach((filter) => {
  61. if (filter instanceof PageFilter) {
  62. pagination.push(filter)
  63. } else if (filter instanceof OrderBy) {
  64. orderBy.push(filter)
  65. } else {
  66. where.push(filter)
  67. }
  68. })
  69. const filters = [...where, ...orderBy, ...pagination]
  70. filters.forEach((filter) => {
  71. query = filter.applyToPiniaOrmQuery(query)
  72. })
  73. return query
  74. }
  75. }