navigationConfiguration.tsx 5.6 KB

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