libs/designer/src/lib/core/DesignerProvider.tsx (72 lines of code) (raw):

import { resetWorkflowState } from '.'; import { ProviderWrappedContext } from './ProviderWrappedContext'; import type { DesignerOptionsState, ServiceOptions } from './state/designerOptions/designerOptionsInterfaces'; import { initDesignerOptions } from './state/designerOptions/designerOptionsSlice'; import { store } from './store'; import { AzureThemeDark } from '@fluentui/azure-themes/lib/azure/AzureThemeDark'; import { AzureThemeLight } from '@fluentui/azure-themes/lib/azure/AzureThemeLight'; import { ThemeProvider } from '@fluentui/react'; import { FluentProvider, webDarkTheme, webLightTheme } from '@fluentui/react-components'; import type { OnErrorFn as OnIntlErrorFn } from '@formatjs/intl'; import { IntlProvider } from '@microsoft/logic-apps-shared'; import type React from 'react'; import { useCallback, useEffect, useMemo } from 'react'; import { Provider as ReduxProvider, useDispatch } from 'react-redux'; export interface DesignerProviderProps { key?: string; id?: string; locale?: string; options: Omit<DesignerOptionsState, 'servicesInitialized'> & { services: ServiceOptions }; children: React.ReactNode; } const OptionsStateSet = ({ options, children }: any) => { const dispatch = useDispatch(); useEffect(() => { if (!options) { return; } dispatch(initDesignerOptions(options)); }, [dispatch, options]); return <>{children}</>; }; export const DesignerProvider = ({ id, locale = 'en', options, children }: DesignerProviderProps) => { const { isDarkMode } = options; const azTheme = isDarkMode ? AzureThemeDark : AzureThemeLight; const webTheme = isDarkMode ? webDarkTheme : webLightTheme; const themeName = useMemo(() => (isDarkMode ? 'dark' : 'light'), [isDarkMode]); const onError = useCallback<OnIntlErrorFn>((err) => { if (err.code === 'MISSING_TRANSLATION' || err.code === 'MISSING_DATA') { console.error(`IntlProvider error ${err.code} - ${err.message} - ${err.stack}`); return; } throw err; }, []); return ( <ReduxProvider store={store}> <OptionsStateSet options={options}> <ProviderWrappedContext.Provider value={options.services}> <ThemeProvider theme={azTheme} style={{ height: 'inherit' }}> <FluentProvider theme={webTheme} style={{ height: 'inherit' }}> <div data-color-scheme={themeName} className={`msla-theme-${themeName}`} style={{ display: 'flex', flexDirection: 'column', height: 'inherit', overflow: 'hidden' }} > <IntlProvider locale={locale} defaultLocale={locale} stringOverrides={options.hostOptions.stringOverrides} onError={onError} > <ReduxReset id={id} /> {children} </IntlProvider> </div> </FluentProvider> </ThemeProvider> </ProviderWrappedContext.Provider> </OptionsStateSet> </ReduxProvider> ); }; // Redux state persists even through component re-mounts (like with changing the key prop in a parent), so we need to reset the state when the key changes manually const ReduxReset = ({ id }: { id?: string }) => { const dispatch = useDispatch(); useEffect(() => { dispatch(resetWorkflowState()); }, [id, dispatch]); return null; };