Skip to content

Commit

Permalink
Wire document downloads up to form submission. This involved some cle…
Browse files Browse the repository at this point in the history
…an-up of the structure of the document importer and other refactoring. Additionally, there are inconsistencies on the imported fields that is preventing the PDFs from being properly filled, so that will be be follow-up work.
  • Loading branch information
danielnaab committed Jan 15, 2024
1 parent bf73645 commit 24749e3
Show file tree
Hide file tree
Showing 27 changed files with 579 additions and 266 deletions.
2 changes: 1 addition & 1 deletion apps/rest-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"dev": "tsup src/* --watch"
},
"dependencies": {
"@atj/interviews": "workspace:*"
"@atj/form-service": "workspace:*"
},
"devDependencies": {
"@types/aws-lambda": "^8.10.109",
Expand Down
2 changes: 1 addition & 1 deletion apps/spotlight/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
"dependencies": {
"@astrojs/react": "^3.0.3",
"@atj/design": "workspace:*",
"@atj/docassemble": "workspace:*",
"@atj/documents": "workspace:*",
"@atj/form-service": "workspace:*",
"@atj/forms": "workspace:*",
"@atj/interviews": "workspace:*",
"astro": "^3.5.4",
Expand Down
224 changes: 146 additions & 78 deletions apps/spotlight/src/components/react/form-builder/document-importer.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,22 @@
import React, { PropsWithChildren, useReducer } from 'react';
import { useNavigate } from 'react-router-dom';

import {
DocumentFieldMap,
addDocumentFieldsToForm,
getDocumentFieldData,
suggestFormDetails,
} from '@atj/documents';
import {
DocumentFieldMap,
Form,
addDocument,
createFormContext,
createPrompt,
} from '@atj/forms';

import { onFileInputChangeGetFile } from '../../../lib/file-input';
import { FormView } from '../form/view';
import { Form, createFormContext, createPrompt } from '@atj/forms';
import { saveFormToStorage } from '../../../lib/form-repo';
import { useNavigate } from 'react-router-dom';

type State = {
page: number;
form: Form;
documentFields?: DocumentFieldMap;
previewForm?: Form;
};
type Action =
| {
type: 'SELECT_PDF';
data: DocumentFieldMap;
}
| {
type: 'PREVIEW_FORM';
data: DocumentFieldMap;
}
| {
type: 'GOTO_PAGE';
page: number;
};
import { saveFormToStorage } from '@atj/form-service';

export const DocumentImporter = ({
formId,
Expand All @@ -40,46 +25,7 @@ export const DocumentImporter = ({
formId: string;
form: Form;
}) => {
const navigate = useNavigate();
const [state, dispatch] = useReducer(
(state: State, action: Action) => {
if (action.type === 'SELECT_PDF') {
return {
page: 2,
documentFields: action.data,
form: state.form,
};
}
if (action.type === 'PREVIEW_FORM') {
return {
page: 3,
documentFields: action.data,
form: state.form,
};
}
if (action.type === 'GOTO_PAGE') {
return {
...state,
page: action.page,
form: state.form,
};
}
return state;
},
{
page: 1,
form: form,
}
);

const selectDocumentByUrl = async (url: string) => {
const response = await fetch(url);
const blob = await response.blob();
const data = new Uint8Array(await blob.arrayBuffer());
const fieldData = await getDocumentFieldData(data);
const fieldInfo = suggestFormDetails(fieldData);
dispatch({ type: 'SELECT_PDF', data: fieldInfo });
};
const { state, actions } = useDocumentImporter(form);

const Step: React.FC<
PropsWithChildren<{ title: string; step: number; current: number }>
Expand Down Expand Up @@ -108,7 +54,7 @@ export const DocumentImporter = ({
<li className="usa-step-indicator__segment usa-step-indicator__segment--complete">
<button
className="usa-button--unstyled"
onClick={() => dispatch({ type: 'GOTO_PAGE', page: step })}
onClick={() => actions.gotoPage(step)}
>
<span className="usa-step-indicator__segment-label">
{title}
Expand Down Expand Up @@ -140,9 +86,7 @@ export const DocumentImporter = ({
type="file"
accept=".pdf"
onChange={onFileInputChangeGetFile(async fileDetails => {
const fieldData = await getDocumentFieldData(fileDetails.data);
const fieldInfo = suggestFormDetails(fieldData);
dispatch({ type: 'SELECT_PDF', data: fieldInfo });
actions.stepOneSelectPdfByUpload(fileDetails);
})}
/>
</div>
Expand All @@ -152,7 +96,7 @@ export const DocumentImporter = ({
<button
className="usa-button--unstyled"
onClick={async () => {
selectDocumentByUrl(
actions.stepOneSelectPdfByUrl(
'sample-documents/ca-unlawful-detainer/ud105.pdf'
);
}}
Expand All @@ -162,7 +106,7 @@ export const DocumentImporter = ({
<button
className="usa-button--unstyled"
onClick={async () => {
selectDocumentByUrl(
actions.stepOneSelectPdfByUrl(
'sample-documents/alabama-name-change/ps-12.pdf'
);
}}
Expand All @@ -187,10 +131,7 @@ export const DocumentImporter = ({
<form
className="usa-form usa-form--large"
onSubmit={event => {
dispatch({
type: 'PREVIEW_FORM',
data: state.documentFields || {},
});
actions.stepTwoConfirmFields();
}}
>
{/*<EditFieldset fields={state.suggestedForm} />*/}
Expand All @@ -212,13 +153,17 @@ export const DocumentImporter = ({
const prompt = createPrompt(formContext);
return (
<>
<FormView prompt={prompt} />
<FormView
prompt={prompt}
onSubmit={data => {
//handleFormSubmission(formId, data);
console.log(formId, data);
}}
/>
<form
className="usa-form usa-form--large"
onSubmit={event => {
event.preventDefault();
saveFormToStorage(window.localStorage, formId, previewForm);
navigate(`/${formId}/edit`);
actions.stepThreeSaveForm(formId);
}}
>
<ButtonBar />
Expand All @@ -243,3 +188,126 @@ export const DocumentImporter = ({
</div>
);
};

type State = {
page: number;
previewForm: Form;
documentFields?: DocumentFieldMap;
};

const useDocumentImporter = (form: Form) => {
const navigate = useNavigate();
const [state, dispatch] = useReducer(
(
state: State,
action:
| {
type: 'SELECT_PDF';
data: {
path: string;
fields: DocumentFieldMap;
previewForm: Form;
};
}
| {
type: 'PREVIEW_FORM';
}
| {
type: 'GOTO_PAGE';
page: number;
}
) => {
if (action.type === 'SELECT_PDF') {
return {
page: 2,
previewForm: action.data.previewForm,
documentFields: action.data.fields,
};
}
if (action.type === 'PREVIEW_FORM') {
return {
page: 3,
documentFields: state.documentFields,
previewForm: state.previewForm,
};
}
if (action.type === 'GOTO_PAGE') {
return {
...state,
page: action.page,
previewForm: state.previewForm,
documentFields: state.documentFields,
};
}
return state;
},
{
page: 1,
previewForm: form,
}
);
return {
state,
actions: {
async stepOneSelectPdfByUrl(url: string) {
const completeUrl = `${(import.meta as any).env.BASE_URL}${url}`;
const response = await fetch(completeUrl);
const blob = await response.blob();
const data = new Uint8Array(await blob.arrayBuffer());
const fieldData = await getDocumentFieldData(data);
const fields = suggestFormDetails(fieldData);
const withFields = addDocumentFieldsToForm(state.previewForm, fields);
const withDocument = addDocument(withFields, {
data,
path: url,
fields: fieldData,
formFields: fields,
});
console.log('withDocument', withDocument);
dispatch({
type: 'SELECT_PDF',
data: {
path: url,
fields,
previewForm: withDocument,
},
});
},
async stepOneSelectPdfByUpload(fileDetails: {
name: string;
data: Uint8Array;
}) {
const fieldData = await getDocumentFieldData(fileDetails.data);
const fieldMap = suggestFormDetails(fieldData);
const withFields = addDocumentFieldsToForm(state.previewForm, fieldMap);
const withDocument = addDocument(withFields, {
data: fileDetails.data,
path: fileDetails.name,
fields: fieldData,
formFields: fieldMap,
});
dispatch({
type: 'SELECT_PDF',
data: {
path: fileDetails.name,
fields: fieldData,
previewForm: withDocument,
},
});
},
stepTwoConfirmFields() {
dispatch({
type: 'PREVIEW_FORM',
});
},
stepThreeSaveForm(formId: string) {
console.log('saving form', state.previewForm);
saveFormToStorage(window.localStorage, formId, state.previewForm);
navigate(`/${formId}/edit`);
},
gotoPage(step: number) {
dispatch({ type: 'GOTO_PAGE', page: step });
},
},
};
};
7 changes: 2 additions & 5 deletions apps/spotlight/src/components/react/form/delete.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import React from 'react';
import { useNavigate } from 'react-router-dom';
import {
deleteFormFromStorage,
getFormFromStorage,
} from '../../../lib/form-repo';
import { deleteFormFromStorage, getFormFromStorage } from '@atj/form-service';

export const FormDelete = ({ formId }: { formId: string }) => {
const navigate = useNavigate();
Expand All @@ -16,7 +13,7 @@ export const FormDelete = ({ formId }: { formId: string }) => {
<div>
<h1>Delete form</h1>
<div>Are you sure you want to delete the form with id: `{formId}`?</div>
<code>{JSON.stringify(form)}</code>
<code>{JSON.stringify(form, null, 4)}</code>
<div>
<button onClick={deleteForm}>Delete form</button>
</div>
Expand Down
5 changes: 2 additions & 3 deletions apps/spotlight/src/components/react/form/edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useForm } from 'react-hook-form';
import { Link } from 'react-router-dom';

import { Form, addQuestions, createForm, getFlatFieldList } from '@atj/forms';
import { getFormFromStorage, saveFormToStorage } from '../../../lib/form-repo';
import { getFormFromStorage, saveFormToStorage } from '@atj/form-service';

export const FormEdit = ({ formId }: { formId: string }) => {
const form = getFormFromStorage(window.localStorage, formId);
Expand All @@ -14,7 +14,6 @@ export const FormEdit = ({ formId }: { formId: string }) => {
<div>
<h1>Edit form interface</h1>
<div>Editing form {formId}</div>
<code>{JSON.stringify(form)}</code>
<ul>
<li>
<button
Expand Down Expand Up @@ -81,7 +80,7 @@ const EditForm = ({
{
fieldType: 'input',
label: value.text,
initial: value.initial,
initial: value.initial.toString(),
required: value.required,
},
];
Expand Down
3 changes: 2 additions & 1 deletion apps/spotlight/src/components/react/form/import-document.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import { getFormFromStorage } from '../../../lib/form-repo';
import { getFormFromStorage } from '@atj/form-service';

import { DocumentImporter } from '../form-builder/document-importer';

export const FormDocumentImport = ({ formId }: { formId: string }) => {
Expand Down
2 changes: 1 addition & 1 deletion apps/spotlight/src/components/react/form/list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useNavigate, Link } from 'react-router-dom';
import {
addFormSummaryToStorage,
getFormListFromStorage,
} from '../../../lib/form-repo';
} from '@atj/form-service';

export const FormList = () => {
const navigate = useNavigate();
Expand Down
Loading

0 comments on commit 24749e3

Please sign in to comment.