Browse Source

improvement/config-save-spinner add spinner for submit button (#3551)

* improvement/config-save-spinner add spinner for submit button

* improvement/config-save-spinner add Spinner component to common, update spinner usage

* improvement/config-save-spinner remove unused props for spinner component

* improvement/config-save-spinner add defaultProps, refactor props definition

* improvement/config-save-spinner disable button on inProgress prop

---------

Co-authored-by: Oleg Shur <workshur@gmail.com>
Nail Badiullin 2 years ago
parent
commit
dc08701246

+ 14 - 1
kafka-ui-react-app/src/components/common/Button/Button.tsx

@@ -3,11 +3,13 @@ import StyledButton, {
 } from 'components/common/Button/Button.styled';
 } from 'components/common/Button/Button.styled';
 import React from 'react';
 import React from 'react';
 import { Link } from 'react-router-dom';
 import { Link } from 'react-router-dom';
+import Spinner from 'components/common/Spinner/Spinner';
 
 
 export interface Props
 export interface Props
   extends React.ButtonHTMLAttributes<HTMLButtonElement>,
   extends React.ButtonHTMLAttributes<HTMLButtonElement>,
     ButtonProps {
     ButtonProps {
   to?: string | object;
   to?: string | object;
+  inProgress?: boolean;
 }
 }
 
 
 export const Button: React.FC<Props> = ({ to, ...props }) => {
 export const Button: React.FC<Props> = ({ to, ...props }) => {
@@ -20,5 +22,16 @@ export const Button: React.FC<Props> = ({ to, ...props }) => {
       </Link>
       </Link>
     );
     );
   }
   }
-  return <StyledButton type="button" {...props} />;
+  return (
+    <StyledButton
+      type="button"
+      disabled={props.disabled || props.inProgress}
+      {...props}
+    >
+      {props.children}{' '}
+      {props.inProgress ? (
+        <Spinner size={16} borderWidth={2} marginLeft={2} emptyBorderColor />
+      ) : null}
+    </StyledButton>
+  );
 };
 };

+ 6 - 0
kafka-ui-react-app/src/components/common/Button/__tests__/Button.spec.tsx

@@ -58,4 +58,10 @@ describe('Button', () => {
       theme.button.primary.invertedColors.normal
       theme.button.primary.invertedColors.normal
     );
     );
   });
   });
+  it('renders disabled button and spinner when inProgress truthy', () => {
+    render(<Button buttonType="primary" buttonSize="M" inProgress />);
+    expect(screen.getByRole('button')).toBeInTheDocument();
+    expect(screen.getByRole('progressbar')).toBeInTheDocument();
+    expect(screen.getByRole('button')).toBeDisabled();
+  });
 });
 });

+ 1 - 21
kafka-ui-react-app/src/components/common/PageLoader/PageLoader.styled.ts

@@ -1,4 +1,4 @@
-import styled, { css } from 'styled-components';
+import styled from 'styled-components';
 
 
 export const Wrapper = styled.div`
 export const Wrapper = styled.div`
   display: flex;
   display: flex;
@@ -8,23 +8,3 @@ export const Wrapper = styled.div`
   height: 100%;
   height: 100%;
   width: 100%;
   width: 100%;
 `;
 `;
-
-export const Spinner = styled.div(
-  ({ theme }) => css`
-    border: 10px solid ${theme.pageLoader.borderColor};
-    border-bottom: 10px solid ${theme.pageLoader.borderBottomColor};
-    border-radius: 50%;
-    width: 80px;
-    height: 80px;
-    animation: spin 1.3s linear infinite;
-
-    @keyframes spin {
-      0% {
-        transform: rotate(0deg);
-      }
-      100% {
-        transform: rotate(360deg);
-      }
-    }
-  `
-);

+ 2 - 1
kafka-ui-react-app/src/components/common/PageLoader/PageLoader.tsx

@@ -1,10 +1,11 @@
 import React from 'react';
 import React from 'react';
+import Spinner from 'components/common/Spinner/Spinner';
 
 
 import * as S from './PageLoader.styled';
 import * as S from './PageLoader.styled';
 
 
 const PageLoader: React.FC = () => (
 const PageLoader: React.FC = () => (
   <S.Wrapper>
   <S.Wrapper>
-    <S.Spinner role="progressbar" />
+    <Spinner />
   </S.Wrapper>
   </S.Wrapper>
 );
 );
 
 

+ 26 - 0
kafka-ui-react-app/src/components/common/Spinner/Spinner.styled.ts

@@ -0,0 +1,26 @@
+import styled from 'styled-components';
+import { SpinnerProps } from 'components/common/Spinner/types';
+
+export const Spinner = styled.div<SpinnerProps>`
+  border-width: ${(props) => props.borderWidth}px;
+  border-style: solid;
+  border-color: ${({ theme }) => theme.pageLoader.borderColor};
+  border-bottom-color: ${(props) =>
+    props.emptyBorderColor
+      ? 'transparent'
+      : props.theme.pageLoader.borderBottomColor};
+  border-radius: 50%;
+  width: ${(props) => props.size}px;
+  height: ${(props) => props.size}px;
+  margin-left: ${(props) => props.marginLeft}px;
+  animation: spin 1.3s linear infinite;
+
+  @keyframes spin {
+    0% {
+      transform: rotate(0deg);
+    }
+    100% {
+      transform: rotate(360deg);
+    }
+  }
+`;

+ 20 - 0
kafka-ui-react-app/src/components/common/Spinner/Spinner.tsx

@@ -0,0 +1,20 @@
+/* eslint-disable react/default-props-match-prop-types */
+import React from 'react';
+import { SpinnerProps } from 'components/common/Spinner/types';
+
+import * as S from './Spinner.styled';
+
+const defaultProps: SpinnerProps = {
+  size: 80,
+  borderWidth: 10,
+  emptyBorderColor: false,
+  marginLeft: 0,
+};
+
+const Spinner: React.FC<SpinnerProps> = (props) => (
+  <S.Spinner role="progressbar" {...props} />
+);
+
+Spinner.defaultProps = defaultProps;
+
+export default Spinner;

+ 6 - 0
kafka-ui-react-app/src/components/common/Spinner/types.ts

@@ -0,0 +1,6 @@
+export interface SpinnerProps {
+  size?: number;
+  borderWidth?: number;
+  emptyBorderColor?: boolean;
+  marginLeft?: number;
+}

+ 1 - 0
kafka-ui-react-app/src/widgets/ClusterConfigForm/index.tsx

@@ -142,6 +142,7 @@ const ClusterConfigForm: React.FC<ClusterConfigFormProps> = ({
               buttonSize="L"
               buttonSize="L"
               buttonType="primary"
               buttonType="primary"
               disabled={isSubmitDisabled}
               disabled={isSubmitDisabled}
+              inProgress={isSubmitting}
             >
             >
               Submit
               Submit
             </Button>
             </Button>