issueListSetAsDefault.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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. sort,
  72. });
  73. if (pinnedSearchActive) {
  74. unpinSearch({orgSlug: organization.slug, type: SavedSearchType.ISSUE});
  75. } else {
  76. pinSearch({
  77. orgSlug: organization.slug,
  78. type: SavedSearchType.ISSUE,
  79. query: removeSpace(query),
  80. sort,
  81. });
  82. }
  83. };
  84. // Hide if we are already on the default search,
  85. // except when the user has a different search pinned.
  86. if (
  87. isDefaultIssueStreamSearch({query, sort}) &&
  88. (!pinnedSearch || isDefaultIssueStreamSearch(pinnedSearch))
  89. ) {
  90. return null;
  91. }
  92. return (
  93. <Button
  94. onClick={onTogglePinnedSearch}
  95. size="sm"
  96. icon={<IconBookmark isSolid={pinnedSearchActive} />}
  97. disabled={isPinning || isUnpinning}
  98. >
  99. {pinnedSearchActive ? t('Remove Default') : t('Set as Default')}
  100. </Button>
  101. );
  102. }
  103. export default IssueListSetAsDefault;