import React, { createContext, useMemo } from 'react' import { useSelector } from 'react-redux' import { getFormSelector, getFormHasNonUniqueDataTagsSelector, getFormHasWrongNotificationEmailsSelector, } from '@epicformbuilder/admin/data' import PluginsLoader from '@epicformbuilder/common/services/PluginsLoader' export type ConfigurationWatchContextType = { hasNonUniqueDataTags: boolean hasWrongNotificationEmails: boolean /** Messages from add-on `validate()`; non-empty blocks Publish and Preview. */ addonErrors: string[] } type ConfigurationWatchContextProviderProps = { children: React.ReactNode } type FormComponent = { component: string } type EditorForm = { steps: Array<{ fields: FormComponent[] }>, actions: FormComponent[] } /** Runs one component's add-on `validate()`, surfacing a throw as a message instead of blanking the editor. */ const validateAddon = ( form: EditorForm, component: string ): string | null => { const validate = PluginsLoader.getEditorPart( component )?.validate if ( ! validate ) return null try { return validate( form ) ?? null } catch ( error ) { console.error( `EpicForms: validator for "${ component }" failed`, error ) return `"${ component }" could not be validated. Check the add-on is up to date.` } } /** Runs each add-on component's own validation against the whole form. */ export const getAddonErrors = ( form: EditorForm ): string[] => [ ...form.steps.flatMap( s => s.fields ), ...form.actions ] .map( c => validateAddon( form, c.component ) ) .filter( Boolean ) as string[] const ConfigurationWatchContext = createContext( null ); const ConfigurationWatchContextProvider = ({ children }: ConfigurationWatchContextProviderProps ) => { const form = useSelector( getFormSelector ) as EditorForm const hasNonUniqueDataTags = useSelector( getFormHasNonUniqueDataTagsSelector ) const hasWrongNotificationEmails = useSelector( getFormHasWrongNotificationEmailsSelector ) const addonErrors = useMemo( () => getAddonErrors( form ), [ form ] ) return ( { children } ) } export { ConfigurationWatchContext, ConfigurationWatchContextProvider }