navigationConfiguration.tsx 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. import FeatureBadge from 'sentry/components/badge/featureBadge';
  2. import {t} from 'sentry/locale';
  3. import ConfigStore from 'sentry/stores/configStore';
  4. import type {Organization} from 'sentry/types/organization';
  5. import type {Project} from 'sentry/types/project';
  6. import {hasCustomMetrics} from 'sentry/utils/metrics/features';
  7. import type {NavigationSection} from 'sentry/views/settings/types';
  8. type ConfigParams = {
  9. debugFilesNeedsReview?: boolean;
  10. organization?: Organization;
  11. project?: Project;
  12. };
  13. const pathPrefix = '/settings/:orgId/projects/:projectId';
  14. export default function getConfiguration({
  15. project,
  16. organization,
  17. debugFilesNeedsReview,
  18. }: ConfigParams): NavigationSection[] {
  19. const plugins = (project?.plugins || []).filter(plugin => plugin.enabled);
  20. const isSelfHostedErrorsOnly = ConfigStore.get('isSelfHostedErrorsOnly');
  21. return [
  22. {
  23. name: t('Project'),
  24. items: [
  25. {
  26. path: `${pathPrefix}/`,
  27. index: true,
  28. title: t('General Settings'),
  29. description: t('Configure general settings for a project'),
  30. },
  31. {
  32. path: `${pathPrefix}/teams/`,
  33. title: t('Project Teams'),
  34. description: t('Manage team access for a project'),
  35. },
  36. {
  37. path: `${pathPrefix}/alerts/`,
  38. title: t('Alert Settings'),
  39. description: t('Project alert settings'),
  40. },
  41. {
  42. path: `${pathPrefix}/tags/`,
  43. title: t('Tags & Context'),
  44. description: t("View and manage a project's tags and context"),
  45. },
  46. {
  47. path: `${pathPrefix}/environments/`,
  48. title: t('Environments'),
  49. description: t('Manage environments in a project'),
  50. },
  51. {
  52. path: `${pathPrefix}/ownership/`,
  53. title: t('Ownership Rules'),
  54. description: t('Manage ownership rules for a project'),
  55. },
  56. {
  57. path: `${pathPrefix}/data-forwarding/`,
  58. title: t('Data Forwarding'),
  59. },
  60. {
  61. path: `${pathPrefix}/user-feedback/`,
  62. title: t('User Feedback'),
  63. show: () => !isSelfHostedErrorsOnly,
  64. },
  65. ],
  66. },
  67. {
  68. name: t('Processing'),
  69. items: [
  70. {
  71. path: `${pathPrefix}/filters/`,
  72. title: t('Inbound Filters'),
  73. description: t(
  74. "Configure a project's inbound filters (e.g. browsers, messages)"
  75. ),
  76. },
  77. {
  78. path: `${pathPrefix}/security-and-privacy/`,
  79. title: t('Security & Privacy'),
  80. description: t(
  81. 'Configuration related to dealing with sensitive data and other security settings. (Data Scrubbing, Data Privacy, Data Scrubbing) for a project'
  82. ),
  83. },
  84. {
  85. path: `${pathPrefix}/issue-grouping/`,
  86. title: t('Issue Grouping'),
  87. },
  88. {
  89. path: `${pathPrefix}/processing-issues/`,
  90. title: t('Processing Issues'),
  91. show: () => {
  92. // NOTE: both `project` and `options` are non-null here.
  93. return 'sentry:reprocessing_active' in (project?.options ?? {});
  94. },
  95. // eslint-disable-next-line @typescript-eslint/no-shadow
  96. badge: ({project}) => {
  97. const issues = project?.processingIssues ?? 0;
  98. return issues <= 0 ? null : issues > 99 ? '99+' : issues;
  99. },
  100. },
  101. {
  102. path: `${pathPrefix}/debug-symbols/`,
  103. title: t('Debug Files'),
  104. badge: debugFilesNeedsReview ? () => 'warning' : undefined,
  105. },
  106. {
  107. path: `${pathPrefix}/proguard/`,
  108. title: t('ProGuard'),
  109. },
  110. {
  111. path: `${pathPrefix}/source-maps/`,
  112. title: t('Source Maps'),
  113. },
  114. {
  115. path: `${pathPrefix}/performance/`,
  116. title: t('Performance'),
  117. show: () =>
  118. !!organization?.features?.includes('performance-view') &&
  119. !isSelfHostedErrorsOnly,
  120. },
  121. {
  122. path: `${pathPrefix}/metrics/`,
  123. title: t('Metrics'),
  124. show: () =>
  125. !!(organization && hasCustomMetrics(organization)) && !isSelfHostedErrorsOnly,
  126. },
  127. {
  128. path: `${pathPrefix}/replays/`,
  129. title: t('Replays'),
  130. show: () =>
  131. !!organization?.features?.includes('session-replay-ui') &&
  132. !isSelfHostedErrorsOnly,
  133. },
  134. ],
  135. },
  136. {
  137. name: t('SDK Setup'),
  138. items: [
  139. {
  140. path: `${pathPrefix}/keys/`,
  141. title: t('Client Keys (DSN)'),
  142. description: t("View and manage the project's client keys (DSN)"),
  143. },
  144. {
  145. path: `${pathPrefix}/loader-script/`,
  146. title: t('Loader Script'),
  147. description: t("View and manage the project's Loader Script"),
  148. },
  149. {
  150. path: `${pathPrefix}/remote-config/`,
  151. badge: () => <FeatureBadge type="experimental" />,
  152. title: t('Remote Config'),
  153. description: t("View and manage the project's Remote Configuration"),
  154. show: organization?.features.includes('remote-config'),
  155. },
  156. {
  157. path: `${pathPrefix}/release-tracking/`,
  158. title: t('Releases'),
  159. },
  160. {
  161. path: `${pathPrefix}/security-headers/`,
  162. title: t('Security Headers'),
  163. },
  164. ],
  165. },
  166. {
  167. name: t('Legacy Integrations'),
  168. items: [
  169. {
  170. path: `${pathPrefix}/plugins/`,
  171. title: t('Legacy Integrations'),
  172. description: t('View, enable, and disable all integrations for a project'),
  173. id: 'legacy_integrations',
  174. recordAnalytics: true,
  175. },
  176. ...plugins.map(plugin => ({
  177. path: `${pathPrefix}/plugins/${plugin.id}/`,
  178. title: plugin.name,
  179. show: opts => opts?.access?.has('project:write') && !plugin.isDeprecated,
  180. id: 'plugin_details',
  181. recordAnalytics: true,
  182. })),
  183. ],
  184. },
  185. ];
  186. }