archive.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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, ResolutionStatus} from 'sentry/types';
  10. interface ArchiveActionProps {
  11. onUpdate: (params: GroupStatusResolution) => void;
  12. className?: string;
  13. confirmLabel?: string;
  14. confirmMessage?: () => React.ReactNode;
  15. disableTooltip?: boolean;
  16. disabled?: boolean;
  17. isArchived?: boolean;
  18. shouldConfirm?: boolean;
  19. size?: 'xs' | 'sm';
  20. }
  21. const ARCHIVE_UNTIL_ESCALATING: GroupStatusResolution = {
  22. status: ResolutionStatus.IGNORED,
  23. statusDetails: {},
  24. substatus: 'until_escalating',
  25. };
  26. const ARCHIVE_FOREVER: GroupStatusResolution = {
  27. status: ResolutionStatus.IGNORED,
  28. statusDetails: {},
  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. disableTooltip,
  78. className,
  79. shouldConfirm,
  80. confirmLabel,
  81. isArchived,
  82. confirmMessage,
  83. onUpdate,
  84. }: ArchiveActionProps) {
  85. if (isArchived) {
  86. return (
  87. <Button
  88. priority="primary"
  89. size="xs"
  90. title={t('Change status to unresolved')}
  91. onClick={() => onUpdate({status: ResolutionStatus.UNRESOLVED, statusDetails: {}})}
  92. aria-label={t('Unarchive')}
  93. />
  94. );
  95. }
  96. const {dropdownItems, onArchive} = getArchiveActions({
  97. confirmLabel,
  98. onUpdate,
  99. shouldConfirm,
  100. confirmMessage,
  101. });
  102. return (
  103. <ButtonBar className={className} merged>
  104. <ArchiveButton
  105. size={size}
  106. tooltipProps={{delay: 1000, disabled: disabled || disableTooltip}}
  107. title={t('Hides the issue until the sh*t hits the fan and events escalate.')}
  108. onClick={() => onArchive(ARCHIVE_UNTIL_ESCALATING)}
  109. disabled={disabled}
  110. >
  111. {t('Archive')}
  112. </ArchiveButton>
  113. <DropdownMenu
  114. size="sm"
  115. trigger={triggerProps => (
  116. <DropdownTrigger
  117. {...triggerProps}
  118. aria-label={t('Archive options')}
  119. size={size}
  120. icon={<IconChevron direction="down" size="xs" />}
  121. disabled={disabled}
  122. />
  123. )}
  124. menuTitle={t('Archive')}
  125. items={dropdownItems}
  126. isDisabled={disabled}
  127. />
  128. </ButtonBar>
  129. );
  130. }
  131. export default ArchiveActions;
  132. const ArchiveButton = styled(Button)`
  133. box-shadow: none;
  134. border-radius: ${p => p.theme.borderRadiusLeft};
  135. `;
  136. const DropdownTrigger = styled(Button)`
  137. box-shadow: none;
  138. border-radius: ${p => p.theme.borderRadiusRight};
  139. border-left: none;
  140. `;