Skip to content

Commit

Permalink
Update form context constructor to take a form instead of question list.
Browse files Browse the repository at this point in the history
  • Loading branch information
danielnaab committed Jan 5, 2024
1 parent ad92ed3 commit 37b1b30
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 113 deletions.
8 changes: 5 additions & 3 deletions apps/spotlight/src/components/react/form/view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
UnorderedList,
} from './fields';
import { getFormFromStorage } from '../../../lib/form-repo';
import { createFormContext } from '@atj/forms';

// Assuming this is the structure of your JSON data
export interface Field {
Expand All @@ -33,11 +34,12 @@ export interface Field {

export const FormView = ({ formId }: { formId: string }) => {
// Fallback to hardcoded data if a magic ID is chosen.
const fields = getFormFromStorage(window.localStorage, formId);
if (!fields) {
const form = getFormFromStorage(window.localStorage, formId);
if (!form) {
return 'null form retrieved from storage';
}
return <FormFieldset fields={fields} />;
const context = createFormContext(form);
return <FormFieldset fields={form.questions} />;
};

export const FormFieldset = ({ fields }: { fields: Field[] }) => {
Expand Down
39 changes: 17 additions & 22 deletions packages/forms/dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
var src_exports = {};
__export(src_exports, {
createForm: () => createForm,
createFormContextFromQuestions: () => createFormContextFromQuestions,
createFormContext: () => createFormContext,
updateForm: () => updateForm
});
module.exports = __toCommonJS(src_exports);
Expand All @@ -32,40 +32,35 @@ var createForm = (summary, questions = []) => {
questions.map((question) => {
return [question.id, question];
})
)
),
strategy: {
type: "sequential",
order: questions.map((question) => {
return question.id;
})
}
};
};
var createFormContextFromQuestions = (questions) => {
var createFormContext = (form) => {
return {
context: {
errors: {},
values: Object.fromEntries(
questions.map((question) => {
Object.values(form.questions).map((question) => {
return [question.id, question.initial];
})
)
},
questions: Object.fromEntries(
questions.map((question) => {
return [question.id, question];
})
),
form: createForm(
{
title: "Form sample",
description: "Form sample created via a list of questions."
},
questions
)
form
};
};
var updateForm = (form, id, value) => {
if (!(id in form.questions)) {
var updateForm = (context, id, value) => {
if (!(id in context.form.questions)) {
console.error(`Question "${id}" does not exist on form.`);
return form;
return context;
}
const nextForm = addValue(form, id, value);
if (form.questions[id].required && !value) {
const nextForm = addValue(context, id, value);
if (context.form.questions[id].required && !value) {
return addError(nextForm, id, "Required value not provided.");
}
return nextForm;
Expand Down Expand Up @@ -93,6 +88,6 @@ var addError = (form, id, error) => ({
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
createForm,
createFormContextFromQuestions,
createFormContext,
updateForm
});
26 changes: 15 additions & 11 deletions packages/forms/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export type FormSummary = {
export type Form = {
summary: FormSummary;
questions: Record<QuestionId, Question>;
strategy: SequentialStrategy;
};

export type FormContext = {
Expand All @@ -28,6 +29,11 @@ export type FormContext = {
form: Form;
};

export type SequentialStrategy = {
type: 'sequential';
order: QuestionId[];
};

export const createForm = (
summary: FormSummary,
questions: Question[] = []
Expand All @@ -39,28 +45,26 @@ export const createForm = (
return [question.id, question];
})
),
strategy: {
type: 'sequential',
order: questions.map(question => {
return question.id;
}),
},
};
};

export const createFormContextFromQuestions = (
questions: Question[]
): FormContext => {
export const createFormContext = (form: Form): FormContext => {
return {
context: {
errors: {},
values: Object.fromEntries(
questions.map(question => {
Object.values(form.questions).map(question => {
return [question.id, question.initial];
})
),
},
form: createForm(
{
title: 'Form sample',
description: 'Form sample created via a list of questions.',
},
questions
),
form,
};
};

Expand Down
57 changes: 0 additions & 57 deletions packages/forms/tests/single-field-form.test.ts

This file was deleted.

47 changes: 27 additions & 20 deletions packages/forms/tests/two-field-form.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,25 @@ const questions: forms.Question[] = [
required: false,
},
];
const form = forms.createForm(
{
title: 'Form sample',
description: 'Form sample created via a list of questions.',
},
questions
);

describe('two question form', () => {
describe('two question form context', () => {
it('initializes', () => {
const form = forms.createFormContextFromQuestions(questions);
expect(form).to.not.toBeNull();
const context = forms.createFormContext(form);
expect(context).to.not.toBeNull();
});

it('empty field value on required field is stored with error', () => {
const form = forms.createFormContextFromQuestions(questions);
const nextForm = forms.updateForm(form, questions[0].id, null);
const context = forms.createFormContext(form);
const nextForm = forms.updateForm(context, questions[0].id, null);
expect(nextForm).toEqual({
...form,
...context,
context: {
errors: {
'question-1': 'Required value not provided.',
Expand All @@ -41,14 +48,14 @@ describe('two question form', () => {
});

it('valid field value is stored on context', () => {
const form = forms.createFormContextFromQuestions(questions);
const formContext = forms.createFormContext(form);
const nextForm = forms.updateForm(
form,
formContext,
questions[0].id,
'supercalifragilisticexpialidocious'
);
expect(nextForm).toEqual({
...form,
...formContext,
context: {
errors: {},
values: {
Expand All @@ -60,15 +67,15 @@ describe('two question form', () => {
});

it('empty field value on non-required field is set with no errors on context', () => {
const form = forms.createFormContextFromQuestions(questions);
const form2 = forms.updateForm(
form,
const context = forms.createFormContext(form);
const context2 = forms.updateForm(
context,
questions[1].id,
'supercalifragilisticexpialidocious'
);
const form3 = forms.updateForm(form2, questions[1].id, '');
expect(form3).toEqual({
...form,
const context3 = forms.updateForm(context2, questions[1].id, '');
expect(context3).toEqual({
...context,
context: {
errors: {},
values: {
Expand All @@ -80,14 +87,14 @@ describe('two question form', () => {
});

it('valid field value on non-required field is stored on context', () => {
const form = forms.createFormContextFromQuestions(questions);
const nextForm = forms.updateForm(
form,
const context = forms.createFormContext(form);
const nextContext = forms.updateForm(
context,
questions[1].id,
'supercalifragilisticexpialidocious'
);
expect(nextForm).toEqual({
...form,
expect(nextContext).toEqual({
...context,
context: {
errors: {},
values: {
Expand Down

0 comments on commit 37b1b30

Please sign in to comment.