();
const navigate = useNavigate();
+ const tenant = useSelector(tenantSelector);
const busy = useSelector(busySelector);
- const { forms, next } = useSelector(formsSelector);
+ const { forms, next } = useSelector((state) => definitionFormsSelector(state, definition?.id));
const { form: defaultForm } = useSelector(defaultUserFormSelector);
const canCreateDraft = useSelector(canCreateDraftSelector);
+ useEffect(() => {
+ dispatch(findUserForms({ definitionId: definition?.id }));
+ }, [dispatch, definition]);
+
return (
-
-
+
+
Continue working on existing draft forms, or view forms you submitted in the past.
- {canCreateDraft && (
+ {definition && canCreateDraft && (
{
const form = await dispatch(createForm(definition.id)).unwrap();
@@ -52,46 +70,52 @@ export const Forms: FunctionComponent = ({ definition }) => {
+ {!definition && Form | }
Created on |
Submitted on |
Status |
- Actions |
+ |
{forms.map((form) => (
+ {!definition && {form.definition?.name} | }
{form.created.toFormat('LLLL dd, yyyy')} |
{form.submitted?.toFormat('LLLL dd, yyyy')} |
{form.status} |
- {form.status === FormStatus.draft ? (
- navigate(`../${form.id}`)}
- >
- Continue draft
-
- ) : (
- navigate(`../${form.id}`)}>
- View submitted
-
- )}
+ {form.definition &&
+ (form.status === FormStatus.draft ? (
+ navigate(`/${tenant.name}/${form.definition.id}/${form.id}`)}
+ >
+ Continue draft
+
+ ) : (
+ navigate(`/${tenant.name}/${form.definition.id}/${form.id}`)}
+ >
+ View submitted
+
+ ))}
|
))}
-
+
dispatch(findUserForms({ definitionId: definition.id, after }))}
+ onLoadMore={(after) => dispatch(findUserForms({ definitionId: definition?.id, after }))}
/>
-
+
);
};
diff --git a/apps/form-app/src/app/state/form.slice.spec.ts b/apps/form-app/src/app/state/form.slice.spec.ts
index 074244429..84f41a9cb 100644
--- a/apps/form-app/src/app/state/form.slice.spec.ts
+++ b/apps/form-app/src/app/state/form.slice.spec.ts
@@ -32,6 +32,9 @@ const initialState: FormState = {
saving: false,
submitting: false,
},
+ initialized: {
+ forms: false,
+ },
};
const definitionsToTest: FormState = {
@@ -55,6 +58,7 @@ const definitionsToTest: FormState = {
form: {
definition: {
id: 'TEST',
+ name: 'test',
},
created: null,
submitted: null,
@@ -73,6 +77,9 @@ const definitionsToTest: FormState = {
saving: false,
submitting: false,
},
+ initialized: {
+ forms: false,
+ },
};
const loadedFormDefinition: FormDefinition = {
@@ -91,6 +98,7 @@ const payload = {
form: {
definition: {
id: 'TEST',
+ name: 'test',
},
created: null,
submitted: null,
diff --git a/apps/form-app/src/app/state/form.slice.ts b/apps/form-app/src/app/state/form.slice.ts
index effe68ca4..423ec2ebd 100644
--- a/apps/form-app/src/app/state/form.slice.ts
+++ b/apps/form-app/src/app/state/form.slice.ts
@@ -36,7 +36,7 @@ interface SerializableFormDefinition {
}
interface SerializableForm {
- definition: { id: string };
+ definition: { id: string; name: string };
id: string;
urn: string;
status: 'draft' | 'locked' | 'submitted' | 'archived';
@@ -81,6 +81,9 @@ export interface FormState {
saving: boolean;
submitting: boolean;
};
+ initialized: {
+ forms: boolean;
+ };
}
const FORM_SERVICE_ID = 'urn:ads:platform:form-service';
@@ -213,7 +216,7 @@ export const loadDefinition = createAsyncThunk(
export const findUserForms = createAsyncThunk(
'form/find-user-forms',
- async ({ definitionId, after }: { definitionId: string; after?: string }, { getState, rejectWithValue }) => {
+ async ({ definitionId, after }: { definitionId?: string; after?: string }, { getState, rejectWithValue }) => {
try {
const { config, user } = getState() as AppState;
const formServiceUrl = config.directory[FORM_SERVICE_ID];
@@ -498,6 +501,9 @@ const initialFormState: FormState = {
saving: false,
submitting: false,
},
+ initialized: {
+ forms: false,
+ },
};
export const formSlice = createSlice({
@@ -517,8 +523,6 @@ export const formSlice = createSlice({
state.selected = meta.arg;
// Clear the form if the form definition is changing.
if (state.form && state.form.definition.id !== meta.arg) {
- state.forms = {};
- state.results = [];
state.next = null;
state.form = null;
state.data = {};
@@ -532,13 +536,6 @@ export const formSlice = createSlice({
.addCase(loadDefinition.fulfilled, (state, { payload, meta }) => {
state.busy.loading = false;
state.definitions[meta.arg] = payload;
-
- //Check form definition id case sensitivity, and use the definition id in the payload object,
- //instead of using the value in querystring because if the case is not the same
- //grabbing the object using the form definition id in the querystring as the key wont work.
- if (payload && payload.id?.toLowerCase() === state.selected?.toLowerCase()) {
- state.selected = payload.id;
- }
})
.addCase(loadDefinition.rejected, (state) => {
state.busy.loading = false;
@@ -580,6 +577,7 @@ export const formSlice = createSlice({
state.forms = payload.results.reduce((forms, result) => ({ ...forms, [result.id]: result }), state.forms);
state.results = [...(payload.page.after ? state.results : []), ...payload.results.map((result) => result.id)];
state.next = payload.page.next;
+ state.initialized.forms = true;
})
.addCase(findUserForms.rejected, (state) => {
state.busy.loading = false;
@@ -643,18 +641,28 @@ export const formsSelector = createSelector(
(state: AppState) => state.form.next,
(forms, results, next) => ({
forms: results
- .map((result) =>
- forms[result]
- ? {
- ...forms[result],
- status: FormStatus[forms[result].status],
- created: forms[result].created && DateTime.fromISO(forms[result].created),
- submitted: forms[result].submitted && DateTime.fromISO(forms[result].submitted),
- }
- : null
- )
+ .map((result) => {
+ const form = forms[result];
+ const status = FormStatus[form.status];
+ return {
+ ...forms[result],
+ status,
+ created: form.created && DateTime.fromISO(form.created),
+ // Submitted can be set for draft forms if it was returned to draft.
+ submitted: status !== FormStatus.draft ? form.submitted && DateTime.fromISO(form.submitted) : undefined,
+ };
+ })
.filter((result) => !!result)
- .sort((a, b) => a.created.diff(b.created).as('seconds')),
+ .sort((a, b) => b.created.diff(a.created).as('seconds')),
+ next,
+ })
+);
+
+export const definitionFormsSelector = createSelector(
+ formsSelector,
+ (_, definitionId: string) => definitionId,
+ ({ forms, next }, definitionId) => ({
+ forms: forms.filter((form) => !definitionId || form.definition?.id === definitionId),
next,
})
);
@@ -668,15 +676,18 @@ export const formSelector = createSelector(
...form,
status: FormStatus[form.status],
created: form.created && DateTime.fromISO(form.created),
- submitted: form.submitted && DateTime.fromISO(form.submitted),
+ submitted:
+ FormStatus[form.status] !== FormStatus.draft
+ ? form.submitted && DateTime.fromISO(form.submitted)
+ : undefined,
}
: null
);
export const defaultUserFormSelector = createSelector(
formsSelector,
- (state: AppState) => state.form.busy.loading,
- ({ forms }, loading) => {
+ (state: AppState) => state.form.initialized.forms,
+ ({ forms }, initialized) => {
let form: ReturnType['forms'][0];
if (forms.length === 1) {
// If user only has one form, then that's the default form.
@@ -690,7 +701,7 @@ export const defaultUserFormSelector = createSelector(
}
return {
form,
- initialized: !loading,
+ initialized,
empty: forms.length < 1,
};
}
@@ -715,12 +726,10 @@ export const isClerkSelector = createSelector(
export const busySelector = (state: AppState) => state.form.busy;
export const canCreateDraftSelector = createSelector(
- (state: AppState) => state.form.busy.creating,
isApplicantSelector,
definitionSelector,
defaultUserFormSelector,
- (creating, isApplicant, { definition }, { form }) =>
- !creating && isApplicant && (definition?.oneFormPerApplicant === false || !form)
+ (isApplicant, { definition }, { form }) => isApplicant && (definition?.oneFormPerApplicant === false || !form)
);
export const showSubmitSelector = createSelector(definitionSelector, ({ definition }) => {