issueSearchWithSavedSearches.tsx 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import styled from '@emotion/styled';
  2. import {Button, ButtonLabel} from 'sentry/components/button';
  3. import {t} from 'sentry/locale';
  4. import trackAdvancedAnalyticsEvent from 'sentry/utils/analytics/trackAdvancedAnalyticsEvent';
  5. import useOrganization from 'sentry/utils/useOrganization';
  6. import {useSyncedLocalStorageState} from 'sentry/utils/useSyncedLocalStorageState';
  7. import {SAVED_SEARCHES_SIDEBAR_OPEN_LOCALSTORAGE_KEY} from 'sentry/views/issueList/utils';
  8. import {useSelectedSavedSearch} from 'sentry/views/issueList/utils/useSelectedSavedSearch';
  9. import IssueListSearchBar from './searchBar';
  10. type IssueSearchWithSavedSearchesProps = {
  11. onSearch: (query: string) => void;
  12. query: string;
  13. };
  14. export function IssueSearchWithSavedSearches({
  15. query,
  16. onSearch,
  17. }: IssueSearchWithSavedSearchesProps) {
  18. const organization = useOrganization();
  19. const selectedSavedSearch = useSelectedSavedSearch();
  20. const [isSavedSearchesOpen, setIsSavedSearchesOpen] = useSyncedLocalStorageState(
  21. SAVED_SEARCHES_SIDEBAR_OPEN_LOCALSTORAGE_KEY,
  22. false
  23. );
  24. function onSavedSearchesToggleClicked() {
  25. const newOpenState = !isSavedSearchesOpen;
  26. trackAdvancedAnalyticsEvent('search.saved_search_sidebar_toggle_clicked', {
  27. organization,
  28. open: newOpenState,
  29. });
  30. setIsSavedSearchesOpen(newOpenState);
  31. }
  32. return (
  33. <SearchBarWithButtonContainer>
  34. <StyledButton onClick={onSavedSearchesToggleClicked}>
  35. {selectedSavedSearch?.name ?? t('Custom Search')}
  36. </StyledButton>
  37. <StyledIssueListSearchBarWithButton
  38. searchSource="main_search"
  39. organization={organization}
  40. query={query || ''}
  41. onSearch={onSearch}
  42. excludedTags={['environment']}
  43. />
  44. </SearchBarWithButtonContainer>
  45. );
  46. }
  47. const SearchBarWithButtonContainer = styled('div')`
  48. flex: 1;
  49. display: flex;
  50. align-items: stretch;
  51. width: 100%;
  52. @media (min-width: ${p => p.theme.breakpoints.small}) {
  53. flex-basis: 35rem;
  54. }
  55. `;
  56. const StyledButton = styled(Button)`
  57. /* Hide this button on small screens */
  58. display: none;
  59. @media (min-width: ${p => p.theme.breakpoints.small}) {
  60. display: flex;
  61. align-items: center;
  62. height: 100%;
  63. max-width: 180px;
  64. text-align: left;
  65. border-top-right-radius: 0;
  66. border-bottom-right-radius: 0;
  67. border-right: none;
  68. ${ButtonLabel} {
  69. height: auto;
  70. display: block;
  71. ${p => p.theme.overflowEllipsis};
  72. }
  73. }
  74. `;
  75. const StyledIssueListSearchBarWithButton = styled(IssueListSearchBar)`
  76. flex: 1;
  77. @media (min-width: ${p => p.theme.breakpoints.small}) {
  78. border-top-left-radius: 0;
  79. border-bottom-left-radius: 0;
  80. }
  81. `;