diff --git a/.changeset/tall-dolphins-laugh.md b/.changeset/tall-dolphins-laugh.md new file mode 100644 index 00000000..27e94e2f --- /dev/null +++ b/.changeset/tall-dolphins-laugh.md @@ -0,0 +1,5 @@ +--- +'@flatfile/react': patch +--- + +Fix bug with Workbook onSubmit diff --git a/.gitignore b/.gitignore index 2d8273bb..5f347843 100644 --- a/.gitignore +++ b/.gitignore @@ -135,4 +135,5 @@ dist .flatfile .flatfilerc.json -*.code-workspace \ No newline at end of file +*.code-workspace +.aider* diff --git a/apps/react/app/App.tsx b/apps/react/app/App.tsx index f1ec1bfb..bec1e0ab 100644 --- a/apps/react/app/App.tsx +++ b/apps/react/app/App.tsx @@ -132,8 +132,13 @@ const App = () => { record.set('email', 'SHEET 3 RECORDHOOK') return record }} - onSubmit={async (sheet) => { - console.log('onSubmit from Sheet 3', { sheet }) + onSubmit={{ + handler: async (sheet) => { + console.log('onSubmit from Sheet 3', { sheet }) + }, + config: { + label: 'Sheet 3 Submit', + }, }} /> { + const [spaceId, setSpaceId] = useState(null) + const { space, loading, error } = useSpace({ + name: 'Reusable Space Example', + publishableKey: 'YOUR_PUBLISHABLE_KEY', + environmentId: 'YOUR_ENVIRONMENT_ID', + spaceId: spaceId, + }) + + const handleCreateSpace = async () => { + if (space) { + const newSpace = await space.create() + setSpaceId(newSpace.id) + } + } + + const handleOpenSpace = () => { + if (space) { + space.open() + } + } + + if (loading) return
Loading...
+ if (error) return
Error: {error.message}
+ + return ( +
+

Reusable Space Example

+ + + {spaceId &&

Space ID: {spaceId}

} +
+ ) +} + +export default ReusableSpaceExample diff --git a/apps/react/app/reuse-space-example/index.tsx b/apps/react/app/reuse-space-example/index.tsx new file mode 100644 index 00000000..d5d124d8 --- /dev/null +++ b/apps/react/app/reuse-space-example/index.tsx @@ -0,0 +1,3 @@ +import ReusableSpaceExample from './ReusableSpaceExample' + +export default ReusableSpaceExample diff --git a/package.json b/package.json index 97eb32d0..68ec96e2 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "format": "prettier --ignore-path .gitignore --write \"**/*.{js,jsx,ts,tsx,md}\"", "changeset": "changeset", "changeset-apply": "changeset version", - "release": "turbo run build && changeset publish" + "release": "turbo run build && changeset publish", + "example:reuse-space": "npm run example:reuse-space -w apps/react/app" }, "devDependencies": { "@changesets/cli": "^2.23.0", diff --git a/packages/react/src/components/FlatfileProvider.tsx b/packages/react/src/components/FlatfileProvider.tsx index de45e589..d176ae51 100644 --- a/packages/react/src/components/FlatfileProvider.tsx +++ b/packages/react/src/components/FlatfileProvider.tsx @@ -52,6 +52,7 @@ export const FlatfileProvider: React.FC = ({ const [internalAccessToken, setInternalAccessToken] = useState< string | undefined | null >(accessToken) + const [listener, setListener] = useState(new FlatfileListener()) const [open, setOpen] = useState(false) const [sessionSpace, setSessionSpace] = useState< @@ -166,7 +167,9 @@ export const FlatfileProvider: React.FC = ({ defaultPage.current = undefined } - const sheetWorkbookAction = workbookOnSubmitAction(sheetToRemove.slug) + const sheetWorkbookAction = workbookOnSubmitAction({ + sheetSlug: sheetToRemove.slug, + }) const updatedWorkbookActions = prevSpace.workbook?.actions?.filter( (action) => action.operation !== sheetWorkbookAction.operation diff --git a/packages/react/src/components/Sheet.tsx b/packages/react/src/components/Sheet.tsx index 2967b4fb..e81dea9b 100644 --- a/packages/react/src/components/Sheet.tsx +++ b/packages/react/src/components/Sheet.tsx @@ -10,10 +10,11 @@ import { useEvent, usePlugin } from '../hooks' import { OnSubmitAction, workbookOnSubmitAction } from '../utils/constants' import { useDeepCompareEffect } from '../utils/useDeepCompareEffect' import FlatfileContext from './FlatfileContext' +import { OnSubmitActionWithConfig } from './Workbook' type SheetProps = { config: Flatfile.SheetConfig - onSubmit?: SimpleOnboarding['onSubmit'] + onSubmit?: SimpleOnboarding['onSubmit'] | OnSubmitActionWithConfig submitSettings?: SimpleOnboarding['submitSettings'] onRecordHook?: SimpleOnboarding['onRecordHook'] defaultPage?: boolean @@ -68,16 +69,20 @@ export const Sheet: React.FC = (props: SheetProps) => { const { addSheet, updateWorkbook, createSpace, setDefaultPage, removeSheet } = useContext(FlatfileContext) const sheetRef = useRef() - + useDeepCompareEffect(() => { const updateSheetConfig = () => { sheetRef.current = config - if (onSubmit && !createSpace.workbook?.actions?.some( - (action: Flatfile.Action) => - action.operation === workbookOnSubmitAction(config.slug).operation - )) { + if ( + onSubmit && + !createSpace.workbook?.actions?.some( + (action: Flatfile.Action) => + action.operation === + workbookOnSubmitAction({ sheetSlug: config.slug, config: 'config' in onSubmit ? onSubmit.config : undefined }).operation + ) + ) { updateWorkbook({ - actions: [workbookOnSubmitAction(config.slug)], + actions: [workbookOnSubmitAction({ sheetSlug: config.slug, config: 'config' in onSubmit ? onSubmit.config : undefined })], }) } addSheet(config) @@ -90,7 +95,10 @@ export const Sheet: React.FC = (props: SheetProps) => { } } - if (!sheetRef.current || (sheetRef.current.slug && sheetRef.current.slug !== config.slug)) { + if ( + !sheetRef.current || + (sheetRef.current.slug && sheetRef.current.slug !== config.slug) + ) { if (sheetRef.current?.slug) { removeSheet(sheetRef.current.slug) } @@ -120,7 +128,11 @@ export const Sheet: React.FC = (props: SheetProps) => { useEvent( 'job:ready', - { job: `workbook:${workbookOnSubmitAction(config.slug).operation}` }, + { + job: `workbook:${ + workbookOnSubmitAction({ sheetSlug: config.slug }).operation + }`, + }, onSubmit ? OnSubmitAction(onSubmit, { ...DefaultSubmitSettings, diff --git a/packages/react/src/components/Workbook.tsx b/packages/react/src/components/Workbook.tsx index 821e32b1..8c949325 100644 --- a/packages/react/src/components/Workbook.tsx +++ b/packages/react/src/components/Workbook.tsx @@ -21,9 +21,14 @@ type HookConfig = [string, onRecordHook] | [onRecordHook] export type onRecordHooks = HookConfig[] +export type OnSubmitActionWithConfig = { + handler: SimpleOnboarding['onSubmit'] + config: Partial +} + type WorkbookProps = Partial<{ config: Flatfile.CreateWorkbookConfig - onSubmit: SimpleOnboarding['onSubmit'] + onSubmit: SimpleOnboarding['onSubmit'] | OnSubmitActionWithConfig submitSettings: SimpleOnboarding['submitSettings'] onRecordHooks: onRecordHooks>> children: React.ReactNode @@ -72,15 +77,24 @@ export const Workbook = (props: WorkbookProps) => { // Accept a workbook onSubmit function and add it to the workbook actions useDeepCompareEffect(() => { - // adds workbook action if onSubmit is passed along - updateWorkbook( + const submitAction = workbookOnSubmitAction() + const existingActions = createSpace.workbook?.actions || [] + + let updatedActions = [...existingActions, ...(config?.actions || [])] + + if ( + !updatedActions.some( + (action) => action.operation === submitAction.operation + ) && onSubmit - ? { - ...config, - actions: [workbookOnSubmitAction(), ...(config?.actions || [])], - } - : config - ) + ) { + updatedActions = [submitAction, ...updatedActions] + } + + updateWorkbook({ + ...config, + actions: updatedActions.length > 0 ? updatedActions : undefined, + }) }, [config]) usePlugin( @@ -117,7 +131,13 @@ export const Workbook = (props: WorkbookProps) => { useEvent( 'job:ready', - { job: `workbook:${workbookOnSubmitAction().operation}` }, + { + job: `workbook:${ + workbookOnSubmitAction( + onSubmit && 'config' in onSubmit ? { config: onSubmit.config } : {} + ).operation + }`, + }, onSubmit ? OnSubmitAction(onSubmit, { ...DefaultSubmitSettings, diff --git a/packages/react/src/utils/constants.ts b/packages/react/src/utils/constants.ts index fce2b643..13924acd 100644 --- a/packages/react/src/utils/constants.ts +++ b/packages/react/src/utils/constants.ts @@ -5,8 +5,15 @@ import { SimpleOnboarding, } from '@flatfile/embedded-utils' import { FlatfileEvent } from '@flatfile/listener' +import { OnSubmitActionWithConfig } from '../components' -export const workbookOnSubmitAction = (sheetSlug?: string): Flatfile.Action => { +export const workbookOnSubmitAction = ({ + sheetSlug, + config, +}: { + sheetSlug?: string + config?: Partial +} = {}): Flatfile.Action => { const operation = sheetSlug ? `sheetSubmitAction-${sheetSlug}` : 'workbookSubmitAction' @@ -16,11 +23,12 @@ export const workbookOnSubmitAction = (sheetSlug?: string): Flatfile.Action => { label: 'Submit', description: 'Action for handling data inside of onSubmit', primary: true, + ...config, } } export const OnSubmitAction = ( - onSubmit: SimpleOnboarding['onSubmit'], + onSubmit: SimpleOnboarding['onSubmit'] | OnSubmitActionWithConfig, onSubmitSettings: SimpleOnboarding['submitSettings'] ) => { return async (event: FlatfileEvent) => { @@ -41,7 +49,11 @@ export const OnSubmitAction = ( const sheet = new SheetHandler(workbookSheets[0].id) if (onSubmit) { - await onSubmit({ job, sheet, event }) + if (typeof onSubmit === 'function') { + await onSubmit({ job, sheet, event }) + } else if (typeof onSubmit.handler === 'function') { + await onSubmit.handler({ job, sheet, event }) + } } await FlatfileAPI.jobs.complete(jobId, {