pickProjectToContinue.tsx 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  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. allowAllProjectsSelection?: boolean;
  24. };
  25. function PickProjectToContinue({
  26. noProjectRedirectPath,
  27. nextPath,
  28. router,
  29. projects,
  30. allowAllProjectsSelection = false,
  31. }: Props) {
  32. const nextPathQuery = nextPath.query;
  33. let navigating = false;
  34. let path = `${nextPath.pathname}?project=`;
  35. if (nextPathQuery) {
  36. const filteredQuery = Object.entries(nextPathQuery)
  37. .filter(([key, _value]) => key !== 'project')
  38. .map(([key, value]) => `${key}=${value}`);
  39. const newPathQuery = [...filteredQuery, 'project='].join('&');
  40. path = `${nextPath.pathname}?${newPathQuery}`;
  41. }
  42. // if the project in URL is missing, but this release belongs to only one project, redirect there
  43. if (projects.length === 1) {
  44. router.replace(path + projects[0].id);
  45. return null;
  46. }
  47. openModal(
  48. modalProps => (
  49. <ContextPickerModal
  50. {...modalProps}
  51. needOrg={false}
  52. needProject
  53. nextPath={`${path}:project`}
  54. onFinish={pathname => {
  55. navigating = true;
  56. router.replace(pathname);
  57. }}
  58. projectSlugs={projects.map(p => p.slug)}
  59. allowAllProjectsSelection={allowAllProjectsSelection}
  60. />
  61. ),
  62. {
  63. onClose() {
  64. // we want this to be executed only if the user didn't select any project
  65. // (closed modal either via button, Esc, clicking outside, ...)
  66. if (!navigating) {
  67. router.push(noProjectRedirectPath);
  68. }
  69. },
  70. }
  71. );
  72. return <ContextPickerBackground />;
  73. }
  74. const ContextPickerBackground = styled('div')`
  75. height: 100vh;
  76. width: 100%;
  77. `;
  78. export default PickProjectToContinue;