mergedToolbar.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import styled from '@emotion/styled';
  2. import {openDiffModal} from 'sentry/actionCreators/modal';
  3. import {Button} from 'sentry/components/button';
  4. import Confirm from 'sentry/components/confirm';
  5. import {PanelHeader} from 'sentry/components/panels';
  6. import {t, tct} from 'sentry/locale';
  7. import GroupingStore from 'sentry/stores/groupingStore';
  8. import {useLegacyStore} from 'sentry/stores/useLegacyStore';
  9. import {space} from 'sentry/styles/space';
  10. import {Group, Organization, Project} from 'sentry/types';
  11. type Props = {
  12. groupId: Group['id'];
  13. onToggleCollapse: () => void;
  14. onUnmerge: () => void;
  15. orgId: Organization['slug'];
  16. project: Project;
  17. };
  18. export function MergedToolbar({
  19. groupId,
  20. project,
  21. orgId,
  22. onUnmerge,
  23. onToggleCollapse,
  24. }: Props) {
  25. const {
  26. unmergeList,
  27. mergedItems,
  28. unmergeLastCollapsed,
  29. unmergeDisabled,
  30. enableFingerprintCompare,
  31. } = useLegacyStore(GroupingStore);
  32. const unmergeCount = unmergeList?.size ?? 0;
  33. function handleShowDiff(event: React.MouseEvent) {
  34. event.stopPropagation();
  35. const entries = unmergeList.entries();
  36. // `unmergeList` should only have 2 items in map
  37. if (unmergeList.size !== 2) {
  38. return;
  39. }
  40. // only need eventId, not fingerprint
  41. const [baseEventId, targetEventId] = Array.from(entries).map(
  42. ([, eventId]) => eventId
  43. );
  44. openDiffModal({
  45. targetIssueId: groupId,
  46. project,
  47. baseIssueId: groupId,
  48. orgId,
  49. baseEventId,
  50. targetEventId,
  51. });
  52. }
  53. const unmergeDisabledReason =
  54. mergedItems.length <= 1
  55. ? t('To unmerge, the list must contain 2 or more items')
  56. : unmergeList.size === 0
  57. ? t('To unmerge, 1 or more items must be selected')
  58. : GroupingStore.isAllUnmergedSelected()
  59. ? t('We are unable to unmerge all items at once')
  60. : undefined;
  61. return (
  62. <PanelHeader hasButtons>
  63. <div>
  64. <Confirm
  65. disabled={unmergeDisabled}
  66. onConfirm={onUnmerge}
  67. message={t(
  68. 'These events will be unmerged and grouped into a new issue. Are you sure you want to unmerge these events?'
  69. )}
  70. >
  71. <Button size="sm" title={unmergeDisabledReason}>
  72. {mergedItems.length <= 1
  73. ? t('Unmerge')
  74. : tct('Unmerge ([itemsSelectedQuantity])', {
  75. itemsSelectedQuantity: unmergeCount,
  76. })}
  77. </Button>
  78. </Confirm>
  79. <CompareButton
  80. size="sm"
  81. disabled={!enableFingerprintCompare}
  82. onClick={handleShowDiff}
  83. title={
  84. !enableFingerprintCompare
  85. ? t('To compare, exactly 2 items must be selected')
  86. : undefined
  87. }
  88. >
  89. {t('Compare')}
  90. </CompareButton>
  91. </div>
  92. <Button size="sm" onClick={onToggleCollapse}>
  93. {unmergeLastCollapsed ? t('Expand All') : t('Collapse All')}
  94. </Button>
  95. </PanelHeader>
  96. );
  97. }
  98. const CompareButton = styled(Button)`
  99. margin-left: ${space(1)};
  100. `;