projectLoadingError.tsx 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import styled from '@emotion/styled';
  2. import Alert from 'sentry/components/alert';
  3. import {LinkButton} from 'sentry/components/button';
  4. import LoadingError from 'sentry/components/loadingError';
  5. import {t} from 'sentry/locale';
  6. import type RequestError from 'sentry/utils/requestError/requestError';
  7. function getSsoLoginUrl(error: RequestError) {
  8. const detail = error?.responseJSON?.detail as any;
  9. const loginUrl = detail?.extra?.loginUrl;
  10. if (!loginUrl || typeof loginUrl !== 'string') {
  11. return null;
  12. }
  13. try {
  14. // Pass a base param as the login may be absolute or relative
  15. const url = new URL(loginUrl, location.origin);
  16. // Pass the current URL as the next URL to redirect to after login
  17. url.searchParams.set('next', location.href);
  18. return url.toString();
  19. } catch {
  20. return null;
  21. }
  22. }
  23. export function ProjectLoadingError({
  24. error,
  25. onRetry,
  26. }: {
  27. error: RequestError;
  28. onRetry: () => void;
  29. }) {
  30. const detail = error?.responseJSON?.detail;
  31. const code = typeof detail === 'string' ? undefined : detail?.code;
  32. const ssoLoginUrl = getSsoLoginUrl(error);
  33. if (code === 'sso-required' && ssoLoginUrl) {
  34. return (
  35. <AlertWithoutMargin
  36. type="error"
  37. showIcon
  38. trailingItems={
  39. <LinkButton href={ssoLoginUrl} size="xs">
  40. {t('Log in')}
  41. </LinkButton>
  42. }
  43. >
  44. {t('This organization requires Single Sign-On.')}
  45. </AlertWithoutMargin>
  46. );
  47. }
  48. return (
  49. <LoadingErrorWithoutMargin
  50. message={t('Failed to load projects')}
  51. onRetry={() => {
  52. onRetry();
  53. }}
  54. />
  55. );
  56. }
  57. const AlertWithoutMargin = styled(Alert)`
  58. margin: 0;
  59. `;
  60. const LoadingErrorWithoutMargin = styled(LoadingError)`
  61. margin: 0;
  62. `;