groupPriority.tsx 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import {useMemo} from 'react';
  2. import type {Theme} from '@emotion/react';
  3. import styled from '@emotion/styled';
  4. import {Button} from 'sentry/components/button';
  5. import {DropdownMenu, type MenuItemProps} from 'sentry/components/dropdownMenu';
  6. import Tag from 'sentry/components/tag';
  7. import {IconChevron} from 'sentry/icons';
  8. import {t} from 'sentry/locale';
  9. import {space} from 'sentry/styles/space';
  10. import {PriorityLevel} from 'sentry/types';
  11. type GroupPriorityDropdownProps = {
  12. onChange: (value: PriorityLevel) => void;
  13. value: PriorityLevel;
  14. };
  15. type GroupPriorityBadgeProps = {
  16. priority: PriorityLevel;
  17. children?: React.ReactNode;
  18. };
  19. const PRIORITY_KEY_TO_LABEL: Record<PriorityLevel, string> = {
  20. [PriorityLevel.HIGH]: t('High'),
  21. [PriorityLevel.MEDIUM]: t('Medium'),
  22. [PriorityLevel.LOW]: t('Low'),
  23. };
  24. const PRIORITY_OPTIONS = [PriorityLevel.HIGH, PriorityLevel.MEDIUM, PriorityLevel.LOW];
  25. function getTagTypeForPriority(priority: string): keyof Theme['tag'] {
  26. switch (priority) {
  27. case PriorityLevel.HIGH:
  28. return 'error';
  29. case PriorityLevel.MEDIUM:
  30. return 'warning';
  31. case PriorityLevel.LOW:
  32. default:
  33. return 'default';
  34. }
  35. }
  36. export function GroupPriorityBadge({priority, children}: GroupPriorityBadgeProps) {
  37. return (
  38. <StyledTag type={getTagTypeForPriority(priority)}>
  39. {PRIORITY_KEY_TO_LABEL[priority] ?? t('Unknown')}
  40. {children}
  41. </StyledTag>
  42. );
  43. }
  44. export function GroupPriorityDropdown({value, onChange}: GroupPriorityDropdownProps) {
  45. const options: MenuItemProps[] = useMemo(() => {
  46. return PRIORITY_OPTIONS.map(priority => ({
  47. textValue: PRIORITY_KEY_TO_LABEL[priority],
  48. key: priority,
  49. label: <GroupPriorityBadge priority={priority} />,
  50. onAction: () => onChange(priority),
  51. }));
  52. }, [onChange]);
  53. return (
  54. <DropdownMenu
  55. size="sm"
  56. trigger={triggerProps => (
  57. <DropdownButton
  58. {...triggerProps}
  59. aria-label={t('Modify issue priority')}
  60. size="zero"
  61. >
  62. <GroupPriorityBadge priority={value}>
  63. <IconChevron direction="down" size="xs" />
  64. </GroupPriorityBadge>
  65. </DropdownButton>
  66. )}
  67. items={options}
  68. />
  69. );
  70. }
  71. const DropdownButton = styled(Button)`
  72. font-weight: normal;
  73. border: none;
  74. padding: 0;
  75. height: unset;
  76. border-radius: 10px;
  77. `;
  78. const StyledTag = styled(Tag)`
  79. span {
  80. display: flex;
  81. align-items: center;
  82. gap: ${space(0.5)};
  83. }
  84. `;