Skip to content
Snippets Groups Projects
Unverified Commit 3051967c authored by Alexander Polyankin's avatar Alexander Polyankin Committed by GitHub
Browse files

Migrate home to redux toolkit and unify jest tests (#31213)

parent 3438e466
No related branches found
No related tags found
No related merge requests found
Showing
with 169 additions and 204 deletions
import { DashboardId } from "./dashboard";
export type UserId = number; export type UserId = number;
export type UserAttribute = string; export type UserAttribute = string;
...@@ -27,7 +29,7 @@ export interface User extends BaseUser { ...@@ -27,7 +29,7 @@ export interface User extends BaseUser {
has_question_and_dashboard: boolean; has_question_and_dashboard: boolean;
personal_collection_id: number; personal_collection_id: number;
custom_homepage: { custom_homepage: {
dashboard_id: number; dashboard_id: DashboardId;
} | null; } | null;
} }
......
import { useDeepCompareEffect } from "react-use"; import { useDeepCompareEffect, usePrevious } from "react-use";
import type { Action } from "@reduxjs/toolkit"; import type { Action } from "@reduxjs/toolkit";
import { useDispatch, useSelector } from "metabase/lib/redux"; import { useDispatch, useSelector } from "metabase/lib/redux";
import { State } from "metabase-types/store"; import { State } from "metabase-types/store";
...@@ -50,17 +50,19 @@ export const useEntityListQuery = <TItem, TQuery = never>( ...@@ -50,17 +50,19 @@ export const useEntityListQuery = <TItem, TQuery = never>(
): UseEntityListQueryResult<TItem> => { ): UseEntityListQueryResult<TItem> => {
const options = { entityQuery }; const options = { entityQuery };
const data = useSelector(state => getList(state, options)); const data = useSelector(state => getList(state, options));
const error = useSelector(state => getError(state, options));
const isLoading = useSelector(state => getLoading(state, options)); const isLoading = useSelector(state => getLoading(state, options));
const isLoaded = useSelector(state => getLoaded(state, options)); const isLoaded = useSelector(state => getLoaded(state, options));
const error = useSelector(state => getError(state, options)); const isLoadedPreviously = usePrevious(isLoaded);
const isInvalidated = !isLoaded && isLoadedPreviously;
const dispatch = useDispatch(); const dispatch = useDispatch();
useDeepCompareEffect(() => { useDeepCompareEffect(() => {
if (enabled && !isLoaded) { if (enabled || (enabled && isInvalidated)) {
const action = dispatch(fetchList(entityQuery, { reload })); const action = dispatch(fetchList(entityQuery, { reload }));
Promise.resolve(action).catch(() => undefined); Promise.resolve(action).catch(() => undefined);
} }
}, [dispatch, fetchList, entityQuery, reload, enabled, isLoaded]); }, [dispatch, fetchList, entityQuery, reload, enabled, isInvalidated]);
return { data, isLoading, error }; return { data, isLoading, error };
}; };
...@@ -23,13 +23,13 @@ export const CustomHomePageModal = ({ ...@@ -23,13 +23,13 @@ export const CustomHomePageModal = ({
isOpen, isOpen,
onClose, onClose,
}: CustomHomePageModalProps) => { }: CustomHomePageModalProps) => {
const [dashboard, setDashboard] = useState<DashboardId>(); const [dashboardId, setDashboardId] = useState<DashboardId>();
const dispatch = useDispatch(); const dispatch = useDispatch();
const handleSave = async () => { const handleSave = async () => {
await dispatch( await dispatch(
updateSettings({ updateSettings({
[CUSTOM_HOMEPAGE_DASHBOARD_SETTING_KEY]: dashboard, [CUSTOM_HOMEPAGE_DASHBOARD_SETTING_KEY]: dashboardId,
[CUSTOM_HOMEPAGE_SETTING_KEY]: true, [CUSTOM_HOMEPAGE_SETTING_KEY]: true,
}), }),
); );
...@@ -37,14 +37,14 @@ export const CustomHomePageModal = ({ ...@@ -37,14 +37,14 @@ export const CustomHomePageModal = ({
}; };
const handleChange = useCallback( const handleChange = useCallback(
(value: number | null | undefined | string) => { (value: DashboardId | null | undefined) => {
if (value) { if (value) {
setDashboard(value); setDashboardId(value);
} else { } else {
setDashboard(undefined); setDashboardId(undefined);
} }
}, },
[setDashboard], [setDashboardId],
); );
return ( return (
...@@ -63,7 +63,7 @@ export const CustomHomePageModal = ({ ...@@ -63,7 +63,7 @@ export const CustomHomePageModal = ({
> >
<p>{t`Pick one of your dashboards to serve as homepage. Users without dashboard access will be directed to the default homepage. You can update or reset this anytime in Admin Settings > Settings > General`}</p> <p>{t`Pick one of your dashboards to serve as homepage. Users without dashboard access will be directed to the default homepage. You can update or reset this anytime in Admin Settings > Settings > General`}</p>
<DashboardSelector <DashboardSelector
value={dashboard} value={dashboardId}
onChange={handleChange} onChange={handleChange}
collectionFilter={(collection: Collection) => collectionFilter={(collection: Collection) =>
collection.personal_owner_id === null || collection.id === "root" collection.personal_owner_id === null || collection.id === "root"
......
export * from "./CustomHomePageModal";
import { ReactNode } from "react"; import { ReactNode } from "react";
import { CaptionRoot } from "./HomeCaption.styled"; import { CaptionRoot } from "./HomeCaption.styled";
export interface HomeCaptionProps { interface HomeCaptionProps {
primary?: boolean; primary?: boolean;
children?: ReactNode; children?: ReactNode;
} }
const HomeCaption = ({ primary, children }: HomeCaptionProps): JSX.Element => { export const HomeCaption = ({
primary,
children,
}: HomeCaptionProps): JSX.Element => {
return <CaptionRoot primary={primary}>{children}</CaptionRoot>; return <CaptionRoot primary={primary}>{children}</CaptionRoot>;
}; };
// eslint-disable-next-line import/no-default-export -- deprecated usage
export default HomeCaption;
import { render, screen } from "@testing-library/react"; import { render, screen } from "__support__/ui";
import HomeCaption from "./HomeCaption"; import { HomeCaption } from "./HomeCaption";
const setup = () => {
render(<HomeCaption>Title</HomeCaption>);
};
describe("HomeCaption", () => { describe("HomeCaption", () => {
it("should render correctly", () => { it("should render correctly", () => {
render(<HomeCaption>Title</HomeCaption>); setup();
expect(screen.getByText("Title")).toBeInTheDocument(); expect(screen.getByText("Title")).toBeInTheDocument();
}); });
}); });
// eslint-disable-next-line import/no-default-export -- deprecated usage export * from "./HomeCaption";
export { default } from "./HomeCaption";
import { ReactNode } from "react"; import { ReactNode } from "react";
import { CardRoot } from "./HomeCard.styled"; import { CardRoot } from "./HomeCard.styled";
export interface HomeCardProps { interface HomeCardProps {
className?: string; className?: string;
url?: string; url?: string;
external?: boolean; external?: boolean;
children?: ReactNode; children?: ReactNode;
} }
const HomeCard = ({ export const HomeCard = ({
className, className,
url = "", url = "",
children, children,
...@@ -19,6 +19,3 @@ const HomeCard = ({ ...@@ -19,6 +19,3 @@ const HomeCard = ({
</CardRoot> </CardRoot>
); );
}; };
// eslint-disable-next-line import/no-default-export -- deprecated usage
export default HomeCard;
import { render, screen } from "@testing-library/react"; import { render, screen } from "__support__/ui";
import HomeCard from "./HomeCard"; import { HomeCard } from "./HomeCard";
const setup = () => {
render(<HomeCard>A look at table</HomeCard>);
};
describe("HomeCard", () => { describe("HomeCard", () => {
it("should render correctly", () => { it("should render correctly", () => {
render(<HomeCard>A look at table</HomeCard>); setup();
expect(screen.getByText("A look at table")).toBeInTheDocument(); expect(screen.getByText("A look at table")).toBeInTheDocument();
}); });
}); });
// eslint-disable-next-line import/no-default-export -- deprecated usage export * from "./HomeCard";
export { default } from "./HomeCard";
import { useSelector } from "metabase/lib/redux";
import { isSyncCompleted } from "metabase/lib/syncing"; import { isSyncCompleted } from "metabase/lib/syncing";
import { getUser } from "metabase/selectors/user";
import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper"; import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
import {
useDatabaseListQuery,
usePopularItemListQuery,
useRecentItemListQuery,
} from "metabase/common/hooks";
import { PopularItem, RecentItem, User } from "metabase-types/api"; import { PopularItem, RecentItem, User } from "metabase-types/api";
import Database from "metabase-lib/metadata/Database"; import Database from "metabase-lib/metadata/Database";
import HomePopularSection from "../HomePopularSection"; import { HomePopularSection } from "../HomePopularSection";
import HomeRecentSection from "../HomeRecentSection"; import { HomeRecentSection } from "../HomeRecentSection";
import HomeXraySection from "../../containers/HomeXraySection"; import { HomeXraySection } from "../HomeXraySection";
import { getIsXrayEnabled } from "../../selectors";
import { isWithinWeeks } from "../../utils"; import { isWithinWeeks } from "../../utils";
export interface HomeContentProps { export const HomeContent = (): JSX.Element | null => {
user: User; const user = useSelector(getUser);
databases?: Database[]; const isXrayEnabled = useSelector(getIsXrayEnabled);
recentItems?: RecentItem[]; const { data: databases } = useDatabaseListQuery();
popularItems?: PopularItem[]; const { data: recentItems } = useRecentItemListQuery({ reload: true });
isXrayEnabled: boolean; const { data: popularItems } = usePopularItemListQuery({ reload: true });
}
const HomeContent = (props: HomeContentProps): JSX.Element | null => { if (!user || isLoading(user, databases, recentItems, popularItems)) {
if (isLoading(props)) {
return <LoadingAndErrorWrapper loading />; return <LoadingAndErrorWrapper loading />;
} }
if (isPopularSection(props)) { if (isPopularSection(user, recentItems, popularItems)) {
return <HomePopularSection />; return <HomePopularSection />;
} }
if (isRecentSection(props)) { if (isRecentSection(user, recentItems)) {
return <HomeRecentSection />; return <HomeRecentSection />;
} }
if (isXraySection(props)) { if (isXraySection(databases, isXrayEnabled)) {
return <HomeXraySection />; return <HomeXraySection />;
} }
return null; return null;
}; };
const isLoading = ({ const isLoading = (
user, user: User,
databases, databases: Database[] | undefined,
recentItems, recentItems: RecentItem[] | undefined,
popularItems, popularItems: PopularItem[] | undefined,
}: HomeContentProps): boolean => { ): boolean => {
if (!user.has_question_and_dashboard) { if (!user.has_question_and_dashboard) {
return databases == null; return databases == null;
} else if (user.is_installer || !isWithinWeeks(user.first_login, 1)) { } else if (user.is_installer || !isWithinWeeks(user.first_login, 1)) {
...@@ -50,11 +56,11 @@ const isLoading = ({ ...@@ -50,11 +56,11 @@ const isLoading = ({
} }
}; };
const isPopularSection = ({ const isPopularSection = (
user, user: User,
recentItems = [], recentItems: RecentItem[] = [],
popularItems = [], popularItems: PopularItem[] = [],
}: HomeContentProps): boolean => { ): boolean => {
return ( return (
!user.is_installer && !user.is_installer &&
user.has_question_and_dashboard && user.has_question_and_dashboard &&
...@@ -63,19 +69,16 @@ const isPopularSection = ({ ...@@ -63,19 +69,16 @@ const isPopularSection = ({
); );
}; };
const isRecentSection = ({ const isRecentSection = (
user, user: User,
recentItems = [], recentItems: RecentItem[] = [],
}: HomeContentProps): boolean => { ): boolean => {
return user.has_question_and_dashboard && recentItems.length > 0; return user.has_question_and_dashboard && recentItems.length > 0;
}; };
const isXraySection = ({ const isXraySection = (
databases = [], databases: Database[] = [],
isXrayEnabled, isXrayEnabled: boolean,
}: HomeContentProps): boolean => { ): boolean => {
return databases.some(isSyncCompleted) && isXrayEnabled; return databases.some(isSyncCompleted) && isXrayEnabled;
}; };
// eslint-disable-next-line import/no-default-export -- deprecated usage
export default HomeContent;
import { checkNotNull } from "metabase/core/utils/types";
import { getMetadata } from "metabase/selectors/metadata";
import { Database, PopularItem, RecentItem, User } from "metabase-types/api"; import { Database, PopularItem, RecentItem, User } from "metabase-types/api";
import { import {
createMockDatabase, createMockDatabase,
...@@ -7,19 +5,22 @@ import { ...@@ -7,19 +5,22 @@ import {
createMockRecentItem, createMockRecentItem,
createMockUser, createMockUser,
} from "metabase-types/api/mocks"; } from "metabase-types/api/mocks";
import { createMockState } from "metabase-types/store/mocks"; import {
import { createMockEntitiesState } from "__support__/store"; createMockSettingsState,
import { renderWithProviders, screen } from "__support__/ui"; createMockState,
import HomeContent from "./HomeContent"; } from "metabase-types/store/mocks";
import {
const PopularSectionMock = () => <div>PopularSection</div>; renderWithProviders,
jest.mock("../HomePopularSection", () => PopularSectionMock); screen,
waitForElementToBeRemoved,
const RecentSectionMock = () => <div>RecentSection</div>; } from "__support__/ui";
jest.mock("../HomeRecentSection", () => RecentSectionMock); import {
setupDatabaseCandidatesEndpoint,
const XraySectionMock = () => <div>XraySection</div>; setupDatabasesEndpoints,
jest.mock("../../containers/HomeXraySection", () => XraySectionMock); setupPopularItemsEndpoints,
setupRecentViewsEndpoints,
} from "__support__/server-mocks";
import { HomeContent } from "./HomeContent";
interface SetupOpts { interface SetupOpts {
user: User; user: User;
...@@ -29,35 +30,33 @@ interface SetupOpts { ...@@ -29,35 +30,33 @@ interface SetupOpts {
isXrayEnabled?: boolean; isXrayEnabled?: boolean;
} }
const setup = ({ const setup = async ({
user, user,
databases, databases = [],
recentItems, recentItems = [],
popularItems, popularItems = [],
isXrayEnabled = true, isXrayEnabled = true,
}: SetupOpts) => { }: SetupOpts) => {
const state = createMockState({ const state = createMockState({
entities: createMockEntitiesState({ databases }), currentUser: user,
settings: createMockSettingsState({
"enable-xrays": isXrayEnabled,
}),
}); });
const metadata = getMetadata(state);
setupDatabasesEndpoints(databases);
renderWithProviders( setupRecentViewsEndpoints(recentItems);
<HomeContent setupPopularItemsEndpoints(popularItems);
user={user} databases.forEach(({ id }) => setupDatabaseCandidatesEndpoint(id, []));
databases={databases?.map(({ id }) =>
checkNotNull(metadata.database(id)), renderWithProviders(<HomeContent />, { storeInitialState: state });
)}
recentItems={recentItems} await waitForElementToBeRemoved(() => screen.queryByText(/Loading/i));
popularItems={popularItems}
isXrayEnabled={isXrayEnabled}
/>,
{ storeInitialState: state },
);
}; };
describe("HomeContent", () => { describe("HomeContent", () => {
beforeEach(() => { beforeEach(() => {
jest.useFakeTimers(); jest.useFakeTimers({ advanceTimers: true });
jest.setSystemTime(new Date(2020, 0, 10)); jest.setSystemTime(new Date(2020, 0, 10));
}); });
...@@ -65,8 +64,8 @@ describe("HomeContent", () => { ...@@ -65,8 +64,8 @@ describe("HomeContent", () => {
jest.useRealTimers(); jest.useRealTimers();
}); });
it("should render popular items for a new user", () => { it("should render popular items for a new user", async () => {
setup({ await setup({
user: createMockUser({ user: createMockUser({
is_installer: false, is_installer: false,
has_question_and_dashboard: true, has_question_and_dashboard: true,
...@@ -77,26 +76,29 @@ describe("HomeContent", () => { ...@@ -77,26 +76,29 @@ describe("HomeContent", () => {
popularItems: [createMockPopularItem()], popularItems: [createMockPopularItem()],
}); });
expect(screen.getByText("PopularSection")).toBeInTheDocument(); expect(
screen.getByText("Here are some popular tables"),
).toBeInTheDocument();
}); });
it("should render popular items for a user without recent items", () => { it("should render popular items for a user without recent items", async () => {
setup({ await setup({
user: createMockUser({ user: createMockUser({
is_installer: false, is_installer: false,
has_question_and_dashboard: true, has_question_and_dashboard: true,
first_login: "2020-01-05T00:00:00Z", first_login: "2020-01-05T00:00:00Z",
}), }),
databases: [createMockDatabase()], databases: [createMockDatabase()],
recentItems: [],
popularItems: [createMockPopularItem()], popularItems: [createMockPopularItem()],
}); });
expect(screen.getByText("PopularSection")).toBeInTheDocument(); expect(
screen.getByText("Here are some popular tables"),
).toBeInTheDocument();
}); });
it("should render recent items for an existing user", () => { it("should render recent items for an existing user", async () => {
setup({ await setup({
user: createMockUser({ user: createMockUser({
is_installer: false, is_installer: false,
has_question_and_dashboard: true, has_question_and_dashboard: true,
...@@ -106,25 +108,24 @@ describe("HomeContent", () => { ...@@ -106,25 +108,24 @@ describe("HomeContent", () => {
recentItems: [createMockRecentItem()], recentItems: [createMockRecentItem()],
}); });
expect(screen.getByText("RecentSection")).toBeInTheDocument(); expect(screen.getByText("Pick up where you left off")).toBeInTheDocument();
}); });
it("should render x-rays for an installer after the setup", () => { it("should render x-rays for an installer after the setup", async () => {
setup({ await setup({
user: createMockUser({ user: createMockUser({
is_installer: true, is_installer: true,
has_question_and_dashboard: false, has_question_and_dashboard: false,
first_login: "2020-01-10T00:00:00Z", first_login: "2020-01-10T00:00:00Z",
}), }),
databases: [createMockDatabase()], databases: [createMockDatabase()],
recentItems: [],
}); });
expect(screen.getByText("XraySection")).toBeInTheDocument(); expect(screen.getByText(/Here are some explorations/)).toBeInTheDocument();
}); });
it("should render x-rays for the installer when there is no question and dashboard", () => { it("should render x-rays for the installer when there is no question and dashboard", async () => {
setup({ await setup({
user: createMockUser({ user: createMockUser({
is_installer: true, is_installer: true,
has_question_and_dashboard: false, has_question_and_dashboard: false,
...@@ -134,11 +135,11 @@ describe("HomeContent", () => { ...@@ -134,11 +135,11 @@ describe("HomeContent", () => {
recentItems: [createMockRecentItem()], recentItems: [createMockRecentItem()],
}); });
expect(screen.getByText("XraySection")).toBeInTheDocument(); expect(screen.getByText(/Here are some explorations/)).toBeInTheDocument();
}); });
it("should not render x-rays for the installer when there is no question and dashboard if the x-rays feature is disabled", () => { it("should not render x-rays for the installer when there is no question and dashboard if the x-rays feature is disabled", async () => {
setup({ await setup({
user: createMockUser({ user: createMockUser({
is_installer: true, is_installer: true,
has_question_and_dashboard: false, has_question_and_dashboard: false,
...@@ -149,33 +150,22 @@ describe("HomeContent", () => { ...@@ -149,33 +150,22 @@ describe("HomeContent", () => {
isXrayEnabled: false, isXrayEnabled: false,
}); });
expect(screen.queryByText("XraySection")).not.toBeInTheDocument(); expect(
}); screen.queryByText(/Here are some explorations/),
).not.toBeInTheDocument();
it("should render nothing if there are no databases", () => {
setup({
user: createMockUser({
is_installer: true,
has_question_and_dashboard: false,
first_login: "2020-01-10T00:00:00Z",
}),
databases: [],
recentItems: [],
});
expect(screen.queryByText("XraySection")).not.toBeInTheDocument();
}); });
it("should render loading state if there is not enough data to choose a section", () => { it("should render nothing if there are no databases", async () => {
setup({ await setup({
user: createMockUser({ user: createMockUser({
is_installer: true, is_installer: true,
has_question_and_dashboard: false, has_question_and_dashboard: false,
first_login: "2020-01-10T00:00:00Z", first_login: "2020-01-10T00:00:00Z",
}), }),
databases: undefined,
}); });
expect(screen.getByText("Loading...")).toBeInTheDocument(); expect(
screen.queryByText(/Here are some explorations/),
).not.toBeInTheDocument();
}); });
}); });
// eslint-disable-next-line import/no-default-export -- deprecated usage export * from "./HomeContent";
export { default } from "./HomeContent";
import { useMemo } from "react"; import { useMemo } from "react";
import { connect } from "react-redux";
import { t } from "ttag"; import { t } from "ttag";
import _ from "underscore"; import _ from "underscore";
import { useSelector } from "metabase/lib/redux";
import Tooltip from "metabase/core/components/Tooltip"; import Tooltip from "metabase/core/components/Tooltip";
import { getUser } from "metabase/selectors/user"; import { getUser } from "metabase/selectors/user";
import { getSetting } from "metabase/selectors/settings"; import { getHasMetabotLogo } from "../../selectors";
import { User } from "metabase-types/api";
import { State } from "metabase-types/store";
import { import {
GreetingLogo, GreetingLogo,
GreetingMessage, GreetingMessage,
GreetingRoot, GreetingRoot,
} from "./HomeGreeting.styled"; } from "./HomeGreeting.styled";
interface StateProps { export const HomeGreeting = (): JSX.Element => {
user: User | null; const user = useSelector(getUser);
showLogo?: boolean; const showLogo = useSelector(getHasMetabotLogo);
}
type HomeGreetingProps = StateProps;
const mapStateToProps = (state: State): StateProps => ({
user: getUser(state),
showLogo: getSetting(state, "show-metabot"),
});
const HomeGreeting = ({ user, showLogo }: HomeGreetingProps): JSX.Element => {
const name = user?.first_name; const name = user?.first_name;
const message = useMemo(() => getMessage(name), [name]); const message = useMemo(() => getMessage(name), [name]);
...@@ -56,6 +44,3 @@ const getMessage = (name: string | null | undefined): string => { ...@@ -56,6 +44,3 @@ const getMessage = (name: string | null | undefined): string => {
return _.sample(options) ?? ""; return _.sample(options) ?? "";
}; };
// eslint-disable-next-line import/no-default-export -- deprecated usage
export default connect(mapStateToProps)(HomeGreeting);
...@@ -5,7 +5,7 @@ import { ...@@ -5,7 +5,7 @@ import {
createMockSettingsState, createMockSettingsState,
createMockState, createMockState,
} from "metabase-types/store/mocks"; } from "metabase-types/store/mocks";
import HomeGreeting from "./HomeGreeting"; import { HomeGreeting } from "./HomeGreeting";
interface SetupOpts { interface SetupOpts {
currentUser?: User; currentUser?: User;
......
// eslint-disable-next-line import/no-default-export -- deprecated usage export * from "./HomeGreeting";
export { default } from "./HomeGreeting";
...@@ -2,7 +2,7 @@ import { t } from "ttag"; ...@@ -2,7 +2,7 @@ import { t } from "ttag";
import MetabaseSettings from "metabase/lib/settings"; import MetabaseSettings from "metabase/lib/settings";
import { CardIcon, CardRoot, CardTitle } from "./HomeHelpCard.styled"; import { CardIcon, CardRoot, CardTitle } from "./HomeHelpCard.styled";
const HomeHelpCard = (): JSX.Element => { export const HomeHelpCard = (): JSX.Element => {
return ( return (
<CardRoot href={MetabaseSettings.learnUrl()}> <CardRoot href={MetabaseSettings.learnUrl()}>
<CardIcon name="reference" /> <CardIcon name="reference" />
...@@ -10,6 +10,3 @@ const HomeHelpCard = (): JSX.Element => { ...@@ -10,6 +10,3 @@ const HomeHelpCard = (): JSX.Element => {
</CardRoot> </CardRoot>
); );
}; };
// eslint-disable-next-line import/no-default-export -- deprecated usage
export default HomeHelpCard;
import { render, screen } from "@testing-library/react"; import { render, screen } from "__support__/ui";
import HomeHelpCard from "./HomeHelpCard"; import { HomeHelpCard } from "./HomeHelpCard";
const setup = () => {
render(<HomeHelpCard />);
};
describe("HomeHelpCard", () => { describe("HomeHelpCard", () => {
it("should render correctly", () => { it("should render correctly", () => {
render(<HomeHelpCard />); setup();
expect(screen.getByText("Metabase tips")).toBeInTheDocument(); expect(screen.getByText("Metabase tips")).toBeInTheDocument();
}); });
}); });
// eslint-disable-next-line import/no-default-export -- deprecated usage export * from "./HomeHelpCard";
export { default } from "./HomeHelpCard";
import { ReactNode, useState } from "react"; import { ReactNode, useState } from "react";
import { connect } from "react-redux"; import { useSelector } from "metabase/lib/redux";
import { getSetting } from "metabase/selectors/settings";
import { getUserIsAdmin } from "metabase/selectors/user"; import { getUserIsAdmin } from "metabase/selectors/user";
import MetabotWidget from "metabase/metabot/components/MetabotWidget"; import MetabotWidget from "metabase/metabot/components/MetabotWidget";
import { State } from "metabase-types/store";
import Tooltip from "metabase/core/components/Tooltip/Tooltip"; import Tooltip from "metabase/core/components/Tooltip/Tooltip";
import HomeGreeting from "../HomeGreeting"; import { HomeGreeting } from "../HomeGreeting";
import { CustomHomePageModal } from "../Modals/CustomHomePageModal/CustomHomePageModal"; import { getHasIllustration } from "../../selectors";
import { CustomHomePageModal } from "../CustomHomePageModal";
import { import {
LayoutBody, LayoutBody,
LayoutEditButton, LayoutEditButton,
...@@ -14,30 +13,18 @@ import { ...@@ -14,30 +13,18 @@ import {
LayoutRoot, LayoutRoot,
} from "./HomeLayout.styled"; } from "./HomeLayout.styled";
interface OwnProps { interface HomeLayoutProps {
hasMetabot?: boolean; hasMetabot: boolean;
children?: ReactNode; children?: ReactNode;
} }
interface StateProps { export const HomeLayout = ({
hasIllustration?: boolean;
isAdmin?: boolean;
}
type HomeLayoutProps = OwnProps & StateProps;
const mapStateToProps = (state: State) => ({
hasIllustration: getSetting(state, "show-lighthouse-illustration"),
isAdmin: getUserIsAdmin(state),
});
const HomeLayout = ({
hasMetabot, hasMetabot,
hasIllustration,
children, children,
isAdmin,
}: HomeLayoutProps): JSX.Element => { }: HomeLayoutProps): JSX.Element => {
const [showModal, setShowModal] = useState(false); const [showModal, setShowModal] = useState(false);
const isAdmin = useSelector(getUserIsAdmin);
const hasIllustration = useSelector(getHasIllustration);
return ( return (
<LayoutRoot> <LayoutRoot>
...@@ -62,6 +49,3 @@ const HomeLayout = ({ ...@@ -62,6 +49,3 @@ const HomeLayout = ({
</LayoutRoot> </LayoutRoot>
); );
}; };
// eslint-disable-next-line import/no-default-export -- deprecated usage
export default connect(mapStateToProps)(HomeLayout);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment