From 2be72885e2d49a5637c2741e1844dfe92d3e197e Mon Sep 17 00:00:00 2001
From: crupest <crupest@outlook.com>
Date: Thu, 3 Sep 2020 18:35:44 +0800
Subject: Beatify login page.

---
 .../src/app/views/common/LoadingButton.tsx         | 28 ++++++++++++++++++++++
 1 file changed, 28 insertions(+)
 create mode 100644 Timeline/ClientApp/src/app/views/common/LoadingButton.tsx

(limited to 'Timeline/ClientApp/src/app/views/common/LoadingButton.tsx')

diff --git a/Timeline/ClientApp/src/app/views/common/LoadingButton.tsx b/Timeline/ClientApp/src/app/views/common/LoadingButton.tsx
new file mode 100644
index 00000000..fa721afe
--- /dev/null
+++ b/Timeline/ClientApp/src/app/views/common/LoadingButton.tsx
@@ -0,0 +1,28 @@
+import React from "react";
+import { Button, ButtonProps, Spinner } from "react-bootstrap";
+
+const LoadingButton: React.FC<{ loading?: boolean } & ButtonProps> = ({
+  loading,
+  variant,
+  ...otherProps
+}) => {
+  return (
+    <Button
+      variant={variant != null ? `outline-${variant}` : "outline-primary"}
+      disabled={loading}
+      {...otherProps}
+    >
+      {otherProps.children}
+      {loading ? (
+        <Spinner
+          className="ml-1"
+          variant={variant}
+          animation="grow"
+          size="sm"
+        />
+      ) : null}
+    </Button>
+  );
+};
+
+export default LoadingButton;
-- 
cgit v1.2.3


From 46dc7e12da41056914a0f5fcdabbd20f81ef3bac Mon Sep 17 00:00:00 2001
From: crupest <crupest@outlook.com>
Date: Thu, 3 Sep 2020 22:49:55 +0800
Subject: ...

---
 .../src/app/views/common/LoadingButton.tsx         |  3 +-
 .../src/app/views/common/OperationDialog.tsx       | 36 ++++++++++------------
 2 files changed, 18 insertions(+), 21 deletions(-)

(limited to 'Timeline/ClientApp/src/app/views/common/LoadingButton.tsx')

diff --git a/Timeline/ClientApp/src/app/views/common/LoadingButton.tsx b/Timeline/ClientApp/src/app/views/common/LoadingButton.tsx
index fa721afe..154334a7 100644
--- a/Timeline/ClientApp/src/app/views/common/LoadingButton.tsx
+++ b/Timeline/ClientApp/src/app/views/common/LoadingButton.tsx
@@ -4,12 +4,13 @@ import { Button, ButtonProps, Spinner } from "react-bootstrap";
 const LoadingButton: React.FC<{ loading?: boolean } & ButtonProps> = ({
   loading,
   variant,
+  disabled,
   ...otherProps
 }) => {
   return (
     <Button
       variant={variant != null ? `outline-${variant}` : "outline-primary"}
-      disabled={loading}
+      disabled={disabled || loading}
       {...otherProps}
     >
       {otherProps.children}
diff --git a/Timeline/ClientApp/src/app/views/common/OperationDialog.tsx b/Timeline/ClientApp/src/app/views/common/OperationDialog.tsx
index 6f97eb15..841392a6 100644
--- a/Timeline/ClientApp/src/app/views/common/OperationDialog.tsx
+++ b/Timeline/ClientApp/src/app/views/common/OperationDialog.tsx
@@ -1,16 +1,10 @@
 import React, { useState } from "react";
 import { useTranslation } from "react-i18next";
-import { Spinner, Container, Form, Button, Modal } from "react-bootstrap";
+import { Form, Button, Modal } from "react-bootstrap";
 
 import { UiLogicError } from "@/common";
 
-const DefaultProcessPrompt: React.FC = (_) => {
-  return (
-    <Container className="justify-content-center align-items-center">
-      <Spinner animation="border" variant="success" />
-    </Container>
-  );
-};
+import LoadingButton from "./LoadingButton";
 
 interface DefaultErrorPromptProps {
   error?: string;
@@ -154,7 +148,9 @@ const OperationDialog: React.FC<OperationDialogProps> = (props) => {
   };
 
   let body: React.ReactNode;
-  if (step === "input") {
+  if (step === "input" || step === "process") {
+    const process = step === "process";
+
     let inputPrompt =
       typeof props.inputPrompt === "function"
         ? props.inputPrompt()
@@ -246,9 +242,12 @@ const OperationDialog: React.FC<OperationDialogProps> = (props) => {
                       );
                     }}
                     isInvalid={error != null}
+                    disabled={process}
                   />
                   {error != null && (
-                    <Form.Control.Feedback>{error}</Form.Control.Feedback>
+                    <Form.Control.Feedback type="invalid">
+                      {error}
+                    </Form.Control.Feedback>
                   )}
                   {item.helperText && (
                     <Form.Text>{t(item.helperText)}</Form.Text>
@@ -265,6 +264,7 @@ const OperationDialog: React.FC<OperationDialogProps> = (props) => {
                       updateValue(index, event.currentTarget.checked);
                     }}
                     label={t(item.label)}
+                    disabled={process}
                   />
                 </Form.Group>
               );
@@ -278,6 +278,7 @@ const OperationDialog: React.FC<OperationDialogProps> = (props) => {
                     onChange={(event) => {
                       updateValue(index, event.target.value);
                     }}
+                    disabled={process}
                   >
                     {item.options.map((option, i) => {
                       return (
@@ -294,11 +295,12 @@ const OperationDialog: React.FC<OperationDialogProps> = (props) => {
           })}
         </Modal.Body>
         <Modal.Footer>
-          <Button variant="secondary" onClick={close}>
+          <Button variant="outline-secondary" onClick={close}>
             {t("operationDialog.cancel")}
           </Button>
-          <Button
+          <LoadingButton
             variant="primary"
+            loading={process}
             disabled={testErrorInfo(inputError)}
             onClick={() => {
               if (validateAll()) {
@@ -307,16 +309,10 @@ const OperationDialog: React.FC<OperationDialogProps> = (props) => {
             }}
           >
             {t("operationDialog.confirm")}
-          </Button>
+          </LoadingButton>
         </Modal.Footer>
       </>
     );
-  } else if (step === "process") {
-    body = (
-      <Modal.Body>
-        {props.processPrompt?.() ?? <DefaultProcessPrompt />}
-      </Modal.Body>
-    );
   } else {
     let content: React.ReactNode;
     const result = step;
@@ -345,7 +341,7 @@ const OperationDialog: React.FC<OperationDialogProps> = (props) => {
   const title = typeof props.title === "string" ? t(props.title) : props.title;
 
   return (
-    <Modal isOpen={props.open} toggle={close}>
+    <Modal show={props.open} onHide={close}>
       <Modal.Header
         className={
           props.titleColor != null
-- 
cgit v1.2.3

