From 1612d377f4bf56407db2b36d662ee6e22123cab0 Mon Sep 17 00:00:00 2001 From: Daniel Naab Date: Tue, 19 Nov 2024 16:11:21 -0600 Subject: [PATCH] Fix array indexing for pages. We should be able to stick with index references, as long as we have a flat list of pages, but will need to revisit if we support navigation hierarchies. --- packages/forms/src/pattern.ts | 1 - .../forms/src/patterns/pages/form-client.ts | 2 + .../forms/src/patterns/pages/submit.test.ts | 3 +- packages/forms/src/patterns/pages/submit.ts | 68 ++++++++++++------- 4 files changed, 49 insertions(+), 25 deletions(-) diff --git a/packages/forms/src/pattern.ts b/packages/forms/src/pattern.ts index c3c92a93..ee0d584a 100644 --- a/packages/forms/src/pattern.ts +++ b/packages/forms/src/pattern.ts @@ -66,7 +66,6 @@ export const getPatternSafely =

(opts: { form: Blueprint; patternId: PatternId; }): r.Result

=> { - console.log('looking for', opts.patternId); const pattern = opts.form.patterns[opts.patternId]; if (pattern === undefined) { return r.failure(`Pattern with id ${opts.patternId} does not exist`); diff --git a/packages/forms/src/patterns/pages/form-client.ts b/packages/forms/src/patterns/pages/form-client.ts index e3ceb271..ed43f46f 100644 --- a/packages/forms/src/patterns/pages/form-client.ts +++ b/packages/forms/src/patterns/pages/form-client.ts @@ -54,6 +54,7 @@ export class FormClient { async submitPage(formData: Record): Promise { const state = await this.getState(); + const result = await this.ctx.formService.submitForm( state.sessionId, this.formId, @@ -69,6 +70,7 @@ export class FormClient { if (!result.success) { throw new Error(`Error submitting form: ${result.error}`); } + this.setState({ sessionId: result.data.sessionId, session: result.data.session, diff --git a/packages/forms/src/patterns/pages/submit.test.ts b/packages/forms/src/patterns/pages/submit.test.ts index a0bb7114..599e3cb4 100644 --- a/packages/forms/src/patterns/pages/submit.test.ts +++ b/packages/forms/src/patterns/pages/submit.test.ts @@ -118,7 +118,7 @@ describe('Page-set submission', () => { }); }); - it.fails('honors first matching page rule', async () => { + it('honors first matching page rule', async () => { const { id, form, formService } = await createTestFormContext(); const client = new FormClient( { @@ -134,6 +134,7 @@ describe('Page-set submission', () => { const state = await client.getState(); expect(state).toEqual( expect.objectContaining({ + attachments: undefined, sessionId: expect.any(String), session: { data: { diff --git a/packages/forms/src/patterns/pages/submit.ts b/packages/forms/src/patterns/pages/submit.ts index a595ae8b..31806108 100644 --- a/packages/forms/src/patterns/pages/submit.ts +++ b/packages/forms/src/patterns/pages/submit.ts @@ -4,11 +4,14 @@ import { getPatternConfig, getPatternSafely, aggregatePatternSessionValues, + type PatternId, + type PatternValue, } from '../../pattern.js'; import { type FormSession } from '../../session'; import { type SubmitHandler } from '../../submission'; import { type PagePattern } from './page/config'; import type { PageSetPattern } from './page-set/config.js'; +import type { FormError } from '../../error.js'; const getPage = (formSession: FormSession) => { const page = formSession.route?.params.page?.toString(); @@ -47,11 +50,44 @@ export const submitPage: SubmitHandler = async ( } ); + const nextPage = getNextPage({ + pageSet: opts.pattern, + page: pagePattern.data, + pageNumber, + data: result, + }); + + return success({ + session: { + ...opts.session, + data: result, + route: opts.session.route + ? { + ...opts.session.route, + params: { + ...opts.session.route.params, + page: nextPage.toString(), + }, + } + : undefined, + }, + }); +}; + +const getNextPage = (opts: { + pageSet: PageSetPattern; + page: PagePattern; + pageNumber: number; + data: { + values: Record; + errors: Record; + }; +}) => { // Evaluate page rules - const ruleMatch = pagePattern.data.data.rules - ? pagePattern.data.data.rules.find(rule => { + const ruleMatch = opts.page.data.rules + ? opts.page.data.rules.find(rule => { if (rule.condition.operator === '=') { - const value = opts.session.data.values[rule.patternId]; + const value = opts.data.values[rule.patternId]; if (value === rule.condition.value) { return true; } @@ -65,27 +101,13 @@ export const submitPage: SubmitHandler = async ( // Get the page number for the 1st rule match, or the next page if no rules // match. - const lastPage = opts.pattern.data.pages.length - 1; + const lastPage = opts.pageSet.data.pages.length - 1; const nextPage = - Object.values(result.errors).length === 0 && pageNumber < lastPage + Object.values(opts.data.errors).length === 0 && opts.pageNumber < lastPage ? ruleMatch - ? pagePattern.data.data.patterns.indexOf(ruleMatch.patternId) - : pageNumber + 1 - : pageNumber; + ? opts.pageSet.data.pages.indexOf(ruleMatch.next) + : opts.pageNumber + 1 + : opts.pageNumber; - return success({ - session: { - ...opts.session, - data: result, - route: opts.session.route - ? { - ...opts.session.route, - params: { - ...opts.session.route.params, - page: nextPage.toString(), - }, - } - : undefined, - }, - }); + return nextPage; };