utils.tsx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import orderBy from 'lodash/orderBy';
  2. import {bulkUpdate} from 'sentry/actionCreators/group';
  3. import {Client} from 'sentry/api';
  4. import {t} from 'sentry/locale';
  5. import {Group, GroupActivity} from 'sentry/types';
  6. import {Event} from 'sentry/types/event';
  7. /**
  8. * Fetches group data and mark as seen
  9. *
  10. * @param orgId organization slug
  11. * @param groupId groupId
  12. * @param eventId eventId or "latest" or "oldest"
  13. * @param envNames
  14. * @param projectId project slug required for eventId that is not latest or oldest
  15. */
  16. export async function fetchGroupEvent(
  17. api: Client,
  18. groupId: string,
  19. eventId: string,
  20. envNames: string[]
  21. ): Promise<Event> {
  22. const url = `/issues/${groupId}/events/${eventId}/`;
  23. const query: {environment?: string[]} = {};
  24. if (envNames.length !== 0) {
  25. query.environment = envNames;
  26. }
  27. const data = await api.requestPromise(url, {query});
  28. return data;
  29. }
  30. export function markEventSeen(
  31. api: Client,
  32. orgId: string,
  33. projectId: string,
  34. groupId: string
  35. ) {
  36. bulkUpdate(
  37. api,
  38. {
  39. orgId,
  40. projectId,
  41. itemIds: [groupId],
  42. failSilently: true,
  43. data: {hasSeen: true},
  44. },
  45. {}
  46. );
  47. }
  48. export function fetchGroupUserReports(groupId: string, query: Record<string, string>) {
  49. const api = new Client();
  50. return api.requestPromise(`/issues/${groupId}/user-reports/`, {
  51. includeAllArgs: true,
  52. query,
  53. });
  54. }
  55. /**
  56. * Returns the environment name for an event or null
  57. *
  58. * @param event
  59. */
  60. export function getEventEnvironment(event: Event) {
  61. const tag = event.tags.find(({key}) => key === 'environment');
  62. return tag ? tag.value : null;
  63. }
  64. const SUBSCRIPTION_REASONS = {
  65. commented: t(
  66. "You're receiving workflow notifications because you have commented on this issue."
  67. ),
  68. assigned: t(
  69. "You're receiving workflow notifications because you were assigned to this issue."
  70. ),
  71. bookmarked: t(
  72. "You're receiving workflow notifications because you have bookmarked this issue."
  73. ),
  74. changed_status: t(
  75. "You're receiving workflow notifications because you have changed the status of this issue."
  76. ),
  77. mentioned: t(
  78. "You're receiving workflow notifications because you have been mentioned in this issue."
  79. ),
  80. };
  81. /**
  82. * @param group
  83. * @param removeLinks add/remove links to subscription reasons text (default: false)
  84. * @returns Reason for subscription
  85. */
  86. export function getSubscriptionReason(group: Group) {
  87. if (group.subscriptionDetails && group.subscriptionDetails.disabled) {
  88. return t('You have disabled workflow notifications for this project.');
  89. }
  90. if (!group.isSubscribed) {
  91. return t('Subscribe to workflow notifications for this issue');
  92. }
  93. if (group.subscriptionDetails) {
  94. const {reason} = group.subscriptionDetails;
  95. if (reason === 'unknown') {
  96. return t(
  97. "You're receiving workflow notifications because you are subscribed to this issue."
  98. );
  99. }
  100. if (reason && SUBSCRIPTION_REASONS.hasOwnProperty(reason)) {
  101. return SUBSCRIPTION_REASONS[reason];
  102. }
  103. }
  104. return t(
  105. "You're receiving updates because you are subscribed to workflow notifications for this project."
  106. );
  107. }
  108. export function getGroupMostRecentActivity(activities: GroupActivity[]) {
  109. // Most recent activity
  110. return orderBy([...activities], ({dateCreated}) => new Date(dateCreated), ['desc'])[0];
  111. }
  112. export enum ReprocessingStatus {
  113. REPROCESSED_AND_HASNT_EVENT = 'reprocessed_and_hasnt_event',
  114. REPROCESSED_AND_HAS_EVENT = 'reprocessed_and_has_event',
  115. REPROCESSING = 'reprocessing',
  116. NO_STATUS = 'no_status',
  117. }
  118. // Reprocessing Checks
  119. export function getGroupReprocessingStatus(
  120. group: Group,
  121. mostRecentActivity?: GroupActivity
  122. ) {
  123. const {status, count, activity: activities} = group;
  124. const groupCount = Number(count);
  125. switch (status) {
  126. case 'reprocessing':
  127. return ReprocessingStatus.REPROCESSING;
  128. case 'unresolved': {
  129. const groupMostRecentActivity =
  130. mostRecentActivity ?? getGroupMostRecentActivity(activities);
  131. if (groupMostRecentActivity?.type === 'reprocess') {
  132. if (groupCount === 0) {
  133. return ReprocessingStatus.REPROCESSED_AND_HASNT_EVENT;
  134. }
  135. return ReprocessingStatus.REPROCESSED_AND_HAS_EVENT;
  136. }
  137. return ReprocessingStatus.NO_STATUS;
  138. }
  139. default:
  140. return ReprocessingStatus.NO_STATUS;
  141. }
  142. }