SafeDynamicImport.tsx 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import React, { lazy, Suspense, FunctionComponent } from 'react';
  2. import { cx, css } from 'emotion';
  3. import { LoadingPlaceholder, ErrorBoundary, Button } from '@grafana/ui';
  4. export const LoadingChunkPlaceHolder: FunctionComponent = () => (
  5. <div className={cx('preloader')}>
  6. <LoadingPlaceholder text={'Loading...'} />
  7. </div>
  8. );
  9. function getAlertPageStyle() {
  10. return css`
  11. width: 508px;
  12. margin: 128px auto;
  13. `;
  14. }
  15. export const SafeDynamicImport = (importStatement: Promise<any>) => ({ ...props }) => {
  16. const LazyComponent = lazy(() => importStatement);
  17. return (
  18. <ErrorBoundary>
  19. {({ error, errorInfo }) => {
  20. if (!errorInfo) {
  21. return (
  22. <Suspense fallback={<LoadingChunkPlaceHolder />}>
  23. <LazyComponent {...props} />
  24. </Suspense>
  25. );
  26. }
  27. return (
  28. <div className={getAlertPageStyle()}>
  29. <h2>Unable to find application file</h2>
  30. <br />
  31. <h2 className="page-heading">Grafana has likely been updated. Please try reloading the page.</h2>
  32. <br />
  33. <div className="gf-form-group">
  34. <Button size={'md'} variant={'secondary'} icon="fa fa-repeat" onClick={() => window.location.reload()}>
  35. Reload
  36. </Button>
  37. </div>
  38. <details style={{ whiteSpace: 'pre-wrap' }}>
  39. {error && error.toString()}
  40. <br />
  41. {errorInfo.componentStack}
  42. </details>
  43. </div>
  44. );
  45. }}
  46. </ErrorBoundary>
  47. );
  48. };