settingsBreadcrumb.tsx 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import styled from '@emotion/styled';
  2. import capitalize from 'lodash/capitalize';
  3. import Link from 'sentry/components/links/link';
  4. import Crumb from 'sentry/views/settings/components/settingsBreadcrumb/crumb';
  5. import Divider from 'sentry/views/settings/components/settingsBreadcrumb/divider';
  6. import OrganizationCrumb from 'sentry/views/settings/components/settingsBreadcrumb/organizationCrumb';
  7. import ProjectCrumb from 'sentry/views/settings/components/settingsBreadcrumb/projectCrumb';
  8. import TeamCrumb from 'sentry/views/settings/components/settingsBreadcrumb/teamCrumb';
  9. const MENUS = {
  10. Organization: OrganizationCrumb,
  11. Project: ProjectCrumb,
  12. Team: TeamCrumb,
  13. } as const;
  14. type Props = {
  15. url: string;
  16. className?: string;
  17. };
  18. function SettingsBreadcrumb({className, url}: Props) {
  19. console.log({url});
  20. const {pathname} = new URL(url);
  21. const splitPath = pathname.split('/').filter(item => !!item);
  22. return (
  23. <Breadcrumbs className={className}>
  24. {splitPath.map((item, i) => {
  25. const pathTitle = capitalize(item.replaceAll('-', ' '));
  26. const isLast = i === splitPath.length - 1;
  27. const createMenu = MENUS[pathTitle];
  28. const Menu = typeof createMenu === 'function' && createMenu;
  29. const hasMenu = !!Menu;
  30. const thisPath = '/' + splitPath.slice(0, i + 1).join('/');
  31. console.log({pathTitle, isLast, thisPath, hasMenu});
  32. const CrumbItem = hasMenu
  33. ? Menu
  34. : () => (
  35. <Crumb>
  36. <CrumbLink to={thisPath}>{pathTitle} </CrumbLink>
  37. <Divider isLast={isLast} />
  38. </Crumb>
  39. );
  40. return <CrumbItem key={`${thisPath}`} isLast={isLast} />;
  41. })}
  42. </Breadcrumbs>
  43. );
  44. }
  45. export default SettingsBreadcrumb;
  46. const CrumbLink = styled(Link)`
  47. display: block;
  48. &.focus-visible {
  49. outline: none;
  50. box-shadow: ${p => p.theme.blue300} 0 2px 0;
  51. }
  52. color: ${p => p.theme.subText};
  53. &:hover {
  54. color: ${p => p.theme.textColor};
  55. }
  56. `;
  57. export {CrumbLink};
  58. const Breadcrumbs = styled('div')`
  59. display: flex;
  60. align-items: center;
  61. `;