Skip to content

Commit

Permalink
Fix array indexing for pages. We should be able to stick with index r…
Browse files Browse the repository at this point in the history
…eferences, as long as we have a flat list of pages, but will need to revisit if we support navigation hierarchies.
  • Loading branch information
danielnaab committed Nov 19, 2024
1 parent 8e2bc3d commit 1612d37
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 25 deletions.
1 change: 0 additions & 1 deletion packages/forms/src/pattern.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ export const getPatternSafely = <P extends Pattern>(opts: {
form: Blueprint;
patternId: PatternId;
}): r.Result<P> => {
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`);
Expand Down
2 changes: 2 additions & 0 deletions packages/forms/src/patterns/pages/form-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export class FormClient {

async submitPage(formData: Record<string, string>): Promise<void> {
const state = await this.getState();

const result = await this.ctx.formService.submitForm(
state.sessionId,
this.formId,
Expand All @@ -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,
Expand Down
3 changes: 2 additions & 1 deletion packages/forms/src/patterns/pages/submit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
{
Expand All @@ -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: {
Expand Down
68 changes: 45 additions & 23 deletions packages/forms/src/patterns/pages/submit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -47,11 +50,44 @@ export const submitPage: SubmitHandler<PageSetPattern> = 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<PatternId, PatternValue>;
errors: Record<PatternId, FormError>;
};
}) => {
// 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;
}
Expand All @@ -65,27 +101,13 @@ export const submitPage: SubmitHandler<PageSetPattern> = 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;
};

0 comments on commit 1612d37

Please sign in to comment.