diff --git a/ui/src/Components/MainModal/index.js b/ui/src/Components/MainModal/index.js index 66948d4ed..bba66f8c2 100644 --- a/ui/src/Components/MainModal/index.js +++ b/ui/src/Components/MainModal/index.js @@ -6,12 +6,19 @@ import { observable, action } from "mobx"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faCog } from "@fortawesome/free-solid-svg-icons/faCog"; +import { faSpinner } from "@fortawesome/free-solid-svg-icons/faSpinner"; import { AlertStore } from "Stores/AlertStore"; import { Settings } from "Stores/Settings"; import { TooltipWrapper } from "Components/TooltipWrapper"; import { Modal } from "Components/Modal"; -import { MainModalContent } from "./MainModalContent"; + +// https://github.com/facebook/react/issues/14603 +const MainModalContent = React.lazy(() => + import("./MainModalContent").then(module => ({ + default: module.MainModalContent + })) +); const MainModal = observer( class MainModal extends Component { @@ -49,12 +56,20 @@ const MainModal = observer( - + + + + } + > + + ); diff --git a/ui/src/Components/MainModal/index.test.js b/ui/src/Components/MainModal/index.test.js index daed8ce4c..83f3e7da7 100644 --- a/ui/src/Components/MainModal/index.test.js +++ b/ui/src/Components/MainModal/index.test.js @@ -31,12 +31,22 @@ describe("", () => { expect(tree.find("MainModalContent")).toHaveLength(0); }); - it("renders the modal when it is shown", () => { + it("renders a spinner placeholder while modal content is loading", () => { + const tree = MountedMainModal(); + const toggle = tree.find(".nav-link"); + toggle.simulate("click"); + expect(tree.find("FontAwesomeIcon")).not.toHaveLength(0); + expect(tree.find("MainModalContent")).toHaveLength(0); + expect(tree.find(".modal-content").find("svg.fa-spinner")).toHaveLength(1); + }); + + it("renders modal content if fallback is not used", () => { const tree = MountedMainModal(); const toggle = tree.find(".nav-link"); toggle.simulate("click"); expect(tree.find("FontAwesomeIcon")).not.toHaveLength(0); expect(tree.find("MainModalContent")).toHaveLength(1); + expect(tree.find(".modal-content").find("svg.fa-spinner")).toHaveLength(0); }); it("hides the modal when toggle() is called twice", () => { diff --git a/ui/src/Components/SilenceModal/index.js b/ui/src/Components/SilenceModal/index.js index 400a261d2..52e0ea155 100644 --- a/ui/src/Components/SilenceModal/index.js +++ b/ui/src/Components/SilenceModal/index.js @@ -5,16 +5,23 @@ import { observer } from "mobx-react"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faBellSlash } from "@fortawesome/free-solid-svg-icons/faBellSlash"; +import { faSpinner } from "@fortawesome/free-solid-svg-icons/faSpinner"; import { AlertStore } from "Stores/AlertStore"; import { SilenceFormStore } from "Stores/SilenceFormStore"; import { Settings } from "Stores/Settings"; import { Modal } from "Components/Modal"; import { TooltipWrapper } from "Components/TooltipWrapper"; -import { SilenceModalContent } from "./SilenceModalContent"; import "./index.css"; +// https://github.com/facebook/react/issues/14603 +const SilenceModalContent = React.lazy(() => + import("./SilenceModalContent").then(module => ({ + default: module.SilenceModalContent + })) +); + const SilenceModal = observer( class SilenceModal extends Component { static propTypes = { @@ -42,12 +49,20 @@ const SilenceModal = observer( isOpen={silenceFormStore.toggle.visible} onExited={silenceFormStore.data.resetProgress} > - + + + + } + > + + ); diff --git a/ui/src/Components/SilenceModal/index.test.js b/ui/src/Components/SilenceModal/index.test.js index 0954eb3e0..8e39ad585 100644 --- a/ui/src/Components/SilenceModal/index.test.js +++ b/ui/src/Components/SilenceModal/index.test.js @@ -39,12 +39,22 @@ describe("", () => { expect(tree.find("SilenceModalContent")).toHaveLength(0); }); - it("renders the modal when it is shown", () => { + it("renders a spinner placeholder while modal content is loading", () => { + const tree = MountedSilenceModal(); + const toggle = tree.find(".nav-link"); + toggle.simulate("click"); + expect(tree.find("FontAwesomeIcon")).not.toHaveLength(0); + expect(tree.find("SilenceModalContent")).toHaveLength(0); + expect(tree.find(".modal-content").find("svg.fa-spinner")).toHaveLength(1); + }); + + it("renders modal content if fallback is not used", () => { const tree = MountedSilenceModal(); const toggle = tree.find(".nav-link"); toggle.simulate("click"); expect(tree.find("FontAwesomeIcon")).not.toHaveLength(0); expect(tree.find("SilenceModalContent")).toHaveLength(1); + expect(tree.find(".modal-content").find("svg.fa-spinner")).toHaveLength(0); }); it("hides the modal when toggle() is called twice", () => { diff --git a/ui/src/Components/TooltipWrapper/index.js b/ui/src/Components/TooltipWrapper/index.js index 5f735f209..e6ce4dba4 100644 --- a/ui/src/Components/TooltipWrapper/index.js +++ b/ui/src/Components/TooltipWrapper/index.js @@ -1,5 +1,4 @@ import React from "react"; -import PropTypes from "prop-types"; import { Tooltip } from "react-tippy"; @@ -10,14 +9,11 @@ const TooltipWrapper = ({ children, ...props }) => ( delay={[1000, 100]} size="small" touchHold={true} - style={{ display: "inline-block", "maxWidth": "100%" }} + style={{ display: "inline-block", maxWidth: "100%" }} {...props} > {children} ); -Tooltip.propTypes = { - children: PropTypes.node.isRequired -}; export { TooltipWrapper };