mirror of
https://github.com/prymitive/karma
synced 2026-05-07 03:26:52 +00:00
Merge pull request #631 from prymitive/code-splitting
feat(ui): lazy load modals
This commit is contained in:
@@ -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(
|
||||
</TooltipWrapper>
|
||||
</li>
|
||||
<Modal isOpen={this.toggle.show}>
|
||||
<MainModalContent
|
||||
alertStore={alertStore}
|
||||
settingsStore={settingsStore}
|
||||
onHide={this.toggle.hide}
|
||||
isVisible={this.toggle.show}
|
||||
/>
|
||||
<React.Suspense
|
||||
fallback={
|
||||
<h1 className="display-1 text-secondary p-5 m-auto">
|
||||
<FontAwesomeIcon icon={faSpinner} size="lg" spin />
|
||||
</h1>
|
||||
}
|
||||
>
|
||||
<MainModalContent
|
||||
alertStore={alertStore}
|
||||
settingsStore={settingsStore}
|
||||
onHide={this.toggle.hide}
|
||||
isVisible={this.toggle.show}
|
||||
/>
|
||||
</React.Suspense>
|
||||
</Modal>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
@@ -31,12 +31,22 @@ describe("<MainModal />", () => {
|
||||
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", () => {
|
||||
|
||||
@@ -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}
|
||||
>
|
||||
<SilenceModalContent
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
settingsStore={settingsStore}
|
||||
onHide={silenceFormStore.toggle.hide}
|
||||
/>
|
||||
<React.Suspense
|
||||
fallback={
|
||||
<h1 className="display-1 text-secondary p-5 m-auto">
|
||||
<FontAwesomeIcon icon={faSpinner} size="lg" spin />
|
||||
</h1>
|
||||
}
|
||||
>
|
||||
<SilenceModalContent
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
settingsStore={settingsStore}
|
||||
onHide={silenceFormStore.toggle.hide}
|
||||
/>
|
||||
</React.Suspense>
|
||||
</Modal>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
@@ -39,12 +39,22 @@ describe("<SilenceModal />", () => {
|
||||
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", () => {
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
Tooltip.propTypes = {
|
||||
children: PropTypes.node.isRequired
|
||||
};
|
||||
|
||||
export { TooltipWrapper };
|
||||
|
||||
Reference in New Issue
Block a user