savedSearches.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import type {Client} from 'sentry/api';
  2. import {MAX_AUTOCOMPLETE_RECENT_SEARCHES} from 'sentry/constants';
  3. import type {RecentSearch, SavedSearch, SavedSearchType} from 'sentry/types/group';
  4. import {defined} from 'sentry/utils';
  5. import {handleXhrErrorResponse} from 'sentry/utils/handleXhrErrorResponse';
  6. import {
  7. type ApiQueryKey,
  8. useApiQuery,
  9. type UseApiQueryOptions,
  10. } from 'sentry/utils/queryClient';
  11. import type RequestError from 'sentry/utils/requestError/requestError';
  12. import useOrganization from 'sentry/utils/useOrganization';
  13. const getRecentSearchUrl = (orgSlug: string): string =>
  14. `/organizations/${orgSlug}/recent-searches/`;
  15. /**
  16. * Saves search term for `user` + `orgSlug`
  17. *
  18. * @param api API client
  19. * @param orgSlug Organization slug
  20. * @param type Context for where search happened, 0 for issue, 1 for event
  21. * @param query The search term that was used
  22. */
  23. export function saveRecentSearch(
  24. api: Client,
  25. orgSlug: string,
  26. type: SavedSearchType,
  27. query: string
  28. ): Promise<SavedSearch> {
  29. const url = getRecentSearchUrl(orgSlug);
  30. const promise = api.requestPromise(url, {
  31. method: 'POST',
  32. data: {
  33. query,
  34. type,
  35. },
  36. });
  37. promise.catch((err: RequestError) =>
  38. handleXhrErrorResponse('Unable to save a recent search', err)
  39. );
  40. return promise;
  41. }
  42. /**
  43. * Fetches a list of recent search terms conducted by `user` for `orgSlug`
  44. *
  45. * @param api API client
  46. * @param orgSlug Organization slug
  47. * @param type Context for where search happened, 0 for issue, 1 for event
  48. * @param query A query term used to filter results
  49. *
  50. * @return Returns a list of objects of recent search queries performed by user
  51. */
  52. export function fetchRecentSearches(
  53. api: Client,
  54. orgSlug: string,
  55. type: SavedSearchType,
  56. query?: string
  57. ): Promise<RecentSearch[]> {
  58. const url = getRecentSearchUrl(orgSlug);
  59. // Prevent requests that are too long
  60. // 8k is the default max size for a URL in nginx
  61. // Docs - http://nginx.org/en/docs/http/ngx_http_core_module.html#large_client_header_buffers
  62. // 5000 saves us room for other query params and url
  63. // Recent searches stops being useful at a certain point
  64. if (query && query.length > 5000) {
  65. query = query.substring(0, 5000);
  66. }
  67. const promise = api.requestPromise(url, {
  68. query: {
  69. query,
  70. type,
  71. limit: MAX_AUTOCOMPLETE_RECENT_SEARCHES,
  72. },
  73. });
  74. promise.catch((resp: RequestError) => {
  75. if (resp.status !== 401 && resp.status !== 403) {
  76. handleXhrErrorResponse('Unable to fetch recent searches', resp);
  77. }
  78. });
  79. return promise;
  80. }
  81. export function makeRecentSearchesQueryKey({
  82. limit,
  83. orgSlug,
  84. savedSearchType,
  85. query,
  86. }: {
  87. limit: number;
  88. orgSlug: string;
  89. savedSearchType: SavedSearchType | null;
  90. query?: string;
  91. }): ApiQueryKey {
  92. return [
  93. getRecentSearchUrl(orgSlug),
  94. {
  95. query: {
  96. query,
  97. type: savedSearchType,
  98. limit,
  99. },
  100. },
  101. ];
  102. }
  103. export function useFetchRecentSearches(
  104. {
  105. query,
  106. savedSearchType,
  107. limit = MAX_AUTOCOMPLETE_RECENT_SEARCHES,
  108. }: {
  109. savedSearchType: SavedSearchType | null;
  110. limit?: number;
  111. query?: string;
  112. },
  113. options: Partial<UseApiQueryOptions<RecentSearch[]>> = {}
  114. ) {
  115. const organization = useOrganization();
  116. return useApiQuery<RecentSearch[]>(
  117. makeRecentSearchesQueryKey({
  118. limit,
  119. orgSlug: organization.slug,
  120. query,
  121. savedSearchType,
  122. }),
  123. {
  124. staleTime: 0,
  125. enabled: defined(savedSearchType),
  126. ...options,
  127. }
  128. );
  129. }