DashboardLoading.tsx 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. import { css, keyframes } from '@emotion/css';
  2. import React from 'react';
  3. import { GrafanaTheme } from '@grafana/data';
  4. import { locationService } from '@grafana/runtime';
  5. import { Button, HorizontalGroup, Spinner, useStyles, VerticalGroup } from '@grafana/ui';
  6. import { DashboardInitPhase } from 'app/types';
  7. export interface Props {
  8. initPhase: DashboardInitPhase;
  9. }
  10. export const DashboardLoading = ({ initPhase }: Props) => {
  11. const styles = useStyles(getStyles);
  12. const cancelVariables = () => {
  13. locationService.push('/');
  14. };
  15. return (
  16. <div className={styles.dashboardLoading}>
  17. <div className={styles.dashboardLoadingText}>
  18. <VerticalGroup spacing="md">
  19. <HorizontalGroup align="center" justify="center" spacing="xs">
  20. <Spinner inline={true} /> {initPhase}
  21. </HorizontalGroup>{' '}
  22. <HorizontalGroup align="center" justify="center">
  23. <Button variant="secondary" size="md" icon="repeat" onClick={cancelVariables}>
  24. Cancel loading dashboard
  25. </Button>
  26. </HorizontalGroup>
  27. </VerticalGroup>
  28. </div>
  29. </div>
  30. );
  31. };
  32. export const getStyles = (theme: GrafanaTheme) => {
  33. // Amount of time we want to pass before we start showing loading spinner
  34. const slowStartThreshold = '0.5s';
  35. const invisibleToVisible = keyframes`
  36. 0% { opacity: 0%; }
  37. 100% { opacity: 100%; }
  38. `;
  39. return {
  40. dashboardLoading: css`
  41. height: 60vh;
  42. display: flex;
  43. opacity: 0%;
  44. align-items: center;
  45. justify-content: center;
  46. animation: ${invisibleToVisible} 0s step-end ${slowStartThreshold} 1 normal forwards;
  47. `,
  48. dashboardLoadingText: css`
  49. font-size: ${theme.typography.size.lg};
  50. `,
  51. };
  52. };