Skip to content

Commit

Permalink
feat: ProjectManagerFormGroup stages form changes
Browse files Browse the repository at this point in the history
  • Loading branch information
matthieu-foucault committed Mar 30, 2022
1 parent 4a0f9df commit df0746c
Show file tree
Hide file tree
Showing 13 changed files with 273 additions and 233 deletions.
18 changes: 9 additions & 9 deletions app/components/Form/ProjectContactForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ const ProjectContactForm: React.FC<Props> = (props) => {
<Grid cols={10} align="center">
<Grid.Row>
<Grid.Col span={10}>
<FormBorder title="Project Contacts">
<FormBorder>
<Grid.Row>
<Grid.Col span={10} className="right-aligned-column">
<Button>View Contact List</Button>
Expand All @@ -263,10 +263,10 @@ const ProjectContactForm: React.FC<Props> = (props) => {
ref={(el) => (formRefs.current[primaryContactForm.id] = el)}
formData={primaryContactForm.newFormData}
onChange={(change) => {
updateFormChange(primaryContactForm, {
...change.formData,
changeStatus: "pending",
});
updateFormChange(
{ ...primaryContactForm, changeStatus: "pending" },
change.formData
);
}}
schema={contactSchema}
uiSchema={uiSchema}
Expand Down Expand Up @@ -296,10 +296,10 @@ const ProjectContactForm: React.FC<Props> = (props) => {
ref={(el) => (formRefs.current[form.id] = el)}
formData={form.newFormData}
onChange={(change) => {
updateFormChange(form, {
...change.formData,
changeStatus: "pending",
});
updateFormChange(
{ ...form, changeStatus: "pending" },
change.formData
);
}}
schema={contactSchema}
uiSchema={uiSchema}
Expand Down
62 changes: 37 additions & 25 deletions app/components/Form/ProjectForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,25 @@ import type { JSONSchema7 } from "json-schema";
import FormBase from "../Form/FormBase";
import { graphql, useFragment } from "react-relay";
import type { ProjectForm_query$key } from "__generated__/ProjectForm_query.graphql";
import { useMemo, useRef } from "react";
import { useMemo } from "react";
import SelectRfpWidget from "components/Form/SelectRfpWidget";
import SelectProjectStatusWidget from "./SelectProjectStatusWidget";
import projectSchema from "data/jsonSchemaForm/projectSchema";
import { ProjectForm_projectRevision$key } from "__generated__/ProjectForm_projectRevision.graphql";
import { FormValidation } from "@rjsf/core";
import { mutation as updateProjectFormChangeMutation } from "mutations/FormChange/updateProjectFormChange";
import useDebouncedMutation from "mutations/useDebouncedMutation";
import { FormValidation, ISubmitEvent } from "@rjsf/core";
import { useUpdateProjectFormChange } from "mutations/FormChange/updateProjectFormChange";
import { Button } from "@button-inc/bcgov-theme";
import SavingIndicator from "./SavingIndicator";

interface Props {
query: ProjectForm_query$key;
projectRevision: ProjectForm_projectRevision$key;
onSubmit: () => void;
}

const ProjectForm: React.FC<Props> = (props) => {
const formRef = useRef();
const [updateProjectFormChange, updatingProjectFormChange] =
useDebouncedMutation(updateProjectFormChangeMutation);
useUpdateProjectFormChange();

const revision = useFragment(
graphql`
Expand Down Expand Up @@ -80,31 +79,39 @@ const ProjectForm: React.FC<Props> = (props) => {
return errors;
};

const handleChange = (changeData: any) => {
const handleChange = (
changeData: any,
changeStatus: "pending" | "staged"
) => {
const updatedFormData = {
...revision.projectFormChange.newFormData,
...changeData,
};
return updateProjectFormChange({
variables: {
input: {
id: revision.projectFormChange.id,
formChangePatch: {
newFormData: updatedFormData,
return new Promise((resolve, reject) =>
updateProjectFormChange({
variables: {
input: {
id: revision.projectFormChange.id,
formChangePatch: {
newFormData: updatedFormData,
changeStatus,
},
},
},
},
optimisticResponse: {
updateFormChange: {
formChange: {
id: revision.projectFormChange.id,
newFormData: updatedFormData,
isUniqueValue: revision.projectFormChange.isUniqueValue,
optimisticResponse: {
updateFormChange: {
formChange: {
id: revision.projectFormChange.id,
newFormData: updatedFormData,
isUniqueValue: revision.projectFormChange.isUniqueValue,
},
},
},
},
debounceKey: revision.projectFormChange.id,
});
onCompleted: resolve,
onError: reject,
debounceKey: revision.projectFormChange.id,
})
);
};

const schema: JSONSchema7 = useMemo(() => {
Expand Down Expand Up @@ -189,6 +196,11 @@ const ProjectForm: React.FC<Props> = (props) => {
[revision.projectFormChange.updatedAt]
);

const handleSubmit = async (e: ISubmitEvent<any>) => {
await handleChange(e.formData, "staged");
props.onSubmit();
};

return (
<>
<header>
Expand All @@ -200,7 +212,6 @@ const ProjectForm: React.FC<Props> = (props) => {
</header>
<FormBase
{...props}
ref={(el) => (formRef.current = el)}
schema={schema}
uiSchema={uiSchema}
validate={uniqueProposalReferenceValidation}
Expand All @@ -214,7 +225,8 @@ const ProjectForm: React.FC<Props> = (props) => {
SelectRfpWidget: SelectRfpWidget,
SelectProjectStatusWidget: SelectProjectStatusWidget,
}}
onChange={(change) => handleChange(change.formData)}
onChange={(change) => handleChange(change.formData, "pending")}
onSubmit={handleSubmit}
>
<Button type="submit" style={{ marginRight: "1rem" }}>
Submit Project Overview
Expand Down
87 changes: 47 additions & 40 deletions app/components/Form/ProjectManagerForm.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
import { JSONSchema7, JSONSchema7Definition } from "json-schema";
import { useMemo, MutableRefObject } from "react";
import { graphql, useFragment } from "react-relay";
import { Disposable, graphql, useFragment } from "react-relay";
import { ProjectManagerForm_managerFormChange$key } from "__generated__/ProjectManagerForm_managerFormChange.graphql";
import { ProjectManagerForm_query$key } from "__generated__/ProjectManagerForm_query.graphql";
import FormBase from "./FormBase";
import projectManagerSchema from "data/jsonSchemaForm/projectManagerSchema";
import FormComponentProps from "./Interfaces/FormComponentProps";
import Grid from "@button-inc/bcgov-theme/Grid";
import { Button } from "@button-inc/bcgov-theme";
import useAddManagerToRevisionMutation from "mutations/Manager/addManagerToRevision";
import { useUpdateFormChange } from "mutations/FormChange/updateFormChange";
import EmptyObjectFieldTemplate from "lib/theme/EmptyObjectFieldTemplate";
import FieldLabel from "lib/theme/widgets/FieldLabel";
import useDeleteManagerFromRevisionMutation from "mutations/Manager/deleteManagerFromRevision";
import { UseDebouncedMutationConfig } from "mutations/useDebouncedMutation";
import { updateFormChangeMutation } from "__generated__/updateFormChangeMutation.graphql";

interface Props extends FormComponentProps {
managerFormChange: ProjectManagerForm_managerFormChange$key;
query: ProjectManagerForm_query$key;
projectId: number;
projectRevisionId: string;
projectRevisionRowId: number;
updateFormChange: (
config: UseDebouncedMutationConfig<updateFormChangeMutation>
) => Disposable;
formRefs: MutableRefObject<{}>;
}

Expand All @@ -42,6 +45,7 @@ const ProjectManagerForm: React.FC<Props> = (props) => {
projectRevisionId,
projectRevisionRowId,
formRefs,
updateFormChange,
} = props;

const { allCifUsers } = useFragment(
Expand Down Expand Up @@ -131,8 +135,6 @@ const ProjectManagerForm: React.FC<Props> = (props) => {
});
};

const [applyUpdateFormChangeMutation] = useUpdateFormChange();

// Delete a manager from the project revision
const [deleteManager, deleteManagerInFlight] =
useDeleteManagerFromRevisionMutation();
Expand Down Expand Up @@ -163,7 +165,7 @@ const ProjectManagerForm: React.FC<Props> = (props) => {

// If a form_change already exists, and the payload contains a cifUserId update it
if (formChangeId && formChange?.cifUserId) {
applyUpdateFormChangeMutation({
updateFormChange({
variables: {
input: {
id: formChangeId,
Expand Down Expand Up @@ -196,42 +198,47 @@ const ProjectManagerForm: React.FC<Props> = (props) => {

return (
<>
<Grid.Row>
<FieldLabel
label={change.projectManagerLabel.label}
required={false}
htmlFor={`${formIdPrefix}_cifUserId`}
<FieldLabel
label={change.projectManagerLabel.label}
required={false}
htmlFor={`${formIdPrefix}_cifUserId`}
uiSchema={uiSchema}
/>
<div>
<FormBase
id={`form-manager-${change.projectManagerLabel.label}`}
idPrefix={formIdPrefix}
ref={(el) => (formRefs.current[change.projectManagerLabel.id] = el)}
formData={change.formChange?.newFormData}
onChange={(data) => {
createOrUpdateFormChange(
change.formChange?.id,
change.projectManagerLabel.rowId,
data.formData
);
}}
schema={managerSchema}
uiSchema={uiSchema}
ObjectFieldTemplate={EmptyObjectFieldTemplate}
/>
<Grid.Col span={6}>
<FormBase
id={`form-manager-${change.projectManagerLabel.label}`}
idPrefix={formIdPrefix}
ref={(el) => (formRefs.current[change.projectManagerLabel.id] = el)}
formData={change.formChange?.newFormData}
onChange={(data) => {
createOrUpdateFormChange(
change.formChange?.id,
change.projectManagerLabel.rowId,
data.formData
);
}}
schema={managerSchema}
uiSchema={uiSchema}
ObjectFieldTemplate={EmptyObjectFieldTemplate}
/>
</Grid.Col>
<Grid.Col span={4}>
<Button
disabled={deleteManagerInFlight || !change.formChange?.id}
variant="secondary"
size="small"
onClick={() => handleClear()}
>
Clear
</Button>
</Grid.Col>
</Grid.Row>
<Button
disabled={deleteManagerInFlight || !change.formChange?.id}
variant="secondary"
size="small"
onClick={() => handleClear()}
>
Clear
</Button>
</div>
<style jsx>{`
div {
display: flex;
align-items: flex-start;
}
div :global(form) {
flex-grow: 1;
}
`}</style>
</>
);
};
Expand Down
Loading

0 comments on commit df0746c

Please sign in to comment.