Browse Source

ref(ui): Extract LoadingTriangle from LoadingIndicator (#30779)

Evan Purkhiser 3 years ago
parent
commit
414d76cacb

+ 6 - 3
docs-ui/stories/components/loadingIndicator.stories.js

@@ -1,4 +1,5 @@
 import LoadingIndicator from 'sentry/components/loadingIndicator';
+import LoadingTriangle from 'sentry/components/loadingTriangle';
 
 export default {
   title: 'Components/Loading Indicators',
@@ -15,9 +16,11 @@ export const All = () => (
       Mini
       <LoadingIndicator mini />
     </div>
-    <div style={{position: 'relative'}}>
+    <div>
       Triangle
-      <LoadingIndicator triangle />
+      <div style={{position: 'relative'}}>
+        <LoadingTriangle />
+      </div>
     </div>
   </div>
 );
@@ -48,7 +51,7 @@ Mini.parameters = {
 
 export const Triangle = () => (
   <div style={{paddingBottom: 300}}>
-    <LoadingIndicator triangle>Loading message</LoadingIndicator>
+    <LoadingTriangle>Loading message</LoadingTriangle>
   </div>
 );
 

+ 1 - 14
static/app/components/loadingIndicator.tsx

@@ -2,13 +2,10 @@ import * as React from 'react';
 import {withProfiler} from '@sentry/react';
 import classNames from 'classnames';
 
-import sentryLoader from 'sentry-images/sentry-loader.svg';
-
 type Props = {
   overlay?: boolean;
   dark?: boolean;
   mini?: boolean;
-  triangle?: boolean;
   relative?: boolean;
   hideMessage?: boolean;
   hideSpinner?: boolean;
@@ -18,15 +15,10 @@ type Props = {
   children?: React.ReactNode;
 };
 
-function renderLogoSpinner() {
-  return <img src={sentryLoader} />;
-}
-
 function LoadingIndicator(props: Props) {
   const {
     hideMessage,
     mini,
-    triangle,
     overlay,
     dark,
     children,
@@ -41,7 +33,6 @@ function LoadingIndicator(props: Props) {
     dark,
     loading: true,
     mini,
-    triangle,
   });
 
   const loadingCx = classNames({
@@ -59,11 +50,7 @@ function LoadingIndicator(props: Props) {
 
   return (
     <div className={cx} style={style} data-test-id="loading-indicator">
-      {!hideSpinner && (
-        <div className={loadingCx} style={loadingStyle}>
-          {triangle && renderLogoSpinner()}
-        </div>
-      )}
+      {!hideSpinner && <div className={loadingCx} style={loadingStyle} />}
       {!hideMessage && <div className="loading-message">{children}</div>}
     </div>
   );

+ 44 - 0
static/app/components/loadingTriangle.tsx

@@ -0,0 +1,44 @@
+import styled from '@emotion/styled';
+
+import sentryLoader from 'sentry-images/sentry-loader.svg';
+
+import space from 'sentry/styles/space';
+
+type Props = {
+  children?: React.ReactNode;
+};
+
+function LoadingTriangle({children}: Props) {
+  return (
+    <LoadingTriangleWrapper data-test-id="loading-indicator">
+      <CircleBackground>
+        <img src={sentryLoader} />
+      </CircleBackground>
+      {children && <div>{children}</div>}
+    </LoadingTriangleWrapper>
+  );
+}
+
+const LoadingTriangleWrapper = styled('div')`
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  width: 500px;
+  transform: translate(-50%, -50%);
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  gap: ${space(3)};
+`;
+
+const CircleBackground = styled('div')`
+  height: 150px;
+  width: 150px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background: ${p => p.theme.white};
+  border-radius: 50%;
+`;
+
+export default LoadingTriangle;

+ 2 - 4
static/app/views/organizationContext.tsx

@@ -10,7 +10,7 @@ import ProjectActions from 'sentry/actions/projectActions';
 import {Client} from 'sentry/api';
 import Alert from 'sentry/components/alert';
 import LoadingError from 'sentry/components/loadingError';
-import LoadingIndicator from 'sentry/components/loadingIndicator';
+import LoadingTriangle from 'sentry/components/loadingTriangle';
 import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
 import Sidebar from 'sentry/components/sidebar';
 import {ORGANIZATION_FETCH_ERROR_TYPES} from 'sentry/constants';
@@ -339,9 +339,7 @@ class OrganizationContextContainer extends React.Component<Props, State> {
   render() {
     if (this.isLoading()) {
       return (
-        <LoadingIndicator triangle>
-          {t('Loading data for your organization.')}
-        </LoadingIndicator>
+        <LoadingTriangle>{t('Loading data for your organization.')}</LoadingTriangle>
       );
     }
 

+ 4 - 4
tests/js/spec/views/organizationContext.spec.jsx

@@ -240,7 +240,7 @@ describe('OrganizationContext', function () {
       organizations: [],
     });
 
-    expect(wrapper.find('LoadingIndicator')).toHaveLength(1);
+    expect(wrapper.find('LoadingTriangle')).toHaveLength(1);
 
     wrapper.setProps({
       organizationsLoading: false,
@@ -253,7 +253,7 @@ describe('OrganizationContext', function () {
     await tick(); // action to start fetch org
     await tick(); // action after successfully fetching org
     wrapper.update();
-    expect(wrapper.find('LoadingIndicator')).toHaveLength(0);
+    expect(wrapper.find('LoadingTriangle')).toHaveLength(0);
 
     expect(getOrgMock).toHaveBeenCalled();
     expect(getProjectsMock).toHaveBeenCalled();
@@ -285,7 +285,7 @@ describe('OrganizationContext', function () {
     // await resolving api, and updating component
     await tick();
     wrapper.update();
-    expect(wrapper.find('LoadingIndicator')).toHaveLength(0);
+    expect(wrapper.find('LoadingTriangle')).toHaveLength(0);
     expect(getOrgMock).toHaveBeenCalledTimes(1);
 
     // Simulate OrganizationsStore being loaded *after* `OrganizationContext` finishes
@@ -314,7 +314,7 @@ describe('OrganizationContext', function () {
     // await resolving api, and updating component
     await tick();
     wrapper.update();
-    expect(wrapper.find('LoadingIndicator')).toHaveLength(0);
+    expect(wrapper.find('LoadingTriangle')).toHaveLength(0);
     expect(getOrgMock).toHaveBeenCalledTimes(1);
 
     // Simulate OrganizationsStore being loaded *after* `OrganizationContext` finishes