savedSearches.tsx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. import {addErrorMessage} from 'sentry/actionCreators/indicator';
  2. import {Client} from 'sentry/api';
  3. import {MAX_AUTOCOMPLETE_RECENT_SEARCHES} from 'sentry/constants';
  4. import {t} from 'sentry/locale';
  5. import SavedSearchesStore from 'sentry/stores/savedSearchesStore';
  6. import {RecentSearch, SavedSearch, SavedSearchType} from 'sentry/types';
  7. import handleXhrErrorResponse from 'sentry/utils/handleXhrErrorResponse';
  8. export function resetSavedSearches() {
  9. SavedSearchesStore.onReset();
  10. }
  11. export function fetchSavedSearches(api: Client, orgSlug: string): Promise<SavedSearch[]> {
  12. const url = `/organizations/${orgSlug}/searches/`;
  13. SavedSearchesStore.onStartFetchSavedSearches();
  14. const promise = api.requestPromise(url, {
  15. method: 'GET',
  16. });
  17. promise
  18. .then(resp => {
  19. SavedSearchesStore.onFetchSavedSearchesSuccess(resp);
  20. })
  21. .catch(err => {
  22. SavedSearchesStore.onFetchSavedSearchesError(err);
  23. addErrorMessage(t('Unable to load saved searches'));
  24. });
  25. return promise;
  26. }
  27. const getRecentSearchUrl = (orgSlug: string): string =>
  28. `/organizations/${orgSlug}/recent-searches/`;
  29. /**
  30. * Saves search term for `user` + `orgSlug`
  31. *
  32. * @param api API client
  33. * @param orgSlug Organization slug
  34. * @param type Context for where search happened, 0 for issue, 1 for event
  35. * @param query The search term that was used
  36. */
  37. export function saveRecentSearch(
  38. api: Client,
  39. orgSlug: string,
  40. type: SavedSearchType,
  41. query: string
  42. ): Promise<SavedSearch> {
  43. const url = getRecentSearchUrl(orgSlug);
  44. const promise = api.requestPromise(url, {
  45. method: 'POST',
  46. data: {
  47. query,
  48. type,
  49. },
  50. });
  51. promise.catch(handleXhrErrorResponse('Unable to save a recent search'));
  52. return promise;
  53. }
  54. /**
  55. * Creates a saved search
  56. *
  57. * @param api API client
  58. * @param orgSlug Organization slug
  59. * @param name Saved search name
  60. * @param query Query to save
  61. */
  62. export function createSavedSearch(
  63. api: Client,
  64. orgSlug: string,
  65. name: string,
  66. query: string,
  67. sort: string | null
  68. ): Promise<SavedSearch> {
  69. const promise = api.requestPromise(`/organizations/${orgSlug}/searches/`, {
  70. method: 'POST',
  71. data: {
  72. type: SavedSearchType.ISSUE,
  73. query,
  74. name,
  75. sort,
  76. },
  77. });
  78. // Need to wait for saved search to save unfortunately because we need to redirect
  79. // to saved search URL
  80. promise.then(resp => {
  81. SavedSearchesStore.onCreateSavedSearchSuccess(resp);
  82. });
  83. return promise;
  84. }
  85. /**
  86. * Fetches a list of recent search terms conducted by `user` for `orgSlug`
  87. *
  88. * @param api API client
  89. * @param orgSlug Organization slug
  90. * @param type Context for where search happened, 0 for issue, 1 for event
  91. * @param query A query term used to filter results
  92. *
  93. * @return Returns a list of objects of recent search queries performed by user
  94. */
  95. export function fetchRecentSearches(
  96. api: Client,
  97. orgSlug: string,
  98. type: SavedSearchType,
  99. query?: string
  100. ): Promise<RecentSearch[]> {
  101. const url = getRecentSearchUrl(orgSlug);
  102. const promise = api.requestPromise(url, {
  103. query: {
  104. query,
  105. type,
  106. limit: MAX_AUTOCOMPLETE_RECENT_SEARCHES,
  107. },
  108. });
  109. promise.catch(resp => {
  110. if (resp.status !== 401 && resp.status !== 403) {
  111. handleXhrErrorResponse('Unable to fetch recent searches')(resp);
  112. }
  113. });
  114. return promise;
  115. }
  116. const getPinSearchUrl = (orgSlug: string): string =>
  117. `/organizations/${orgSlug}/pinned-searches/`;
  118. export function pinSearch(
  119. api: Client,
  120. orgSlug: string,
  121. type: SavedSearchType,
  122. query: string,
  123. sort?: string
  124. ): Promise<SavedSearch> {
  125. const url = getPinSearchUrl(orgSlug);
  126. // Optimistically update store
  127. SavedSearchesStore.onPinSearch(type, query, sort);
  128. const promise = api.requestPromise(url, {
  129. method: 'PUT',
  130. data: {
  131. query,
  132. type,
  133. sort,
  134. },
  135. });
  136. promise.then(SavedSearchesStore.onPinSearchSuccess);
  137. promise.catch(handleXhrErrorResponse('Unable to pin search'));
  138. promise.catch(() => {
  139. SavedSearchesStore.onUnpinSearch(type);
  140. });
  141. return promise;
  142. }
  143. export function unpinSearch(
  144. api: Client,
  145. orgSlug: string,
  146. type: SavedSearchType,
  147. pinnedSearch: SavedSearch
  148. ) {
  149. const url = getPinSearchUrl(orgSlug);
  150. // Optimistically update store
  151. SavedSearchesStore.onUnpinSearch(type);
  152. const promise = api.requestPromise(url, {
  153. method: 'DELETE',
  154. data: {
  155. type,
  156. },
  157. });
  158. promise.catch(handleXhrErrorResponse('Unable to un-pin search'));
  159. promise.catch(() => {
  160. const {type: pinnedType, query} = pinnedSearch;
  161. SavedSearchesStore.onPinSearch(pinnedType, query);
  162. });
  163. return promise;
  164. }
  165. /**
  166. * Send a DELETE request to remove a saved search
  167. *
  168. * @param api API client
  169. * @param orgSlug Organization slug
  170. * @param search The search to remove.
  171. */
  172. export function deleteSavedSearch(
  173. api: Client,
  174. orgSlug: string,
  175. search: SavedSearch
  176. ): Promise<void> {
  177. const url = `/organizations/${orgSlug}/searches/${search.id}/`;
  178. const promise = api
  179. .requestPromise(url, {
  180. method: 'DELETE',
  181. })
  182. .then(() => SavedSearchesStore.onDeleteSavedSearchSuccess(search))
  183. .catch(handleXhrErrorResponse('Unable to delete a saved search'));
  184. return promise;
  185. }