archive.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import styled from '@emotion/styled';
  2. import {getIgnoreActions} from 'sentry/components/actions/ignore';
  3. import {Button} from 'sentry/components/button';
  4. import ButtonBar from 'sentry/components/buttonBar';
  5. import {openConfirmModal} from 'sentry/components/confirm';
  6. import {DropdownMenu} from 'sentry/components/dropdownMenu';
  7. import {IconChevron} from 'sentry/icons';
  8. import {t} from 'sentry/locale';
  9. import {GroupStatusResolution, GroupSubstatus, ResolutionStatus} from 'sentry/types';
  10. interface ArchiveActionProps {
  11. onUpdate: (params: GroupStatusResolution) => void;
  12. className?: string;
  13. confirmLabel?: string;
  14. confirmMessage?: () => React.ReactNode;
  15. disabled?: boolean;
  16. isArchived?: boolean;
  17. shouldConfirm?: boolean;
  18. size?: 'xs' | 'sm';
  19. }
  20. const ARCHIVE_UNTIL_ESCALATING: GroupStatusResolution = {
  21. status: ResolutionStatus.IGNORED,
  22. statusDetails: {},
  23. substatus: GroupSubstatus.ARCHIVED_UNTIL_ESCALATING,
  24. };
  25. const ARCHIVE_FOREVER: GroupStatusResolution = {
  26. status: ResolutionStatus.IGNORED,
  27. statusDetails: {},
  28. substatus: GroupSubstatus.ARCHIVED_FOREVER,
  29. };
  30. export function getArchiveActions({
  31. shouldConfirm,
  32. confirmLabel,
  33. confirmMessage,
  34. onUpdate,
  35. }: Pick<
  36. ArchiveActionProps,
  37. 'shouldConfirm' | 'confirmMessage' | 'onUpdate' | 'confirmLabel'
  38. >) {
  39. // TODO(workflow): Replace ignore actions with more archive actions
  40. const {dropdownItems} = getIgnoreActions({
  41. confirmLabel,
  42. onUpdate,
  43. shouldConfirm,
  44. confirmMessage,
  45. });
  46. const onArchive = (resolution: GroupStatusResolution) => {
  47. if (shouldConfirm && confirmMessage) {
  48. openConfirmModal({
  49. onConfirm: () => onUpdate(resolution),
  50. message: confirmMessage(),
  51. confirmText: confirmLabel,
  52. });
  53. } else {
  54. onUpdate(resolution);
  55. }
  56. };
  57. return {
  58. onArchive,
  59. dropdownItems: [
  60. {
  61. key: 'untilEscalating',
  62. label: t('Until it escalates'),
  63. onAction: () => onArchive(ARCHIVE_UNTIL_ESCALATING),
  64. },
  65. {
  66. key: 'forever',
  67. label: t('Forever'),
  68. onAction: () => onArchive(ARCHIVE_FOREVER),
  69. },
  70. ...dropdownItems,
  71. ],
  72. };
  73. }
  74. function ArchiveActions({
  75. size = 'xs',
  76. disabled,
  77. className,
  78. shouldConfirm,
  79. confirmLabel,
  80. isArchived,
  81. confirmMessage,
  82. onUpdate,
  83. }: ArchiveActionProps) {
  84. if (isArchived) {
  85. return (
  86. <Button
  87. priority="primary"
  88. size="xs"
  89. title={t('Change status to unresolved')}
  90. onClick={() => onUpdate({status: ResolutionStatus.UNRESOLVED, statusDetails: {}})}
  91. aria-label={t('Unarchive')}
  92. />
  93. );
  94. }
  95. const {dropdownItems, onArchive} = getArchiveActions({
  96. confirmLabel,
  97. onUpdate,
  98. shouldConfirm,
  99. confirmMessage,
  100. });
  101. return (
  102. <ButtonBar className={className} merged>
  103. <ArchiveButton
  104. size={size}
  105. tooltipProps={{delay: 1000, disabled}}
  106. title={t('Hides the issue until the sh*t hits the fan and events escalate.')}
  107. onClick={() => onArchive(ARCHIVE_UNTIL_ESCALATING)}
  108. disabled={disabled}
  109. >
  110. {t('Archive')}
  111. </ArchiveButton>
  112. <DropdownMenu
  113. size="sm"
  114. trigger={triggerProps => (
  115. <DropdownTrigger
  116. {...triggerProps}
  117. aria-label={t('Archive options')}
  118. size={size}
  119. icon={<IconChevron direction="down" size="xs" />}
  120. disabled={disabled}
  121. />
  122. )}
  123. menuTitle={t('Archive')}
  124. items={dropdownItems}
  125. isDisabled={disabled}
  126. />
  127. </ButtonBar>
  128. );
  129. }
  130. export default ArchiveActions;
  131. const ArchiveButton = styled(Button)`
  132. box-shadow: none;
  133. border-radius: ${p => p.theme.borderRadiusLeft};
  134. `;
  135. const DropdownTrigger = styled(Button)`
  136. box-shadow: none;
  137. border-radius: ${p => p.theme.borderRadiusRight};
  138. border-left: none;
  139. `;