fields2.tsx 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. import {Fragment} from 'react';
  2. import type {Field} from 'sentry/components/forms/types';
  3. import ExternalLink from 'sentry/components/links/externalLink';
  4. import QuestionTooltip from 'sentry/components/questionTooltip';
  5. import {t, tct} from 'sentry/locale';
  6. import {getDocsLinkForEventType} from 'sentry/views/settings/account/notifications/utils';
  7. export const NOTIFICATION_SETTING_FIELDS: Record<string, Field> = {
  8. alerts: {
  9. name: 'alerts',
  10. type: 'select',
  11. label: t('Issue Alerts'),
  12. choices: [
  13. ['always', t('On')],
  14. ['never', t('Off')],
  15. ],
  16. help: t('Notifications sent from Alert rules that your team has set up.'),
  17. },
  18. workflow: {
  19. name: 'workflow',
  20. type: 'select',
  21. label: t('Issue Workflow'),
  22. choices: [
  23. ['always', t('On')],
  24. ['subscribe_only', t('Only Subscribed Issues')],
  25. ['never', t('Off')],
  26. ],
  27. help: t('Changes in issue assignment, resolution status, and comments.'),
  28. },
  29. deploy: {
  30. name: 'deploy',
  31. type: 'select',
  32. label: t('Deploys'),
  33. choices: [
  34. ['always', t('On')],
  35. ['committed_only', t('Releases with My Commits')],
  36. ['never', t('Off')],
  37. ],
  38. help: t('Release, environment, and commit overviews.'),
  39. },
  40. provider: {
  41. name: 'provider',
  42. type: 'select',
  43. label: t('Delivery Method'),
  44. choices: [
  45. ['email', t('Email')],
  46. ['slack', t('Slack')],
  47. ['msteams', t('Microsoft Teams')],
  48. ],
  49. help: t('Where personal notifications will be sent.'),
  50. multiple: true,
  51. onChange: val => {
  52. // This is a little hack to prevent this field from being empty.
  53. // TODO(nisanthan): need to prevent showing the clearable on. the multi-select when its only 1 value.
  54. if (!val || val.length === 0) {
  55. throw Error('Invalid selection. Field cannot be empty.');
  56. }
  57. },
  58. },
  59. approval: {
  60. name: 'approval',
  61. type: 'select',
  62. label: t('Nudges'),
  63. choices: [
  64. ['always', t('On')],
  65. ['never', t('Off')],
  66. ],
  67. help: t('Notifications that require review or approval.'),
  68. },
  69. quota: {
  70. name: 'quota',
  71. type: 'select',
  72. label: t('Quota'),
  73. choices: [
  74. ['always', t('On')],
  75. ['never', t('Off')],
  76. ],
  77. help: t('Error, transaction, replay, attachment, and cron monitor quota limits.'),
  78. },
  79. reports: {
  80. name: 'reports',
  81. type: 'select',
  82. label: t('Weekly Reports'),
  83. help: t('A summary of the past week for an organization.'),
  84. choices: [
  85. ['always', t('On')],
  86. ['never', t('Off')],
  87. ],
  88. },
  89. email: {
  90. name: 'email routing',
  91. type: 'blank',
  92. label: t('Email Routing'),
  93. help: t('Change the email address that receives notifications.'),
  94. },
  95. spikeProtection: {
  96. name: 'spikeProtection',
  97. type: 'select',
  98. label: t('Spike Protection'),
  99. choices: [
  100. ['always', t('On')],
  101. ['never', t('Off')],
  102. ],
  103. help: t('Notifications about spikes on a per project basis.'),
  104. },
  105. // legacy options
  106. personalActivityNotifications: {
  107. name: 'personalActivityNotifications',
  108. type: 'select',
  109. label: t('My Own Activity'),
  110. choices: [
  111. [true as any, t('On')],
  112. [false as any, t('Off')],
  113. ],
  114. help: t('Notifications about your own actions on Sentry.'),
  115. },
  116. selfAssignOnResolve: {
  117. name: 'selfAssignOnResolve',
  118. type: 'select',
  119. label: t('Resolve and Auto-Assign'),
  120. choices: [
  121. [true as any, t('On')],
  122. [false as any, t('Off')],
  123. ],
  124. help: t("When you resolve an unassigned issue, we'll auto-assign it to you."),
  125. },
  126. };
  127. // TODO(isabella): Once spend vis notifs are GA, remove this
  128. // partial field definition for quota sub-categories
  129. export const QUOTA_FIELDS = [
  130. {
  131. name: 'quotaWarnings',
  132. label: t('Set Quota Limit'),
  133. help: t('Receive notifications when your organization exceeds the following limits.'),
  134. choices: [
  135. ['always', t('100% and 80%')],
  136. ['never', t('100%')],
  137. ] as const,
  138. },
  139. {
  140. name: 'quotaErrors',
  141. label: t('Errors'),
  142. help: tct('Receive notifications about your error quotas. [learnMore:Learn more]', {
  143. learnMore: <ExternalLink href={getDocsLinkForEventType('error')} />,
  144. }),
  145. choices: [
  146. ['always', t('On')],
  147. ['never', t('Off')],
  148. ] as const,
  149. },
  150. {
  151. name: 'quotaTransactions',
  152. label: t('Transactions'),
  153. help: tct(
  154. 'Receive notifications about your transaction quota. [learnMore:Learn more]',
  155. {
  156. learnMore: <ExternalLink href={getDocsLinkForEventType('transaction')} />,
  157. }
  158. ),
  159. choices: [
  160. ['always', t('On')],
  161. ['never', t('Off')],
  162. ] as const,
  163. },
  164. {
  165. name: 'quotaReplays',
  166. label: t('Replays'),
  167. help: tct('Receive notifications about your replay quotas. [learnMore:Learn more]', {
  168. learnMore: <ExternalLink href={getDocsLinkForEventType('replay')} />,
  169. }),
  170. choices: [
  171. ['always', t('On')],
  172. ['never', t('Off')],
  173. ] as const,
  174. },
  175. {
  176. name: 'quotaAttachments',
  177. label: t('Attachments'),
  178. help: tct(
  179. 'Receive notifications about your attachment quota. [learnMore:Learn more]',
  180. {
  181. learnMore: <ExternalLink href={getDocsLinkForEventType('attachment')} />,
  182. }
  183. ),
  184. choices: [
  185. ['always', t('On')],
  186. ['never', t('Off')],
  187. ] as const,
  188. },
  189. {
  190. name: 'quotaMonitorSeats',
  191. label: t('Cron Monitors'),
  192. help: tct(
  193. 'Receive notifications about your cron monitor quotas. [learnMore:Learn more]',
  194. {
  195. learnMore: <ExternalLink href={getDocsLinkForEventType('monitorSeat')} />,
  196. }
  197. ),
  198. choices: [
  199. ['always', t('On')],
  200. ['never', t('Off')],
  201. ] as const,
  202. },
  203. {
  204. name: 'quotaSpendAllocations',
  205. label: (
  206. <Fragment>
  207. {t('Spend Allocations')}{' '}
  208. <QuestionTooltip position="top" title="Business plan only" size="xs" />
  209. </Fragment>
  210. ),
  211. help: t('Receive notifications about your spend allocations.'),
  212. choices: [
  213. ['always', t('On')],
  214. ['never', t('Off')],
  215. ] as const,
  216. },
  217. ];
  218. export const SPEND_FIELDS = [
  219. {
  220. name: 'quotaWarnings',
  221. label: t('Spend Notifications'),
  222. help: tct(
  223. 'Receive notifications when your spend crosses predefined or custom thresholds. [learnMore:Learn more]',
  224. {
  225. learnMore: (
  226. <ExternalLink
  227. href={
  228. 'https://docs.sentry.io/product/alerts/notifications/#spend-notifications'
  229. }
  230. />
  231. ),
  232. }
  233. ),
  234. choices: [
  235. ['always', t('On')],
  236. ['never', t('Off')],
  237. ] as const,
  238. },
  239. ...QUOTA_FIELDS.slice(1),
  240. ];