Passed
Push — task/update-profile-experience ( 9cba2e...f7db59 )
by Tristan
07:12
created

resources/assets/js/components/ApplicantProfile/Experience/AwardExperienceProfileModal.tsx   A

Complexity

Total Complexity 5
Complexity/F 0

Size

Lines of Code 145
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 5
eloc 114
mnd 5
bc 5
fnc 0
dl 0
loc 145
rs 10
bpm 0
cpm 0
noi 0
c 0
b 0
f 0
1
import React, { FunctionComponent } from "react";
2
import { Formik, Form } from "formik";
3
import { useIntl } from "react-intl";
4
import * as Yup from "yup";
5
import {
6
  ProfileSkillSubform,
7
  SkillFormValues,
8
  submitDataToFormSkills,
9
  validationShape as skillValidationShape,
10
} from "./ProfileSkillSubform";
11
import { Skill, ExperienceAward, ExperienceSkill } from "../../../models/types";
12
import { ExperienceSubmitData } from "./ExperienceModalCommon";
13
import {
14
  ExperienceModalHeader,
15
  ExperienceDetailsIntro,
16
  ExperienceModalFooter,
17
} from "../../Application/ExperienceModals/ExperienceModalCommon";
18
import Modal from "../../Modal";
19
import {
20
  AwardDetailsSubform,
21
  awardValidationShape,
22
  messages,
23
  experienceToDetails,
24
  newExperienceAward,
25
  detailsToExperience,
26
  AwardDetailsFormValues,
27
  FormAwardRecipientType,
28
  FormAwardRecognitionType,
29
} from "../../Application/ExperienceModals/AwardExperienceModal";
30
31
type AwardExperienceFormValues = SkillFormValues & AwardDetailsFormValues;
32
33
const dataToFormValues = (
34
  data: ExperienceSubmitData<ExperienceAward>,
35
  allSkills: Skill[],
36
  creatingNew: boolean,
37
): AwardExperienceFormValues => {
38
  return {
39
    ...experienceToDetails(data.experience, creatingNew),
40
    ...submitDataToFormSkills(data, allSkills),
41
  };
42
};
43
44
interface ProfileAwardModalProps {
45
  modalId: string;
46
  experienceAward: ExperienceAward | null;
47
  recipientTypes: FormAwardRecipientType[];
48
  recognitionTypes: FormAwardRecognitionType[];
49
  experienceableId: number;
50
  experienceableType: ExperienceAward["experienceable_type"];
51
  userSkills: Skill[];
52
  experienceSkills: ExperienceSkill[];
53
  parentElement: Element | null;
54
  visible: boolean;
55
  onModalCancel: () => void;
56
  onModalConfirm: (data: ExperienceAward) => Promise<void>;
57
}
58
59
export const ProfileAwardModal: FunctionComponent<ProfileAwardModalProps> = ({
60
  modalId,
61
  experienceAward,
62
  recipientTypes,
63
  recognitionTypes,
64
  experienceableId,
65
  experienceableType,
66
  userSkills,
67
  experienceSkills,
68
  parentElement,
69
  visible,
70
  onModalCancel,
71
  onModalConfirm,
72
}) => {
73
  const intl = useIntl();
74
75
  const originalExperience =
76
    experienceAward ?? newExperienceAward(experienceableId, experienceableType);
77
78
  const relevantExperienceSkills = experienceSkills.filter(
79
    (expSkill) =>
80
      expSkill.experience_id === experienceAward?.id &&
81
      expSkill.experience_type === "experience_award",
82
  );
83
84
  const validationSchema = Yup.object().shape({
85
    ...awardValidationShape(intl),
86
    ...skillValidationShape(intl),
87
  });
88
89
  const initialFormValues = dataToFormValues(
90
    {
91
      experience: originalExperience,
92
      savedSkills: relevantExperienceSkills.map((expSkill) => ({
93
        skillId: expSkill.skill_id,
94
        justification: expSkill.justification ?? "",
95
      })),
96
    },
97
    userSkills,
98
    experienceAward === null,
99
  );
100
101
  return (
102
    <Modal
103
      id={modalId}
104
      parentElement={parentElement}
105
      visible={visible}
106
      onModalCancel={onModalCancel}
107
      onModalConfirm={onModalCancel}
108
      className="application-experience-dialog"
109
    >
110
      <ExperienceModalHeader
111
        title={intl.formatMessage(messages.modalTitle)}
112
        iconClass="fa-trophy"
113
      />
114
      <Formik
115
        enableReinitialize
116
        initialValues={initialFormValues}
117
        onSubmit={async (values, actions): Promise<void> => {
118
          await onModalConfirm(detailsToExperience(values, originalExperience));
119
          actions.setSubmitting(false);
120
          actions.resetForm();
121
        }}
122
        validationSchema={validationSchema}
123
      >
124
        {(formikProps): React.ReactElement => (
125
          <Form>
126
            <Modal.Body>
127
              <ExperienceDetailsIntro
128
                description={intl.formatMessage(messages.modalDescription)}
129
              />
130
              <AwardDetailsSubform
131
                recipientTypes={recipientTypes}
132
                recognitionTypes={recognitionTypes}
133
              />
134
              <ProfileSkillSubform keyPrefix="award" skills={userSkills} />
135
            </Modal.Body>
136
            <ExperienceModalFooter buttonsDisabled={formikProps.isSubmitting} />
137
          </Form>
138
        )}
139
      </Formik>
140
    </Modal>
141
  );
142
};
143
144
export default ProfileAwardModal;
145