diff options
| author | crupest <crupest@outlook.com> | 2020-09-03 18:10:02 +0800 | 
|---|---|---|
| committer | crupest <crupest@outlook.com> | 2020-09-03 18:10:02 +0800 | 
| commit | 70be5235ba90a15b7798a7922382835fd680b1fc (patch) | |
| tree | 9f1ed076ecb0b7ef884b8cd8aa5c7e7497cb6376 /Timeline/ClientApp/src/app/views/common | |
| parent | b06cd597488b2d1c12ef9e35b25bdba6a9d4b11e (diff) | |
| download | timeline-70be5235ba90a15b7798a7922382835fd680b1fc.tar.gz timeline-70be5235ba90a15b7798a7922382835fd680b1fc.tar.bz2 timeline-70be5235ba90a15b7798a7922382835fd680b1fc.zip | |
Migrate to react-bootstrap.
Diffstat (limited to 'Timeline/ClientApp/src/app/views/common')
4 files changed, 48 insertions, 92 deletions
| diff --git a/Timeline/ClientApp/src/app/views/common/AppBar.tsx b/Timeline/ClientApp/src/app/views/common/AppBar.tsx index 464747c0..ee4ead8f 100644 --- a/Timeline/ClientApp/src/app/views/common/AppBar.tsx +++ b/Timeline/ClientApp/src/app/views/common/AppBar.tsx @@ -17,7 +17,7 @@ const AppBar: React.FC = (_) => {    const isAdministrator = user && user.administrator;    return ( -    <Navbar bg="primary" variant="dark" expand="md"> +    <Navbar bg="primary" variant="dark" expand="md" sticky="top">        <LinkContainer to="/">          <Navbar.Brand className="d-flex align-items-center">            <TimelineLogo style={{ height: "1em" }} /> diff --git a/Timeline/ClientApp/src/app/views/common/FileInput.tsx b/Timeline/ClientApp/src/app/views/common/FileInput.tsx deleted file mode 100644 index 7b053d5c..00000000 --- a/Timeline/ClientApp/src/app/views/common/FileInput.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from "react"; -import clsx from "clsx"; - -export interface FileInputProps -  extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "type" | "id"> { -  inputId?: string; -  labelText: string; -  color?: string; -  className?: string; -} - -const FileInput: React.FC<FileInputProps> = (props) => { -  const { inputId, labelText, color, className, ...otherProps } = props; - -  const realInputId = React.useMemo<string>(() => { -    if (inputId != null) return inputId; -    return ( -      "file-input-" + -      (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1) -    ); -  }, [inputId]); - -  return ( -    <> -      <input className="d-none" type="file" id={realInputId} {...otherProps} /> -      <label -        htmlFor={realInputId} -        className={clsx("btn", "btn-" + (color ?? "primary"), className)} -      > -        {labelText} -      </label> -    </> -  ); -}; - -export default FileInput; diff --git a/Timeline/ClientApp/src/app/views/common/OperationDialog.tsx b/Timeline/ClientApp/src/app/views/common/OperationDialog.tsx index 402ffbec..6f97eb15 100644 --- a/Timeline/ClientApp/src/app/views/common/OperationDialog.tsx +++ b/Timeline/ClientApp/src/app/views/common/OperationDialog.tsx @@ -1,26 +1,13 @@  import React, { useState } from "react";  import { useTranslation } from "react-i18next"; -import { -  Spinner, -  Container, -  ModalBody, -  Label, -  Input, -  FormGroup, -  FormFeedback, -  ModalFooter, -  Button, -  Modal, -  ModalHeader, -  FormText, -} from "reactstrap"; +import { Spinner, Container, Form, Button, Modal } from "react-bootstrap";  import { UiLogicError } from "@/common";  const DefaultProcessPrompt: React.FC = (_) => {    return (      <Container className="justify-content-center align-items-center"> -      <Spinner /> +      <Spinner animation="border" variant="success" />      </Container>    );  }; @@ -233,7 +220,7 @@ const OperationDialog: React.FC<OperationDialogProps> = (props) => {      body = (        <> -        <ModalBody> +        <Modal.Body>            {inputPrompt}            {inputScheme.map((item, index) => {              const value = values[index]; @@ -242,9 +229,9 @@ const OperationDialog: React.FC<OperationDialogProps> = (props) => {              if (item.type === "text") {                return ( -                <FormGroup key={index}> -                  {item.label && <Label>{t(item.label)}</Label>} -                  <Input +                <Form.Group key={index}> +                  {item.label && <Form.Label>{t(item.label)}</Form.Label>} +                  <Form.Control                      type={item.password === true ? "password" : "text"}                      value={value as string}                      onChange={(e) => { @@ -258,35 +245,35 @@ const OperationDialog: React.FC<OperationDialogProps> = (props) => {                          )                        );                      }} -                    invalid={error != null} -                    {...item.textFieldProps} +                    isInvalid={error != null}                    /> -                  {error != null && <FormFeedback>{error}</FormFeedback>} -                  {item.helperText && <FormText>{t(item.helperText)}</FormText>} -                </FormGroup> +                  {error != null && ( +                    <Form.Control.Feedback>{error}</Form.Control.Feedback> +                  )} +                  {item.helperText && ( +                    <Form.Text>{t(item.helperText)}</Form.Text> +                  )} +                </Form.Group>                );              } else if (item.type === "bool") {                return ( -                <FormGroup check key={index}> -                  <Input +                <Form.Group key={index}> +                  <Form.Check<"input">                      type="checkbox" -                    value={value as string} -                    onChange={(e) => { -                      updateValue( -                        index, -                        (e.target as HTMLInputElement).checked -                      ); +                    checked={value as boolean} +                    onChange={(event) => { +                      updateValue(index, event.currentTarget.checked);                      }} +                    label={t(item.label)}                    /> -                  <Label check>{t(item.label)}</Label> -                </FormGroup> +                </Form.Group>                );              } else if (item.type === "select") {                return ( -                <FormGroup key={index}> -                  <Label>{t(item.label)}</Label> -                  <Input -                    type="select" +                <Form.Group key={index}> +                  <Form.Label>{t(item.label)}</Form.Label> +                  <Form.Control +                    as="select"                      value={value as string}                      onChange={(event) => {                        updateValue(index, event.target.value); @@ -300,18 +287,18 @@ const OperationDialog: React.FC<OperationDialogProps> = (props) => {                          </option>                        );                      })} -                  </Input> -                </FormGroup> +                  </Form.Control> +                </Form.Group>                );              }            })} -        </ModalBody> -        <ModalFooter> -          <Button color="secondary" onClick={close}> +        </Modal.Body> +        <Modal.Footer> +          <Button variant="secondary" onClick={close}>              {t("operationDialog.cancel")}            </Button>            <Button -            color="primary" +            variant="primary"              disabled={testErrorInfo(inputError)}              onClick={() => {                if (validateAll()) { @@ -321,14 +308,14 @@ const OperationDialog: React.FC<OperationDialogProps> = (props) => {            >              {t("operationDialog.confirm")}            </Button> -        </ModalFooter> +        </Modal.Footer>        </>      );    } else if (step === "process") {      body = ( -      <ModalBody> +      <Modal.Body>          {props.processPrompt?.() ?? <DefaultProcessPrompt />} -      </ModalBody> +      </Modal.Body>      );    } else {      let content: React.ReactNode; @@ -345,12 +332,12 @@ const OperationDialog: React.FC<OperationDialogProps> = (props) => {      }      body = (        <> -        <ModalBody>{content}</ModalBody> -        <ModalFooter> -          <Button color="primary" onClick={close}> +        <Modal.Body>{content}</Modal.Body> +        <Modal.Footer> +          <Button variant="primary" onClick={close}>              {t("operationDialog.ok")}            </Button> -        </ModalFooter> +        </Modal.Footer>        </>      );    } @@ -359,7 +346,7 @@ const OperationDialog: React.FC<OperationDialogProps> = (props) => {    return (      <Modal isOpen={props.open} toggle={close}> -      <ModalHeader +      <Modal.Header          className={            props.titleColor != null              ? "text-" + @@ -372,7 +359,7 @@ const OperationDialog: React.FC<OperationDialogProps> = (props) => {          }        >          {title} -      </ModalHeader> +      </Modal.Header>        {body}      </Modal>    ); diff --git a/Timeline/ClientApp/src/app/views/common/alert/AlertHost.tsx b/Timeline/ClientApp/src/app/views/common/alert/AlertHost.tsx index 31c0fb86..c74f18e2 100644 --- a/Timeline/ClientApp/src/app/views/common/alert/AlertHost.tsx +++ b/Timeline/ClientApp/src/app/views/common/alert/AlertHost.tsx @@ -1,8 +1,8 @@  import React, { useCallback } from "react"; -import { Alert } from "reactstrap";  import without from "lodash/without";  import concat from "lodash/concat";  import { useTranslation } from "react-i18next"; +import { Alert } from "react-bootstrap";  import {    alertService, @@ -37,7 +37,12 @@ export const AutoCloseAlert: React.FC<AutoCloseAlertProps> = (props) => {    }, [dismissTime, props.close]);    return ( -    <Alert className="m-3" color={alert.type ?? "primary"} toggle={props.close}> +    <Alert +      className="m-3" +      variant={alert.type ?? "primary"} +      onClose={props.close} +      dismissible +    >        {(() => {          const { message } = alert;          if (typeof message === "function") { | 
