utils.tsx 4.4 KB

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