pickProjectToContinue.tsx 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import {InjectedRouter} from 'react-router';
  2. import styled from '@emotion/styled';
  3. import {LocationDescriptor, LocationDescriptorObject} from 'history';
  4. import {openModal} from 'sentry/actionCreators/modal';
  5. import ContextPickerModal from 'sentry/components/contextPickerModal';
  6. type Project = {
  7. id: string;
  8. slug: string;
  9. };
  10. type Props = {
  11. /**
  12. * Path used on the redirect router if the user did select a project
  13. */
  14. nextPath: Pick<LocationDescriptorObject, 'query'> & {
  15. pathname: NonNullable<LocationDescriptorObject['pathname']>;
  16. };
  17. /**
  18. * Path used on the redirect router if the user did not select a project
  19. */
  20. noProjectRedirectPath: LocationDescriptor;
  21. projects: Project[];
  22. router: InjectedRouter;
  23. };
  24. function PickProjectToContinue({
  25. noProjectRedirectPath,
  26. nextPath,
  27. router,
  28. projects,
  29. }: Props) {
  30. const nextPathQuery = nextPath.query;
  31. let navigating = false;
  32. let path = `${nextPath.pathname}?project=`;
  33. if (nextPathQuery) {
  34. const filteredQuery = Object.entries(nextPathQuery)
  35. .filter(([key, _value]) => key !== 'project')
  36. .map(([key, value]) => `${key}=${value}`);
  37. const newPathQuery = [...filteredQuery, 'project='].join('&');
  38. path = `${nextPath.pathname}?${newPathQuery}`;
  39. }
  40. // if the project in URL is missing, but this release belongs to only one project, redirect there
  41. if (projects.length === 1) {
  42. router.replace(path + projects[0].id);
  43. return null;
  44. }
  45. openModal(
  46. modalProps => (
  47. <ContextPickerModal
  48. {...modalProps}
  49. needOrg={false}
  50. needProject
  51. nextPath={`${path}:project`}
  52. onFinish={pathname => {
  53. navigating = true;
  54. router.replace(pathname);
  55. }}
  56. projectSlugs={projects.map(p => p.slug)}
  57. />
  58. ),
  59. {
  60. onClose() {
  61. // we want this to be executed only if the user didn't select any project
  62. // (closed modal either via button, Esc, clicking outside, ...)
  63. if (!navigating) {
  64. router.push(noProjectRedirectPath);
  65. }
  66. },
  67. }
  68. );
  69. return <ContextPickerBackground />;
  70. }
  71. const ContextPickerBackground = styled('div')`
  72. height: 100vh;
  73. width: 100%;
  74. `;
  75. export default PickProjectToContinue;