index.tsx 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import {Link as RouterLink} from 'react-router';
  2. import styled from '@emotion/styled';
  3. import {t} from 'sentry/locale';
  4. import getRouteStringFromRoutes from 'sentry/utils/getRouteStringFromRoutes';
  5. import recreateRoute from 'sentry/utils/recreateRoute';
  6. import Crumb from 'sentry/views/settings/components/settingsBreadcrumb/crumb';
  7. import Divider from 'sentry/views/settings/components/settingsBreadcrumb/divider';
  8. import {OrganizationCrumb} from 'sentry/views/settings/components/settingsBreadcrumb/organizationCrumb';
  9. import ProjectCrumb from 'sentry/views/settings/components/settingsBreadcrumb/projectCrumb';
  10. import TeamCrumb from 'sentry/views/settings/components/settingsBreadcrumb/teamCrumb';
  11. import {useBreadcrumbsPathmap} from './context';
  12. import type {RouteWithName} from './types';
  13. const MENUS = {
  14. Organization: OrganizationCrumb,
  15. Project: ProjectCrumb,
  16. Team: TeamCrumb,
  17. } as const;
  18. type Props = {
  19. params: {[param: string]: string | undefined};
  20. route: any;
  21. routes: RouteWithName[];
  22. className?: string;
  23. };
  24. function SettingsBreadcrumb({className, routes, params}: Props) {
  25. const pathMap = useBreadcrumbsPathmap();
  26. const lastRouteIndex = routes.map(r => !!r.name).lastIndexOf(true);
  27. return (
  28. <Breadcrumbs aria-label={t('Settings Breadcrumbs')} className={className}>
  29. {routes.map((route, i) => {
  30. if (!route.name) {
  31. return null;
  32. }
  33. const pathTitle = pathMap[getRouteStringFromRoutes(routes.slice(0, i + 1))];
  34. const isLast = i === lastRouteIndex;
  35. const createMenu = MENUS[route.name];
  36. const Menu = typeof createMenu === 'function' && createMenu;
  37. const hasMenu = !!Menu;
  38. if (hasMenu) {
  39. return (
  40. <Menu
  41. key={`${route.name}:${route.path}`}
  42. routes={routes}
  43. params={params}
  44. route={route}
  45. isLast={isLast}
  46. />
  47. );
  48. }
  49. return (
  50. <Crumb key={`${route.name}:${route.path}`}>
  51. <CrumbLink to={recreateRoute(route, {routes, params})}>
  52. {pathTitle || route.name}
  53. </CrumbLink>
  54. <Divider isLast={isLast} />
  55. </Crumb>
  56. );
  57. })}
  58. </Breadcrumbs>
  59. );
  60. }
  61. export default SettingsBreadcrumb;
  62. const CrumbLink = styled(RouterLink)`
  63. display: block;
  64. color: ${p => p.theme.subText};
  65. &:hover {
  66. color: ${p => p.theme.textColor};
  67. }
  68. `;
  69. export {CrumbLink};
  70. const Breadcrumbs = styled('nav')`
  71. display: flex;
  72. align-items: center;
  73. `;