builderBreadCrumbs.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import {browserHistory} from 'react-router';
  2. import styled from '@emotion/styled';
  3. import type {Location} from 'history';
  4. import Breadcrumbs, {Crumb, CrumbDropdown} from 'sentry/components/breadcrumbs';
  5. import IdBadge from 'sentry/components/idBadge';
  6. import {t} from 'sentry/locale';
  7. import space from 'sentry/styles/space';
  8. import {Organization} from 'sentry/types';
  9. import {isActiveSuperuser} from 'sentry/utils/isActiveSuperuser';
  10. import recreateRoute from 'sentry/utils/recreateRoute';
  11. import useProjects from 'sentry/utils/useProjects';
  12. import MenuItem from 'sentry/views/settings/components/settingsBreadcrumb/menuItem';
  13. import type {RouteWithName} from 'sentry/views/settings/components/settingsBreadcrumb/types';
  14. interface Props {
  15. location: Location;
  16. organization: Organization;
  17. projectSlug: string;
  18. routes: RouteWithName[];
  19. title: string;
  20. alertName?: string;
  21. alertType?: string;
  22. canChangeProject?: boolean;
  23. }
  24. function BuilderBreadCrumbs({
  25. title,
  26. alertName,
  27. projectSlug,
  28. routes,
  29. canChangeProject,
  30. location,
  31. organization,
  32. alertType,
  33. }: Props) {
  34. const {projects} = useProjects();
  35. const isSuperuser = isActiveSuperuser();
  36. const project = projects.find(({slug}) => projectSlug === slug);
  37. const hasAlertWizardV3 = organization.features.includes('alert-wizard-v3');
  38. const label = (
  39. <IdBadge project={project ?? {slug: projectSlug}} avatarSize={18} disableLink />
  40. );
  41. const projectCrumbLink: Crumb = {
  42. to: `/organizations/${organization.slug}/alerts/rules/?project=${project?.id}`,
  43. label,
  44. };
  45. function getProjectDropdownCrumb(): CrumbDropdown {
  46. return {
  47. onSelect: ({value: projectId}) => {
  48. // TODO(taylangocmen): recreating route doesn't update query, don't edit recreateRoute will add project selector for alert-wizard-v3
  49. browserHistory.push(
  50. recreateRoute('', {
  51. routes,
  52. params: hasAlertWizardV3
  53. ? {orgId: organization.slug, alertType}
  54. : {orgId: organization.slug, projectId},
  55. location,
  56. })
  57. );
  58. },
  59. label,
  60. items: projects
  61. .filter(proj => proj.isMember || isSuperuser)
  62. .map((proj, index) => ({
  63. index,
  64. value: proj.slug,
  65. label: (
  66. <MenuItem>
  67. <IdBadge
  68. project={proj}
  69. avatarProps={{consistentWidth: true}}
  70. avatarSize={18}
  71. disableLink
  72. />
  73. </MenuItem>
  74. ),
  75. searchKey: proj.slug,
  76. })),
  77. };
  78. }
  79. const projectCrumb = canChangeProject ? getProjectDropdownCrumb() : projectCrumbLink;
  80. const crumbs: (Crumb | CrumbDropdown)[] = [
  81. {
  82. to: `/organizations/${organization.slug}/alerts/rules/`,
  83. label: t('Alerts'),
  84. preservePageFilters: true,
  85. },
  86. ...(hasAlertWizardV3 ? [] : [projectCrumb]),
  87. {
  88. label: title,
  89. ...(alertName
  90. ? {
  91. to: `/organizations/${organization.slug}/alerts/${projectSlug}/wizard`,
  92. preservePageFilters: true,
  93. }
  94. : {}),
  95. },
  96. ];
  97. if (alertName) {
  98. crumbs.push({label: alertName});
  99. }
  100. return <StyledBreadcrumbs crumbs={crumbs} />;
  101. }
  102. const StyledBreadcrumbs = styled(Breadcrumbs)`
  103. font-size: 18px;
  104. margin-bottom: ${space(3)};
  105. `;
  106. export default BuilderBreadCrumbs;