feedbackListBulkSelection.tsx 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import Button from 'sentry/components/actions/button';
  2. import {Flex} from 'sentry/components/container/flex';
  3. import {DropdownMenu} from 'sentry/components/dropdownMenu';
  4. import ErrorBoundary from 'sentry/components/errorBoundary';
  5. import type decodeMailbox from 'sentry/components/feedback/decodeMailbox';
  6. import useBulkEditFeedbacks from 'sentry/components/feedback/list/useBulkEditFeedbacks';
  7. import type useListItemCheckboxState from 'sentry/components/feedback/list/useListItemCheckboxState';
  8. import {IconEllipsis} from 'sentry/icons/iconEllipsis';
  9. import {t, tct} from 'sentry/locale';
  10. import {space} from 'sentry/styles/space';
  11. import {GroupStatus} from 'sentry/types/group';
  12. interface Props
  13. extends Pick<
  14. ReturnType<typeof useListItemCheckboxState>,
  15. 'countSelected' | 'deselectAll' | 'selectedIds'
  16. > {
  17. mailbox: ReturnType<typeof decodeMailbox>;
  18. }
  19. export default function FeedbackListBulkSelection({
  20. mailbox,
  21. countSelected,
  22. selectedIds,
  23. deselectAll,
  24. }: Props) {
  25. const {onToggleResovled, onMarkAsRead, onMarkUnread} = useBulkEditFeedbacks({
  26. selectedIds,
  27. deselectAll,
  28. });
  29. const newMailboxResolve =
  30. mailbox === 'resolved' ? GroupStatus.UNRESOLVED : GroupStatus.RESOLVED;
  31. // reuse the issues ignored category for spam feedbacks
  32. const newMailboxSpam =
  33. mailbox === 'ignored' ? GroupStatus.UNRESOLVED : GroupStatus.IGNORED;
  34. return (
  35. <Flex gap={space(1)} align="center" justify="space-between" flex="1 0 auto">
  36. <span>
  37. <strong>
  38. {tct('[countSelected] Selected', {
  39. countSelected,
  40. })}
  41. </strong>
  42. </span>
  43. <Flex gap={space(1)} justify="flex-end">
  44. <ErrorBoundary mini>
  45. <Button onClick={() => onToggleResovled({newMailbox: newMailboxResolve})}>
  46. {mailbox === 'resolved' ? t('Unresolve') : t('Resolve')}
  47. </Button>
  48. </ErrorBoundary>
  49. <ErrorBoundary mini>
  50. <Button
  51. onClick={() =>
  52. onToggleResovled({
  53. newMailbox: newMailboxSpam,
  54. moveToInbox: mailbox === 'ignored',
  55. })
  56. }
  57. >
  58. {mailbox === 'ignored' ? t('Move to inbox') : t('Mark as Spam')}
  59. </Button>
  60. </ErrorBoundary>
  61. <ErrorBoundary mini>
  62. <DropdownMenu
  63. position="bottom-end"
  64. triggerProps={{
  65. 'aria-label': t('Read Menu'),
  66. icon: <IconEllipsis />,
  67. showChevron: false,
  68. size: 'xs',
  69. }}
  70. items={[
  71. {
  72. key: 'mark read',
  73. label: t('Mark Read'),
  74. onAction: onMarkAsRead,
  75. },
  76. {
  77. key: 'mark unread',
  78. label: t('Mark Unread'),
  79. onAction: onMarkUnread,
  80. },
  81. ]}
  82. />
  83. </ErrorBoundary>
  84. </Flex>
  85. </Flex>
  86. );
  87. }