diff --git a/frontend/src/metabase/models/containers/NewModelOptions/NewModelOptions.tsx b/frontend/src/metabase/models/containers/NewModelOptions/NewModelOptions.tsx index c23ed0be4c73de2bcda8c1821c5b1d15f0b3d37f..bf9b6cdb5e0b99371ad5ae40fddece4da10ce520 100644 --- a/frontend/src/metabase/models/containers/NewModelOptions/NewModelOptions.tsx +++ b/frontend/src/metabase/models/containers/NewModelOptions/NewModelOptions.tsx @@ -4,6 +4,7 @@ import { t } from "ttag"; import _ from "underscore"; import { useListDatabasesQuery } from "metabase/api"; +import { DelayedLoadingSpinner } from "metabase/common/components/EntityPicker/components/LoadingSpinner"; import { Grid } from "metabase/components/Grid"; import CS from "metabase/css/core/index.css"; import Databases from "metabase/entities/databases"; @@ -29,7 +30,7 @@ interface NewModelOptionsProps { } const NewModelOptions = ({ location }: NewModelOptionsProps) => { - const { data } = useListDatabasesQuery(); + const { data, isFetching } = useListDatabasesQuery(); const databases = data?.data ?? []; const hasDataAccess = getHasDataAccess(databases); const hasNativeWrite = getHasNativeWrite(databases); @@ -44,6 +45,10 @@ const NewModelOptions = ({ location }: NewModelOptionsProps) => { const showMetabaseLinks = useSelector(getShowMetabaseLinks); + if (isFetching) { + return <DelayedLoadingSpinner />; + } + if (!hasDataAccess && !hasNativeWrite) { return ( <div diff --git a/frontend/src/metabase/models/containers/NewModelOptions/tests/common.unit.spec.tsx b/frontend/src/metabase/models/containers/NewModelOptions/tests/common.unit.spec.tsx index 35ab0754a895a27623960d9213f42fc22256667d..64ba105dfe1392bb1a3fd213abef49a813ff467c 100644 --- a/frontend/src/metabase/models/containers/NewModelOptions/tests/common.unit.spec.tsx +++ b/frontend/src/metabase/models/containers/NewModelOptions/tests/common.unit.spec.tsx @@ -1,4 +1,7 @@ +import fetchMock from "fetch-mock"; + import { screen } from "__support__/ui"; +import { delay } from "metabase/lib/promise"; import { createMockDatabase } from "metabase-types/api/mocks"; import { setup } from "./setup"; @@ -13,6 +16,25 @@ describe("NewModelOptions (OSS)", () => { }); describe("has data access", () => { + it("should render loading indicator when fetching databases (metabase#44813)", async () => { + // Mocking the response needs to happen before the setup + // because setup already instantiates the component - it contains `renderWithProviders`. + fetchMock.get( + "path:/api/database", + delay(2000).then(() => { + return [createMockDatabase()]; + }), + { overwriteRoutes: true }, + ); + + setup({ databases: [createMockDatabase()] }); + + expect(await screen.findByTestId("loading-spinner")).toBeInTheDocument(); + expect( + screen.queryByText("Metabase is no fun without any data"), + ).not.toBeInTheDocument(); + }); + it("should render options for creating a model", async () => { setup({ databases: [createMockDatabase()] });