Skip to content

Commit

Permalink
Form manager navigation (#117)
Browse files Browse the repository at this point in the history
* Rename /edit to /create, and update form manager flow to be consistent with mock-ups

* Remove unnecessary uswdsRoot injection

* Move Zustand store to FormManger level; will also split into slices, as appropriate.

* Convert FormEdit store into a Zustand slice

* Move formService into context injected into the store, so we don't need to pass it down. todo: sort out store provider in the tests

* Remove unnecessary FormService param on FormManager

* Put the base URL on the form manager context.

* Rename (and move) FormEditUIContext to FormManagerContext

* Wrap FormEdit stories with test FormManagerProvider

* In-progress for sharing

* Add placeholder for "upload" step, which includes some of the original demo flow of how an upload works. We'll tweak this when we have updated designs for the final flow.

* Preview link wired to preview page; navigation for page TODO

* Fix some typing issues with the storybook wrappers

* Remove unused hooks module

* Add contexts to Storybook specs

* Stories for form manager layout steps

* Add routes constants for the form manager

* Add a simple indicator for last saved time.

* Tweak mobile display of top nav

* Tweak margins a bit
  • Loading branch information
danielnaab authored Apr 29, 2024
1 parent d406581 commit 6f1d27b
Show file tree
Hide file tree
Showing 58 changed files with 733 additions and 516 deletions.
6 changes: 3 additions & 3 deletions apps/doj-demo/src/components/AppFormManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ export default function () {
return (
<FormManager
context={{
config: ctx.formConfig,
baseUrl: ctx.baseUrl,
components: defaultPatternComponents,
config: ctx.formConfig,
editComponents: defaultPatternEditComponents,
formService: ctx.formService,
uswdsRoot: ctx.uswdsRoot,
}}
formService={ctx.formService}
baseUrl={ctx.baseUrl}
/>
);
}
2 changes: 0 additions & 2 deletions apps/doj-demo/src/layouts/Layout.astro
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import '../styles.css';
import UsaBanner from '../components/UsaBanner.astro';
import Footer from '../components/Footer.astro';
import Header from '../components/Header.astro';
import { getAppContext } from '../context';
import * as routes from '../routes';
Expand All @@ -11,7 +10,6 @@ interface Props {
title: string;
}
const { title } = Astro.props;
const context = getAppContext();
---

<html lang="en">
Expand Down
6 changes: 3 additions & 3 deletions apps/spotlight/src/components/AppFormManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ export default function () {
return (
<FormManager
context={{
config: ctx.formConfig,
baseUrl: ctx.baseUrl,
components: defaultPatternComponents,
config: ctx.formConfig,
editComponents: defaultPatternEditComponents,
formService: ctx.formService,
uswdsRoot: ctx.uswdsRoot,
}}
formService={ctx.formService}
baseUrl={ctx.baseUrl}
/>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
import { describeStories } from '../test-helper';
import meta, * as stories from './AvailableFormList.stories';

describeStories(meta.title, stories);
describeStories(meta, stories);
2 changes: 1 addition & 1 deletion packages/design/src/Form/ActionBar/ActionBar.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
import { describeStories } from '../../test-helper';
import meta, * as stories from './ActionBar.stories';

describeStories(meta.title, stories);
describeStories(meta, stories);
2 changes: 1 addition & 1 deletion packages/design/src/Form/Form.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
import { describeStories } from '../test-helper';
import meta, * as stories from './Form.stories';

describeStories(meta.title, stories);
describeStories(meta, stories);
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
import { describeStories } from '../../../test-helper';
import meta, * as stories from './Fieldset.stories';

describeStories(meta.title, stories);
describeStories(meta, stories);
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
import { describeStories } from '../../../test-helper';
import meta, * as stories from './FormSummary.stories';

describeStories(meta.title, stories);
describeStories(meta, stories);
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
import { describeStories } from '../../../test-helper';
import meta, * as stories from './TestInput.stories';

describeStories(meta.title, stories);
describeStories(meta, stories);
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
import { describeStories } from '../../test-helper';
import meta, * as stories from './FormDelete.stories';

describeStories(meta.title, stories);
describeStories(meta, stories);
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { MemoryRouter } from 'react-router-dom';
import type { Meta, StoryObj } from '@storybook/react';

import DocumentImporter from '.';
import { createTestForm } from '../../test-form';
import { createTestForm } from '../../../test-form';

export default {
title: 'FormManager/DocumentImporter',
Expand All @@ -20,6 +20,6 @@ export default {
form: createTestForm(),
},
tags: ['autodocs'],
} satisfies Meta<typeof DocumentImporter>;
} as Meta<typeof DocumentImporter>;

export const TestForm = {} satisfies StoryObj<typeof DocumentImporter>;
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @vitest-environment jsdom
*/
import { describeStories } from '../../test-helper';
import { describeStories } from '../../../test-helper';
import meta, * as stories from './DocumentImporter.stories';

describeStories(meta.title, stories);
describeStories(meta, stories);
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { PropsWithChildren, useReducer } from 'react';
import React, { useReducer } from 'react';
import { useNavigate } from 'react-router-dom';

import {
Expand All @@ -11,8 +11,8 @@ import {
} from '@atj/forms';
import { type FormService } from '@atj/form-service';

import Form, { FormUIContext } from '../../Form';
import { onFileInputChangeGetFile } from '../FormList/CreateNew/file-input';
import Form, { FormUIContext } from '../../../Form';
import { onFileInputChangeGetFile } from '../../FormList/CreateNew/file-input';

const DocumentImporter = ({
baseUrl,
Expand All @@ -29,46 +29,6 @@ const DocumentImporter = ({
}) => {
const { state, actions } = useDocumentImporter(formService, form, baseUrl);

const Step: React.FC<
PropsWithChildren<{ title: string; step: number; current: number }>
> = ({ children, title, step, current }) => {
if (current === step) {
return (
<li className="usa-step-indicator__segment usa-step-indicator__segment--current">
<span className="usa-step-indicator__segment-label">
{title}
{children}
</span>
</li>
);
} else if (current < step) {
return (
<li className="usa-step-indicator__segment">
<span className="usa-step-indicator__segment-label">
{title}
{children}
<span className="usa-sr-only">not completed</span>
</span>
</li>
);
} else {
return (
<li className="usa-step-indicator__segment usa-step-indicator__segment--complete">
<button
className="usa-button--unstyled"
onClick={() => actions.gotoPage(step)}
>
<span className="usa-step-indicator__segment-label">
{title}
{children}
<span className="usa-sr-only">completed</span>
</span>
</button>
</li>
);
}
};

const CreateNew = () => {
return (
<div className="usa-form-group">
Expand Down Expand Up @@ -168,13 +128,6 @@ const DocumentImporter = ({
return (
<div>
<h1>Import a PDF</h1>
<div className="usa-step-indicator" aria-label="progress">
<ol className="usa-step-indicator__segments">
<Step title="Select a PDF" step={1} current={state.page} />
<Step title="Review document fields" step={2} current={state.page} />
<Step title="Preview form" step={3} current={state.page} />
</ol>
</div>
{state.page === 1 && <CreateNew />}
{state.page === 2 && <BuildFormPage />}
{state.page === 3 && <PreviewFormPage />}
Expand Down Expand Up @@ -292,7 +245,7 @@ const useDocumentImporter = (
},
stepThreeSaveForm(formId: string) {
formService.saveForm(formId, state.previewForm);
navigate(`/${formId}/edit`);
navigate(`/${formId}/create`);
},
gotoPage(step: number) {
dispatch({ type: 'GOTO_PAGE', page: step });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';

import { type FormService } from '@atj/form-service';

import { type FormUIContext } from '../Form';
import { type FormUIContext } from '../../Form';
import DocumentImporter from './DocumentImporter';

export const FormDocumentImport = ({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from 'react';
import { useFormEditStore } from './store';
import { useFormManagerStore } from '../store';

export const AddPatternDropdown = () => {
const store = useFormEditStore(state => ({
const store = useFormManagerStore(state => ({
availablePatterns: state.availablePatterns,
addPattern: state.addPattern,
}));
Expand Down
17 changes: 9 additions & 8 deletions packages/design/src/FormManager/FormEdit/FormEdit.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
import React from 'react';
import { MemoryRouter } from 'react-router-dom';
import type { Meta, StoryObj } from '@storybook/react';
import { expect, userEvent, waitFor, within } from '@storybook/test';

import { createTestFormService } from '@atj/form-service';
import { FormManagerProvider } from '../store';

import FormEdit from '.';
import { createTestForm, createTestFormEditContext } from '../../test-form';
import { expect, userEvent, waitFor, within } from '@storybook/test';
import { createTestForm, createTestFormManagerContext } from '../../test-form';

export default {
title: 'FormManager/FormEdit',
component: FormEdit,
decorators: [
(Story, args) => (
<MemoryRouter initialEntries={['/']}>
<Story {...args} />
<FormManagerProvider
context={createTestFormManagerContext()}
form={createTestForm()}
>
<Story {...args} />
</FormManagerProvider>
</MemoryRouter>
),
],
args: {
context: createTestFormEditContext(),
formId: 'test-form',
formService: createTestFormService({
'test-form': createTestForm(),
}),
},
tags: ['autodocs'],
} satisfies Meta<typeof FormEdit>;
Expand Down
2 changes: 1 addition & 1 deletion packages/design/src/FormManager/FormEdit/FormEdit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
import { describeStories } from '../../test-helper';
import meta, * as stories from './FormEdit.stories';

describeStories(meta.title, stories);
describeStories(meta, stories);
4 changes: 2 additions & 2 deletions packages/design/src/FormManager/FormEdit/PreviewPattern.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';

import { PatternComponent } from '../../Form';
import { useFormEditStore } from './store';
import { useFormManagerStore } from '../store';

export const PreviewPattern: PatternComponent = function PreviewPattern(props) {
const { context, setFocus } = useFormEditStore(state => ({
const { context, setFocus } = useFormManagerStore(state => ({
context: state.context,
setFocus: state.setFocus,
updatePatternById: state.updatePatternById,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import React from 'react';

import { PatternId, type FieldsetProps } from '@atj/forms';
import { FieldsetPattern } from '@atj/forms/src/patterns/fieldset';
import { type PatternId, type FieldsetProps } from '@atj/forms';

import Fieldset from '../../../Form/components/Fieldset';
import { useIsPatternSelected, usePattern } from '../store';
import { useFormManagerStore } from '../../store';
import { PatternEditComponent } from '../types';

import { PatternEditActions } from './common/PatternEditActions';
import { PatternEditForm } from './common/PatternEditForm';

const FieldsetEdit: PatternEditComponent<FieldsetProps> = props => {
const isSelected = useIsPatternSelected(props.previewProps._patternId);
const isSelected = useFormManagerStore(
state => state.focusedPattern?.id === props.previewProps._patternId
);
return (
<>
{isSelected ? (
Expand All @@ -29,7 +30,9 @@ const FieldsetEdit: PatternEditComponent<FieldsetProps> = props => {
};

const FieldsetPreview = (props: FieldsetProps) => {
const pattern = usePattern<FieldsetPattern>(props._patternId);
const pattern = useFormManagerStore(
state => state.form.patterns[props._patternId]
);
return (
<>
{pattern.data.patterns.length === 0 && <em>[Empty fieldset]</em>}
Expand All @@ -39,7 +42,7 @@ const FieldsetPreview = (props: FieldsetProps) => {
};

const EditComponent = ({ patternId }: { patternId: PatternId }) => {
const pattern = usePattern(patternId);
const pattern = useFormManagerStore(state => state.form.patterns[patternId]);
//const { register } = usePatternEditFormContext();
return (
<div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from 'react';
import { type FormSummaryProps, type PatternId } from '@atj/forms';

import FormSummary from '../../../Form/components/FormSummary';
import { useIsPatternSelected } from '../store';
import { useFormManagerStore } from '../../store';
import { PatternEditComponent } from '../types';

import {
Expand All @@ -12,7 +12,9 @@ import {
} from './common/PatternEditForm';

const FormSummaryEdit: PatternEditComponent<FormSummaryProps> = props => {
const isSelected = useIsPatternSelected(props.previewProps._patternId);
const isSelected = useFormManagerStore(
state => state.focusedPattern?.id === props.previewProps._patternId
);
return (
<>
{isSelected ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from 'react';
import { PatternId, TextInputProps } from '@atj/forms';

import TextInput from '../../../Form/components/TextInput';
import { useIsPatternSelected, usePattern } from '../store';
import { useFormManagerStore } from '../../store';
import { PatternEditComponent } from '../types';

import { PatternEditActions } from './common/PatternEditActions';
Expand All @@ -13,7 +13,9 @@ import {
} from './common/PatternEditForm';

const InputPatternEdit: PatternEditComponent<TextInputProps> = props => {
const isSelected = useIsPatternSelected(props.previewProps._patternId);
const isSelected = useFormManagerStore(
state => state.focusedPattern?.id === props.previewProps._patternId
);
return (
<>
{isSelected ? (
Expand All @@ -31,7 +33,7 @@ const InputPatternEdit: PatternEditComponent<TextInputProps> = props => {
};

const EditComponent = ({ patternId }: { patternId: PatternId }) => {
const pattern = usePattern(patternId);
const pattern = useFormManagerStore(state => state.form.patterns[patternId]);

const methods = usePatternEditFormContext();
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from 'react';
import { PatternId, type ParagraphProps } from '@atj/forms';

import Paragraph from '../../../Form/components/Paragraph';
import { useIsPatternSelected } from '../store';
import { useFormManagerStore } from '../../store';
import { PatternEditComponent } from '../types';

import { PatternEditActions } from './common/PatternEditActions';
Expand All @@ -13,7 +13,9 @@ import {
} from './common/PatternEditForm';

const ParagraphPatternEdit: PatternEditComponent<ParagraphProps> = props => {
const isSelected = useIsPatternSelected(props.previewProps._patternId);
const isSelected = useFormManagerStore(
state => state.focusedPattern?.id === props.previewProps._patternId
);
return (
<>
{isSelected ? (
Expand Down
Loading

0 comments on commit 6f1d27b

Please sign in to comment.