navigationConfiguration.tsx 5.5 KB

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