breadcrumb.tsx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import {useMemo} from 'react';
  2. import styled from '@emotion/styled';
  3. import {Location} from 'history';
  4. import Breadcrumbs, {Crumb} from 'sentry/components/breadcrumbs';
  5. import {t} from 'sentry/locale';
  6. import {Organization, Project} from 'sentry/types';
  7. import {
  8. generateProfileDetailsRouteWithQuery,
  9. generateProfileFlamechartRouteWithQuery,
  10. generateProfileSummaryRouteWithQuery,
  11. generateProfilingRouteWithQuery,
  12. } from 'sentry/utils/profiling/routes';
  13. interface BreadcrumbProps {
  14. location: Location;
  15. organization: Organization;
  16. trails: Trail[];
  17. }
  18. function Breadcrumb({location, organization, trails}: BreadcrumbProps) {
  19. const crumbs = useMemo(
  20. () => trails.map(trail => trailToCrumb(trail, {location, organization})),
  21. [location, organization, trails]
  22. );
  23. return <StyledBreadcrumbs crumbs={crumbs} />;
  24. }
  25. function trailToCrumb(
  26. trail: Trail,
  27. {
  28. location,
  29. organization,
  30. }: {
  31. location: Location;
  32. organization: Organization;
  33. }
  34. ): Crumb {
  35. switch (trail.type) {
  36. case 'landing': {
  37. return {
  38. to: generateProfilingRouteWithQuery({
  39. location,
  40. orgSlug: organization.slug,
  41. }),
  42. label: t('Profiling'),
  43. preservePageFilters: true,
  44. };
  45. }
  46. case 'profile summary': {
  47. return {
  48. to: generateProfileSummaryRouteWithQuery({
  49. location,
  50. orgSlug: organization.slug,
  51. projectSlug: trail.payload.projectSlug,
  52. transaction: trail.payload.transaction,
  53. }),
  54. label: t('Profile Summary'),
  55. preservePageFilters: true,
  56. };
  57. }
  58. case 'flamechart': {
  59. const generateRouteWithQuery =
  60. trail.payload.tab === 'flamechart'
  61. ? generateProfileFlamechartRouteWithQuery
  62. : generateProfileDetailsRouteWithQuery;
  63. return {
  64. to: generateRouteWithQuery({
  65. location,
  66. orgSlug: organization.slug,
  67. projectSlug: trail.payload.projectSlug,
  68. profileId: trail.payload.profileId,
  69. }),
  70. label: trail.payload.transaction,
  71. preservePageFilters: true,
  72. };
  73. }
  74. default:
  75. throw new Error(`Unknown breadcrumb type: ${JSON.stringify(trail)}`);
  76. }
  77. }
  78. type ProfilingTrail = {
  79. type: 'landing';
  80. };
  81. type ProfileSummaryTrail = {
  82. payload: {
  83. projectSlug: Project['slug'];
  84. transaction: string;
  85. };
  86. type: 'profile summary';
  87. };
  88. type FlamegraphTrail = {
  89. payload: {
  90. profileId: string;
  91. projectSlug: string;
  92. tab: 'flamechart' | 'details';
  93. transaction: string;
  94. };
  95. type: 'flamechart';
  96. };
  97. type Trail = ProfilingTrail | ProfileSummaryTrail | FlamegraphTrail;
  98. const StyledBreadcrumbs = styled(Breadcrumbs)`
  99. padding: 0;
  100. `;
  101. export {Breadcrumb};