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 };