Skip to content
Snippets Groups Projects
MetabaseProvider.tsx 3.69 KiB
Newer Older
  • Learn to ignore specific revisions
  • import type { Action, Store } from "@reduxjs/toolkit";
    
    import { type JSX, type ReactNode, memo, useEffect } from "react";
    
    import { Provider } from "react-redux";
    
    
    import { SdkThemeProvider } from "embedding-sdk/components/private/SdkThemeProvider";
    
    import {
      EMBEDDING_SDK_PORTAL_ROOT_ELEMENT_ID,
      EMBEDDING_SDK_ROOT_ELEMENT_ID,
    } from "embedding-sdk/config";
    import { useInitData } from "embedding-sdk/hooks";
    
    import type { SdkEventHandlersConfig } from "embedding-sdk/lib/events";
    
    import type { SdkPluginsConfig } from "embedding-sdk/lib/plugins";
    
    import { store } from "embedding-sdk/store";
    
    import {
      setErrorComponent,
    
      setMetabaseClientUrl,
    
      setPlugins,
    } from "embedding-sdk/store/reducer";
    
    import type { SdkStoreState } from "embedding-sdk/store/types";
    
    import type { SDKConfig } from "embedding-sdk/types";
    
    import type { MetabaseTheme } from "embedding-sdk/types/theme";
    
    import { setOptions } from "metabase/redux/embed";
    
    import { EmotionCacheProvider } from "metabase/styled-components/components/EmotionCacheProvider";
    
    
    import { PublicComponentStylesWrapper } from "../private/PublicComponentStylesWrapper";
    
    import { SdkFontsGlobalStyles } from "../private/SdkGlobalFontsStyles";
    
    import "metabase/css/index.module.css";
    
    import { SdkUsageProblemDisplay } from "../private/SdkUsageProblem";
    
    import "metabase/css/vendor.css";
    
    export interface MetabaseProviderProps {
    
      children: ReactNode;
    
      config: SDKConfig;
    
      pluginsConfig?: SdkPluginsConfig;
    
      eventHandlers?: SdkEventHandlersConfig;
    
    interface InternalMetabaseProviderProps extends MetabaseProviderProps {
      store: Store<SdkStoreState, Action>;
    }
    
    export const MetabaseProviderInternal = ({
    
      pluginsConfig,
    
    }: InternalMetabaseProviderProps): JSX.Element => {
    
      const { fontFamily } = theme ?? {};
      useInitData({ config });
    
        if (fontFamily) {
          store.dispatch(setOptions({ font: fontFamily }));
    
      useEffect(() => {
        store.dispatch(setPlugins(pluginsConfig || null));
    
      useEffect(() => {
        store.dispatch(setEventHandlers(eventHandlers || null));
      }, [store, eventHandlers]);
    
    
      useEffect(() => {
        store.dispatch(setLoaderComponent(config.loaderComponent ?? null));
    
      }, [store, config.loaderComponent]);
    
    
      useEffect(() => {
        store.dispatch(setErrorComponent(config.errorComponent ?? null));
    
      }, [store, config.errorComponent]);
    
      useEffect(() => {
        store.dispatch(setMetabaseClientUrl(config.metabaseInstanceUrl));
    
      }, [store, config.metabaseInstanceUrl]);
    
      return (
    
        <EmotionCacheProvider>
          <SdkThemeProvider theme={theme}>
            <SdkFontsGlobalStyles baseUrl={config.metabaseInstanceUrl} />
            <div className={className} id={EMBEDDING_SDK_ROOT_ELEMENT_ID}>
              <PortalContainer />
              {children}
    
            </div>
          </SdkThemeProvider>
        </EmotionCacheProvider>
    
    export const MetabaseProvider = memo(function MetabaseProvider(
      props: MetabaseProviderProps,
    ) {
    
      return (
        <Provider store={store}>
          <MetabaseProviderInternal store={store} {...props} />
        </Provider>
      );
    
     * This is the portal container used by popovers modals etc, it is wrapped with PublicComponentStylesWrapper
    
     * so that it has our styles applied.
     * Mantine components needs to have the defaultProps set to use `EMBEDDING_SDK_PORTAL_CONTAINER_ELEMENT_ID` as target for the portal
     */
    const PortalContainer = () => (
    
        <div id={EMBEDDING_SDK_PORTAL_ROOT_ELEMENT_ID}></div>