issueListSetAsDefault.tsx 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // eslint-disable-next-line no-restricted-imports
  2. import {browserHistory, withRouter, WithRouterProps} from 'react-router';
  3. import isNil from 'lodash/isNil';
  4. import Button from 'sentry/components/button';
  5. import {removeSpace} from 'sentry/components/smartSearchBar/utils';
  6. import {IconBookmark} from 'sentry/icons';
  7. import {t} from 'sentry/locale';
  8. import {Organization, SavedSearch, SavedSearchType} from 'sentry/types';
  9. import trackAdvancedAnalyticsEvent from 'sentry/utils/analytics/trackAdvancedAnalyticsEvent';
  10. import {usePinSearch} from 'sentry/views/issueList/mutations/usePinSearch';
  11. import {useUnpinSearch} from 'sentry/views/issueList/mutations/useUnpinSearch';
  12. interface IssueListSetAsDefaultProps extends WithRouterProps {
  13. organization: Organization;
  14. query: string;
  15. savedSearch: SavedSearch | null;
  16. sort: string;
  17. }
  18. const IssueListSetAsDefault = ({
  19. location,
  20. organization,
  21. savedSearch,
  22. sort,
  23. query,
  24. }: IssueListSetAsDefaultProps) => {
  25. const pinnedSearch = savedSearch?.isPinned ? savedSearch : undefined;
  26. const pinnedSearchActive = !isNil(pinnedSearch);
  27. const {mutate: pinSearch, isLoading: isPinning} = usePinSearch({
  28. onSuccess: response => {
  29. const {cursor: _cursor, page: _page, ...currentQuery} = location.query;
  30. browserHistory.push({
  31. ...location,
  32. pathname: `/organizations/${organization.slug}/issues/searches/${response.id}/`,
  33. query: {referrer: 'search-bar', ...currentQuery},
  34. });
  35. },
  36. });
  37. const {mutate: unpinSearch, isLoading: isUnpinning} = useUnpinSearch({
  38. onSuccess: () => {
  39. const {cursor: _cursor, page: _page, ...currentQuery} = location.query;
  40. browserHistory.push({
  41. ...location,
  42. pathname: `/organizations/${organization.slug}/issues/`,
  43. query: {
  44. referrer: 'search-bar',
  45. ...currentQuery,
  46. },
  47. });
  48. },
  49. });
  50. const onTogglePinnedSearch = () => {
  51. trackAdvancedAnalyticsEvent('search.pin', {
  52. organization,
  53. action: pinnedSearch ? 'unpin' : 'pin',
  54. search_type: 'issues',
  55. query: pinnedSearch?.query ?? query,
  56. });
  57. if (pinnedSearch) {
  58. unpinSearch({orgSlug: organization.slug, type: SavedSearchType.ISSUE});
  59. } else {
  60. pinSearch({
  61. orgSlug: organization.slug,
  62. type: SavedSearchType.ISSUE,
  63. query: removeSpace(query),
  64. sort,
  65. });
  66. }
  67. };
  68. if (!organization.features.includes('issue-list-saved-searches-v2')) {
  69. return null;
  70. }
  71. return (
  72. <Button
  73. onClick={onTogglePinnedSearch}
  74. size="sm"
  75. icon={<IconBookmark isSolid={pinnedSearchActive} />}
  76. disabled={isPinning || isUnpinning}
  77. >
  78. {pinnedSearchActive ? t('Remove Default') : t('Set as Default')}
  79. </Button>
  80. );
  81. };
  82. export default withRouter(IssueListSetAsDefault);