issueListSetAsDefault.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import {browserHistory} from 'react-router';
  2. import {Button} from 'sentry/components/button';
  3. import {removeSpace} from 'sentry/components/smartSearchBar/utils';
  4. import {IconBookmark} from 'sentry/icons';
  5. import {t} from 'sentry/locale';
  6. import {Organization, SavedSearchType} from 'sentry/types';
  7. import {trackAnalytics} from 'sentry/utils/analytics';
  8. import {useLocation} from 'sentry/utils/useLocation';
  9. import useOrganization from 'sentry/utils/useOrganization';
  10. import {normalizeUrl} from 'sentry/utils/withDomainRequired';
  11. import {usePinSearch} from 'sentry/views/issueList/mutations/usePinSearch';
  12. import {useUnpinSearch} from 'sentry/views/issueList/mutations/useUnpinSearch';
  13. import {useFetchSavedSearchesForOrg} from 'sentry/views/issueList/queries/useFetchSavedSearchesForOrg';
  14. import {isDefaultIssueStreamSearch} from 'sentry/views/issueList/utils';
  15. import {useSelectedSavedSearch} from 'sentry/views/issueList/utils/useSelectedSavedSearch';
  16. interface IssueListSetAsDefaultProps {
  17. organization: Organization;
  18. query: string;
  19. sort: string;
  20. }
  21. const usePinnedSearch = () => {
  22. const organization = useOrganization();
  23. const {data: savedSearches} = useFetchSavedSearchesForOrg(
  24. {orgSlug: organization.slug},
  25. {notifyOnChangeProps: ['data']}
  26. );
  27. return savedSearches?.find(savedSearch => savedSearch.isPinned) ?? null;
  28. };
  29. function IssueListSetAsDefault({organization, sort, query}: IssueListSetAsDefaultProps) {
  30. const location = useLocation();
  31. const selectedSavedSearch = useSelectedSavedSearch();
  32. const pinnedSearch = usePinnedSearch();
  33. const pinnedSearchActive = selectedSavedSearch
  34. ? pinnedSearch?.id === selectedSavedSearch?.id
  35. : false;
  36. const {mutate: pinSearch, isLoading: isPinning} = usePinSearch({
  37. onSuccess: response => {
  38. const {cursor: _cursor, page: _page, ...currentQuery} = location.query;
  39. browserHistory.replace(
  40. normalizeUrl({
  41. ...location,
  42. pathname: `/organizations/${organization.slug}/issues/searches/${response.id}/`,
  43. query: {referrer: 'search-bar', ...currentQuery},
  44. })
  45. );
  46. },
  47. });
  48. const {mutate: unpinSearch, isLoading: isUnpinning} = useUnpinSearch({
  49. onSuccess: () => {
  50. const {cursor: _cursor, page: _page, ...currentQuery} = location.query;
  51. browserHistory.replace(
  52. normalizeUrl({
  53. ...location,
  54. pathname: `/organizations/${organization.slug}/issues/`,
  55. query: {
  56. referrer: 'search-bar',
  57. query,
  58. sort,
  59. ...currentQuery,
  60. },
  61. })
  62. );
  63. },
  64. });
  65. const onTogglePinnedSearch = () => {
  66. trackAnalytics('search.pin', {
  67. organization,
  68. action: pinnedSearch ? 'unpin' : 'pin',
  69. search_type: 'issues',
  70. query: pinnedSearch?.query ?? query,
  71. });
  72. if (pinnedSearchActive) {
  73. unpinSearch({orgSlug: organization.slug, type: SavedSearchType.ISSUE});
  74. } else {
  75. pinSearch({
  76. orgSlug: organization.slug,
  77. type: SavedSearchType.ISSUE,
  78. query: removeSpace(query),
  79. sort,
  80. });
  81. }
  82. };
  83. // Hide if we are already on the default search,
  84. // except when the user has a different search pinned.
  85. if (
  86. isDefaultIssueStreamSearch({query, sort}) &&
  87. (!pinnedSearch || isDefaultIssueStreamSearch(pinnedSearch))
  88. ) {
  89. return null;
  90. }
  91. return (
  92. <Button
  93. onClick={onTogglePinnedSearch}
  94. size="sm"
  95. icon={<IconBookmark isSolid={pinnedSearchActive} />}
  96. disabled={isPinning || isUnpinning}
  97. >
  98. {pinnedSearchActive ? t('Remove Default') : t('Set as Default')}
  99. </Button>
  100. );
  101. }
  102. export default IssueListSetAsDefault;