Query.ts 2.1 KB

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