fields2.tsx 5.8 KB

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