organizationGeneralSettings.tsx 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. import type {JsonFormObject} from 'sentry/components/forms/types';
  2. import ExternalLink from 'sentry/components/links/externalLink';
  3. import {t, tct} from 'sentry/locale';
  4. import ConfigStore from 'sentry/stores/configStore';
  5. import type {BaseRole} from 'sentry/types/organization';
  6. import slugify from 'sentry/utils/slugify';
  7. // Export route to make these forms searchable by label/help
  8. export const route = '/settings/:orgId/';
  9. const formGroups: JsonFormObject[] = [
  10. {
  11. // Form "section"/"panel"
  12. title: t('General'),
  13. fields: [
  14. {
  15. name: 'slug',
  16. type: 'string',
  17. required: true,
  18. label: t('Organization Slug'),
  19. help: t('A unique ID used to identify this organization'),
  20. transformInput: slugify,
  21. saveOnBlur: false,
  22. saveMessageAlertType: 'info',
  23. saveMessage: t(
  24. 'You will be redirected to the new organization slug after saving'
  25. ),
  26. },
  27. {
  28. name: 'name',
  29. type: 'string',
  30. required: true,
  31. label: t('Display Name'),
  32. help: t('A human-friendly name for the organization'),
  33. },
  34. {
  35. name: 'isEarlyAdopter',
  36. type: 'boolean',
  37. label: t('Early Adopter'),
  38. help: tct("Opt-in to [link:new features] before they're released to the public", {
  39. link: (
  40. <ExternalLink href="https://docs.sentry.io/product/accounts/early-adopter/" />
  41. ),
  42. }),
  43. visible: () => !ConfigStore.get('isSelfHostedErrorsOnly'),
  44. },
  45. {
  46. name: 'aiSuggestedSolution',
  47. type: 'boolean',
  48. label: t('AI Suggested Solution'),
  49. help: tct(
  50. 'Opt-in to [link:ai suggested solution] to get AI help on how to solve an issue.',
  51. {
  52. link: (
  53. <ExternalLink href="https://docs.sentry.io/product/issues/issue-details/ai-suggested-solution/" />
  54. ),
  55. }
  56. ),
  57. visible: () => !ConfigStore.get('isSelfHostedErrorsOnly'),
  58. },
  59. {
  60. name: 'uptimeAutodetection',
  61. type: 'boolean',
  62. label: t('Automatically Configure Uptime Alerts'),
  63. help: t('Detect most-used URLs for uptime monitoring.'),
  64. // TOOD(epurkhiser): Currently there's no need for users to change this
  65. // setting as it will just be confusing. In the future when
  66. // autodetection is used for suggested URLs it will make more sense to
  67. // for users to have the option to disable this.
  68. visible: false,
  69. },
  70. ],
  71. },
  72. {
  73. title: 'Membership',
  74. fields: [
  75. {
  76. name: 'defaultRole',
  77. type: 'select',
  78. label: t('Default Role'),
  79. // seems weird to have choices in initial form data
  80. choices: ({initialData} = {}) =>
  81. initialData?.orgRoleList?.map((r: BaseRole) => [r.id, r.name]) ?? [],
  82. help: t('The default role new members will receive'),
  83. disabled: ({access}) => !access.has('org:admin'),
  84. },
  85. {
  86. name: 'openMembership',
  87. type: 'boolean',
  88. label: t('Open Team Membership'),
  89. help: t('Allow organization members to freely join any team'),
  90. },
  91. {
  92. name: 'allowMemberInvite',
  93. type: 'boolean',
  94. label: t('Let Members Invite Freely'),
  95. help: t(
  96. 'Allow organization members to invite other members via email without needing org owner or manager approval.'
  97. ),
  98. visible: ({features}) => features.has('members-invite-teammates'),
  99. disabled: ({features, access}) =>
  100. !access.has('org:write') || !features.has('team-roles'),
  101. disabledReason: ({features}) =>
  102. !features.has('team-roles')
  103. ? t('You must be on a business plan to toggle this feature.')
  104. : undefined,
  105. },
  106. {
  107. name: 'allowMemberProjectCreation',
  108. type: 'boolean',
  109. label: t('Let Members Create Projects'),
  110. help: t('Allow organization members to create and configure new projects.'),
  111. disabled: ({features, access}) =>
  112. !access.has('org:write') || !features.has('team-roles'),
  113. disabledReason: ({features}) =>
  114. !features.has('team-roles')
  115. ? t('You must be on a business plan to toggle this feature.')
  116. : undefined,
  117. },
  118. {
  119. name: 'eventsMemberAdmin',
  120. type: 'boolean',
  121. label: t('Let Members Delete Events'),
  122. help: t(
  123. 'Allow members to delete events (including the delete & discard action) by granting them the `event:admin` scope.'
  124. ),
  125. },
  126. {
  127. name: 'alertsMemberWrite',
  128. type: 'boolean',
  129. label: t('Let Members Create and Edit Alerts'),
  130. help: t(
  131. 'Allow members to create, edit, and delete alert rules by granting them the `alerts:write` scope.'
  132. ),
  133. },
  134. {
  135. name: 'attachmentsRole',
  136. type: 'select',
  137. choices: ({initialData = {}}) =>
  138. initialData?.orgRoleList?.map((r: BaseRole) => [r.id, r.name]) ?? [],
  139. label: t('Attachments Access'),
  140. help: t(
  141. 'Role required to download event attachments, such as native crash reports or log files.'
  142. ),
  143. visible: ({features}) => features.has('event-attachments'),
  144. },
  145. {
  146. name: 'debugFilesRole',
  147. type: 'select',
  148. choices: ({initialData = {}}) =>
  149. initialData?.orgRoleList?.map((r: BaseRole) => [r.id, r.name]) ?? [],
  150. label: t('Debug Files Access'),
  151. help: t(
  152. 'Role required to download debug information files, proguard mappings and source maps.'
  153. ),
  154. },
  155. ],
  156. },
  157. ];
  158. export default formGroups;