diff --git a/enterprise/frontend/src/embedding-sdk/components/private/AppInitializeController.tsx b/enterprise/frontend/src/embedding-sdk/components/private/AppInitializeController.tsx
new file mode 100644
index 0000000000000..7ac7a0505326a
--- /dev/null
+++ b/enterprise/frontend/src/embedding-sdk/components/private/AppInitializeController.tsx
@@ -0,0 +1,48 @@
+import type * as React from "react";
+import { useEffect } from "react";
+import { t } from "ttag";
+
+import { useDispatch } from "metabase/lib/redux";
+import { setOptions } from "metabase/redux/embed";
+
+import { EmbeddingContext } from "../../context";
+import { useInitData } from "../../hooks";
+import type { SDKConfigType } from "../../types";
+
+import { SdkContentWrapper } from "./SdkContentWrapper";
+
+interface AppInitializeControllerProps {
+ children: React.ReactNode;
+ config: SDKConfigType;
+}
+
+export const AppInitializeController = ({
+ config,
+ children,
+}: AppInitializeControllerProps) => {
+ const { isLoggedIn, isInitialized } = useInitData({
+ config,
+ });
+ const dispatch = useDispatch();
+
+ const font = config.font ?? "Lato";
+
+ useEffect(() => {
+ if (font) {
+ dispatch(setOptions({ font }));
+ }
+ }, [dispatch, font]);
+
+ return (
+
+
+ {!isInitialized ? {t`Loading…`}
: children}
+
+
+ );
+};
diff --git a/enterprise/frontend/src/embedding-sdk/components/SdkContentWrapper.tsx b/enterprise/frontend/src/embedding-sdk/components/private/SdkContentWrapper.tsx
similarity index 100%
rename from enterprise/frontend/src/embedding-sdk/components/SdkContentWrapper.tsx
rename to enterprise/frontend/src/embedding-sdk/components/private/SdkContentWrapper.tsx
diff --git a/enterprise/frontend/src/embedding-sdk/components/public/MetabaseProvider.tsx b/enterprise/frontend/src/embedding-sdk/components/public/MetabaseProvider.tsx
index f437f2d95e059..243024f557cdd 100644
--- a/enterprise/frontend/src/embedding-sdk/components/public/MetabaseProvider.tsx
+++ b/enterprise/frontend/src/embedding-sdk/components/public/MetabaseProvider.tsx
@@ -1,20 +1,21 @@
+import type { AnyAction, Store } from "@reduxjs/toolkit";
import type * as React from "react";
-import { memo, useEffect, useState } from "react";
+import { memo } from "react";
import { Provider } from "react-redux";
import reducers from "metabase/reducers-main";
-import { setOptions } from "metabase/redux/embed";
import { getStore } from "metabase/store";
import { EmotionCacheProvider } from "metabase/styled-components/components/EmotionCacheProvider";
import { ThemeProvider } from "metabase/ui/components/theme/ThemeProvider";
+import type { State } from "metabase-types/store";
-import type { SDKConfigType } from "../../config";
-import { EmbeddingContext } from "../../context";
-import { useInitData } from "../../hooks";
-import { SdkContentWrapper } from "../SdkContentWrapper";
+import type { SDKConfigType } from "../../types";
+import { AppInitializeController } from "../private/AppInitializeController";
import "metabase/css/vendor.css";
-import "../../styles.css";
+import "metabase/css/index.module.css";
+
+const store = getStore(reducers) as unknown as Store;
const MetabaseProviderInternal = ({
children,
@@ -22,42 +23,17 @@ const MetabaseProviderInternal = ({
}: {
children: React.ReactNode;
config: SDKConfigType;
-}): JSX.Element => {
- const store = getStore(reducers);
-
- const [font, setFont] = useState(config.font ?? "Lato");
-
- useEffect(() => {
- if (font) {
- store.dispatch(setOptions({ font }));
- }
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [font]);
-
- const { isLoggedIn, isInitialized } = useInitData({
- store,
- config,
- });
-
+}): React.JSX.Element => {
return (
-
-
-
-
-
- {!isInitialized ? Initializing...
: children}
-
-
-
-
-
+
+
+
+
+ {children}
+
+
+
+
);
};
diff --git a/enterprise/frontend/src/embedding-sdk/components/public/QueryVisualization.tsx b/enterprise/frontend/src/embedding-sdk/components/public/QueryVisualization.tsx
index d9d06a09e4908..5289b6dea824a 100644
--- a/enterprise/frontend/src/embedding-sdk/components/public/QueryVisualization.tsx
+++ b/enterprise/frontend/src/embedding-sdk/components/public/QueryVisualization.tsx
@@ -16,7 +16,7 @@ import { PublicMode } from "metabase/visualizations/click-actions/modes/PublicMo
import Question from "metabase-lib/v1/Question";
import type { Card, CardId, Dataset } from "metabase-types/api";
-import { useEmbeddingContext } from "../../hooks";
+import { useEmbeddingContext } from "../../context";
interface QueryVisualizationProps {
questionId: CardId;
@@ -37,7 +37,7 @@ export const QueryVisualizationSdk = (
const { questionId } = props;
- const [state, setState] = useState({
+ const [{ loading, card, result }, setState] = useState({
loading: false,
card: null,
result: null,
@@ -85,12 +85,10 @@ export const QueryVisualizationSdk = (
loadCardData({ questionId });
}, [isInitialized, isLoggedIn, questionId]);
- const { card, result } = state;
-
const changeVisualization = (newQuestion: Question) => {
setState({
card: newQuestion.card(),
- result: state.result,
+ result: result,
loading: false,
});
};
@@ -108,10 +106,12 @@ export const QueryVisualizationSdk = (
);
}
+ const isLoading = loading || !result;
+
return (
@@ -140,7 +140,7 @@ export const QueryVisualizationSdk = (
className="flex full-width"
question={question}
rawSeries={[{ card, data: result && result.data }]}
- isRunning={state.loading}
+ isRunning={isLoading}
isObjectDetail={false}
isResultDirty={false}
isNativeEditorOpen={false}
diff --git a/enterprise/frontend/src/embedding-sdk/context.ts b/enterprise/frontend/src/embedding-sdk/context.ts
index c994702acc11c..bac2f6c52704c 100644
--- a/enterprise/frontend/src/embedding-sdk/context.ts
+++ b/enterprise/frontend/src/embedding-sdk/context.ts
@@ -3,15 +3,11 @@ import { createContext, useContext } from "react";
interface EmbeddingSdkContextData {
isInitialized: boolean;
isLoggedIn: boolean;
- font: string | null;
- setFont: (font: string) => void;
}
export const EmbeddingContext = createContext({
isInitialized: false,
isLoggedIn: false,
- font: null,
- setFont: () => {},
});
export const useEmbeddingContext = () => {
diff --git a/enterprise/frontend/src/embedding-sdk/hooks/private/index.ts b/enterprise/frontend/src/embedding-sdk/hooks/private/index.ts
index 98b2c2700e921..a159167a9e0ba 100644
--- a/enterprise/frontend/src/embedding-sdk/hooks/private/index.ts
+++ b/enterprise/frontend/src/embedding-sdk/hooks/private/index.ts
@@ -1,2 +1 @@
-export * from "./use-sdk-context";
export * from "./use-init-data";
diff --git a/enterprise/frontend/src/embedding-sdk/hooks/private/use-init-data.ts b/enterprise/frontend/src/embedding-sdk/hooks/private/use-init-data.ts
index b479f80bab7cc..8bd756e440061 100644
--- a/enterprise/frontend/src/embedding-sdk/hooks/private/use-init-data.ts
+++ b/enterprise/frontend/src/embedding-sdk/hooks/private/use-init-data.ts
@@ -3,25 +3,25 @@ import _ from "underscore";
import { reloadSettings } from "metabase/admin/settings/settings";
import api from "metabase/lib/api";
+import { useDispatch } from "metabase/lib/redux";
import { refreshCurrentUser } from "metabase/redux/user";
import registerVisualizations from "metabase/visualizations/register";
-import type { SDKConfigType } from "../../config";
+import type { SDKConfigType } from "../../types";
const registerVisualizationsOnce = _.once(registerVisualizations);
-type InitDataLoaderProps = {
- store: any;
+interface InitDataLoaderParameters {
config: SDKConfigType;
-};
+}
export const useInitData = ({
- store,
config,
-}: InitDataLoaderProps): {
+}: InitDataLoaderParameters): {
isLoggedIn: boolean;
isInitialized: boolean;
} => {
+ const dispatch = useDispatch();
const [isInitialized, setIsInitialized] = useState(false);
const [isLoggedIn, setIsLoggedIn] = useState(false);
@@ -40,13 +40,13 @@ export const useInitData = ({
}
Promise.all([
- store.dispatch(refreshCurrentUser()),
- store.dispatch(reloadSettings()),
+ dispatch(refreshCurrentUser()),
+ dispatch(reloadSettings()),
]).then(() => {
setIsInitialized(true);
setIsLoggedIn(true);
});
- }, [config, store]);
+ }, [config, dispatch]);
return {
isLoggedIn,
diff --git a/enterprise/frontend/src/embedding-sdk/hooks/private/use-sdk-context.ts b/enterprise/frontend/src/embedding-sdk/hooks/private/use-sdk-context.ts
deleted file mode 100644
index 5896863a232aa..0000000000000
--- a/enterprise/frontend/src/embedding-sdk/hooks/private/use-sdk-context.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { useContext } from "react";
-
-import { EmbeddingContext } from "../../context";
-
-export const useEmbeddingContext = () => {
- return useContext(EmbeddingContext);
-};
diff --git a/enterprise/frontend/src/embedding-sdk/hooks/public/use-available-fonts.ts b/enterprise/frontend/src/embedding-sdk/hooks/public/use-available-fonts.ts
index a0e157c838eca..9253cc8c95fce 100644
--- a/enterprise/frontend/src/embedding-sdk/hooks/public/use-available-fonts.ts
+++ b/enterprise/frontend/src/embedding-sdk/hooks/public/use-available-fonts.ts
@@ -1,14 +1,10 @@
import { useSelector } from "metabase/lib/redux";
+import { getEmbedOptions } from "metabase/selectors/embed";
import { getSetting } from "metabase/selectors/settings";
-import { useEmbeddingContext } from "../../hooks/private/use-sdk-context";
-
export const useAvailableFonts = () => {
- const { font, setFont } = useEmbeddingContext();
-
return {
availableFonts: useSelector(state => getSetting(state, "available-fonts")),
- currentFont: font,
- setFont,
+ currentFont: useSelector(getEmbedOptions)?.font,
};
};
diff --git a/enterprise/frontend/src/embedding-sdk/hooks/public/use-question-search.ts b/enterprise/frontend/src/embedding-sdk/hooks/public/use-question-search.ts
index 7f72f345373b0..699f12c8c60b6 100644
--- a/enterprise/frontend/src/embedding-sdk/hooks/public/use-question-search.ts
+++ b/enterprise/frontend/src/embedding-sdk/hooks/public/use-question-search.ts
@@ -2,7 +2,7 @@ import { useMemo } from "react";
import { useSearchListQuery } from "metabase/common/hooks";
-import { useEmbeddingContext } from "../private/use-sdk-context";
+import { useEmbeddingContext } from "../../context";
export const useQuestionSearch = (searchQuery?: string) => {
const { isInitialized, isLoggedIn } = useEmbeddingContext();
diff --git a/enterprise/frontend/src/embedding-sdk/styles.css b/enterprise/frontend/src/embedding-sdk/styles.css
deleted file mode 100644
index d7e71512b9a92..0000000000000
--- a/enterprise/frontend/src/embedding-sdk/styles.css
+++ /dev/null
@@ -1 +0,0 @@
-@import "../../../../frontend/src/metabase/css/index.module.css";
diff --git a/enterprise/frontend/src/embedding-sdk/config.ts b/enterprise/frontend/src/embedding-sdk/types.ts
similarity index 100%
rename from enterprise/frontend/src/embedding-sdk/config.ts
rename to enterprise/frontend/src/embedding-sdk/types.ts