releasesSelectControl.tsx 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import {useState} from 'react';
  2. import styled from '@emotion/styled';
  3. import Badge from 'sentry/components/badge';
  4. import CompactSelect from 'sentry/components/forms/compactSelect';
  5. import TextOverflow from 'sentry/components/textOverflow';
  6. import {IconReleases} from 'sentry/icons';
  7. import {t} from 'sentry/locale';
  8. import {useReleases} from 'sentry/utils/releases/releasesProvider';
  9. import {DashboardFilterKeys, DashboardFilters} from './types';
  10. type Props = {
  11. selectedReleases: string[];
  12. className?: string;
  13. handleChangeFilter?: (activeFilters: DashboardFilters) => void;
  14. isDisabled?: boolean;
  15. };
  16. function ReleasesSelectControl({
  17. handleChangeFilter,
  18. selectedReleases,
  19. className,
  20. isDisabled,
  21. }: Props) {
  22. const {releases, loading} = useReleases();
  23. const [activeReleases, setActiveReleases] = useState<string[]>(selectedReleases);
  24. const triggerLabel = activeReleases.length ? (
  25. <TextOverflow>{activeReleases[0]} </TextOverflow>
  26. ) : (
  27. t('All Releases')
  28. );
  29. return (
  30. <CompactSelect
  31. multiple
  32. isClearable
  33. isSearchable
  34. isDisabled={isDisabled}
  35. isLoading={loading}
  36. menuTitle={t('Filter Releases')}
  37. className={className}
  38. options={
  39. releases.length
  40. ? releases.map(release => {
  41. return {
  42. label: release.shortVersion ?? release.version,
  43. value: release.version,
  44. };
  45. })
  46. : []
  47. }
  48. onChange={opts => setActiveReleases(opts.map(opt => opt.value))}
  49. onClose={() => {
  50. handleChangeFilter?.({[DashboardFilterKeys.RELEASE]: activeReleases});
  51. }}
  52. value={activeReleases}
  53. triggerLabel={
  54. <ButtonLabelWrapper>
  55. {triggerLabel}{' '}
  56. {activeReleases.length > 1 && (
  57. <StyledBadge text={`+${activeReleases.length - 1}`} />
  58. )}
  59. </ButtonLabelWrapper>
  60. }
  61. triggerProps={{icon: <IconReleases />}}
  62. />
  63. );
  64. }
  65. export default ReleasesSelectControl;
  66. const StyledBadge = styled(Badge)`
  67. flex-shrink: 0;
  68. `;
  69. const ButtonLabelWrapper = styled('span')`
  70. width: 100%;
  71. text-align: left;
  72. align-items: center;
  73. display: inline-grid;
  74. grid-template-columns: 1fr auto;
  75. `;