searchBar.tsx 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import {useCallback} from 'react';
  2. // eslint-disable-next-line no-restricted-imports
  3. import {fetchTagValues} from 'sentry/actionCreators/tags';
  4. import SmartSearchBar from 'sentry/components/smartSearchBar';
  5. import {Organization, SavedSearchType, Tag, TagCollection} from 'sentry/types';
  6. import {getUtcDateString} from 'sentry/utils/dates';
  7. import {FieldKind, getFieldDefinition} from 'sentry/utils/fields';
  8. import useApi from 'sentry/utils/useApi';
  9. import usePageFilters from 'sentry/utils/usePageFilters';
  10. import withIssueTags, {WithIssueTagsProps} from 'sentry/utils/withIssueTags';
  11. const getSupportedTags = (supportedTags: TagCollection) =>
  12. Object.fromEntries(
  13. Object.keys(supportedTags).map(key => [
  14. key,
  15. {
  16. ...supportedTags[key],
  17. kind:
  18. getFieldDefinition(key)?.kind ??
  19. (supportedTags[key].predefined ? FieldKind.FIELD : FieldKind.TAG),
  20. },
  21. ])
  22. );
  23. interface Props extends React.ComponentProps<typeof SmartSearchBar>, WithIssueTagsProps {
  24. organization: Organization;
  25. }
  26. const EXCLUDED_TAGS = ['environment'];
  27. function IssueListSearchBar({organization, tags, ...props}: Props) {
  28. const api = useApi();
  29. const {selection: pageFilters} = usePageFilters();
  30. const tagValueLoader = useCallback(
  31. (key: string, search: string) => {
  32. const orgSlug = organization.slug;
  33. const projectIds = pageFilters.projects.map(id => id.toString());
  34. const endpointParams = {
  35. start: getUtcDateString(pageFilters.datetime.start),
  36. end: getUtcDateString(pageFilters.datetime.end),
  37. statsPeriod: pageFilters.datetime.period,
  38. };
  39. return fetchTagValues({
  40. api,
  41. orgSlug,
  42. tagKey: key,
  43. search,
  44. projectIds,
  45. endpointParams,
  46. });
  47. },
  48. [
  49. api,
  50. organization.slug,
  51. pageFilters.datetime.end,
  52. pageFilters.datetime.period,
  53. pageFilters.datetime.start,
  54. pageFilters.projects,
  55. ]
  56. );
  57. const getTagValues = useCallback(
  58. async (tag: Tag, query: string): Promise<string[]> => {
  59. const values = await tagValueLoader(tag.key, query);
  60. return values.map(({value}) => value);
  61. },
  62. [tagValueLoader]
  63. );
  64. return (
  65. <SmartSearchBar
  66. hasRecentSearches
  67. savedSearchType={SavedSearchType.ISSUE}
  68. onGetTagValues={getTagValues}
  69. excludedTags={EXCLUDED_TAGS}
  70. maxMenuHeight={500}
  71. supportedTags={getSupportedTags(tags)}
  72. organization={organization}
  73. {...props}
  74. />
  75. );
  76. }
  77. export default withIssueTags(IssueListSearchBar);