issueListSetAsDefault.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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 trackAdvancedAnalyticsEvent from 'sentry/utils/analytics/trackAdvancedAnalyticsEvent';
  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. const IssueListSetAsDefault = ({
  30. organization,
  31. sort,
  32. query,
  33. }: IssueListSetAsDefaultProps) => {
  34. const location = useLocation();
  35. const selectedSavedSearch = useSelectedSavedSearch();
  36. const pinnedSearch = usePinnedSearch();
  37. const pinnedSearchActive = selectedSavedSearch
  38. ? pinnedSearch?.id === selectedSavedSearch?.id
  39. : false;
  40. const {mutate: pinSearch, isLoading: isPinning} = usePinSearch({
  41. onSuccess: response => {
  42. const {cursor: _cursor, page: _page, ...currentQuery} = location.query;
  43. browserHistory.replace(
  44. normalizeUrl({
  45. ...location,
  46. pathname: `/organizations/${organization.slug}/issues/searches/${response.id}/`,
  47. query: {referrer: 'search-bar', ...currentQuery},
  48. })
  49. );
  50. },
  51. });
  52. const {mutate: unpinSearch, isLoading: isUnpinning} = useUnpinSearch({
  53. onSuccess: () => {
  54. const {cursor: _cursor, page: _page, ...currentQuery} = location.query;
  55. browserHistory.replace(
  56. normalizeUrl({
  57. ...location,
  58. pathname: `/organizations/${organization.slug}/issues/`,
  59. query: {
  60. referrer: 'search-bar',
  61. query,
  62. sort,
  63. ...currentQuery,
  64. },
  65. })
  66. );
  67. },
  68. });
  69. const onTogglePinnedSearch = () => {
  70. trackAdvancedAnalyticsEvent('search.pin', {
  71. organization,
  72. action: pinnedSearch ? 'unpin' : 'pin',
  73. search_type: 'issues',
  74. query: pinnedSearch?.query ?? query,
  75. });
  76. if (pinnedSearchActive) {
  77. unpinSearch({orgSlug: organization.slug, type: SavedSearchType.ISSUE});
  78. } else {
  79. pinSearch({
  80. orgSlug: organization.slug,
  81. type: SavedSearchType.ISSUE,
  82. query: removeSpace(query),
  83. sort,
  84. });
  85. }
  86. };
  87. // Hide if we are already on the default search,
  88. // except when the user has a different search pinned.
  89. if (
  90. isDefaultIssueStreamSearch({query, sort}) &&
  91. (!pinnedSearch || isDefaultIssueStreamSearch(pinnedSearch))
  92. ) {
  93. return null;
  94. }
  95. return (
  96. <Button
  97. onClick={onTogglePinnedSearch}
  98. size="sm"
  99. icon={<IconBookmark isSolid={pinnedSearchActive} />}
  100. disabled={isPinning || isUnpinning}
  101. >
  102. {pinnedSearchActive ? t('Remove Default') : t('Set as Default')}
  103. </Button>
  104. );
  105. };
  106. export default IssueListSetAsDefault;