Passed
Push — dev ( 15f923...8fee54 )
by Yonathan
05:40 queued 12s
created

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

Complexity

Total Complexity 5
Complexity/F 0

Size

Lines of Code 165
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 5
eloc 132
c 0
b 0
f 0
dl 0
loc 165
rs 10
mnd 5
bc 5
fnc 0
bpm 0
cpm 0
noi 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
  dataToFormSkills,
9
  validationShape as skillValidationShape,
10
  formSkillsToData,
11
} from "./ProfileSkillSubform";
12
import {
13
  Skill,
14
  ExperienceEducation,
15
  ExperienceSkill,
16
} from "../../../models/types";
17
import { ExperienceSubmitData } from "./ProfileExperienceCommon";
18
import {
19
  ExperienceModalHeader,
20
  ExperienceDetailsIntro,
21
  ExperienceModalFooter,
22
} from "../../Application/ExperienceModals/ExperienceModalCommon";
23
import Modal from "../../Modal";
24
import {
25
  EducationDetailsSubform,
26
  EducationDetailsFormValues,
27
  newExperienceEducation,
28
  experienceToDetails,
29
  educationExperienceValidationShape,
30
  detailsToExperience,
31
  messages,
32
  FormEducationType,
33
  FormEducationStatus,
34
} from "../../Application/ExperienceModals/EducationExperienceModal";
35
import { getId } from "../../../helpers/queries";
36
37
type EducationExperienceFormValues = SkillFormValues &
38
  EducationDetailsFormValues;
39
40
const dataToFormValues = (
41
  data: ExperienceSubmitData<ExperienceEducation>,
42
  allSkills: Skill[],
43
  creatingNew: boolean,
44
): EducationExperienceFormValues => {
45
  return {
46
    ...experienceToDetails(data.experience, creatingNew),
47
    ...dataToFormSkills(data, allSkills),
48
  };
49
};
50
51
const formValuesToData = (
52
  formValues: EducationExperienceFormValues,
53
  originalExperience: ExperienceEducation,
54
): ExperienceSubmitData<ExperienceEducation> => {
55
  return {
56
    experience: detailsToExperience(formValues, originalExperience),
57
    savedSkills: formSkillsToData(formValues),
58
  };
59
};
60
61
interface ProfileEducationModalProps {
62
  modalId: string;
63
  experienceEducation: ExperienceEducation | null;
64
  educationTypes: FormEducationType[];
65
  educationStatuses: FormEducationStatus[];
66
  experienceableId: number;
67
  experienceableType: ExperienceEducation["experienceable_type"];
68
  userSkills: Skill[];
69
  experienceSkills: ExperienceSkill[];
70
  parentElement: Element | null;
71
  visible: boolean;
72
  onModalCancel: () => void;
73
  onModalConfirm: (
74
    experience: ExperienceSubmitData<ExperienceEducation>,
75
  ) => Promise<void>;
76
}
77
78
export const ProfileEducationModal: FunctionComponent<ProfileEducationModalProps> = ({
79
  modalId,
80
  experienceEducation,
81
  educationTypes,
82
  educationStatuses,
83
  experienceableId,
84
  experienceableType,
85
  userSkills,
86
  experienceSkills,
87
  parentElement,
88
  visible,
89
  onModalCancel,
90
  onModalConfirm,
91
}) => {
92
  const intl = useIntl();
93
94
  const originalExperience =
95
    experienceEducation ??
96
    newExperienceEducation(experienceableId, experienceableType);
97
98
  const relevantExperienceSkills = experienceSkills.filter(
99
    (expSkill) =>
100
      expSkill.experience_id === experienceEducation?.id &&
101
      expSkill.experience_type === "experience_education",
102
  );
103
104
  const validationSchema = Yup.object().shape({
105
    ...educationExperienceValidationShape(intl),
106
    ...skillValidationShape(intl, userSkills.map(getId)),
107
  });
108
109
  const initialFormValues = dataToFormValues(
110
    {
111
      experience: originalExperience,
112
      savedSkills: relevantExperienceSkills.map((expSkill) => ({
113
        skillId: expSkill.skill_id,
114
        justification: expSkill.justification ?? "",
115
      })),
116
    },
117
    userSkills,
118
    experienceEducation === null,
119
  );
120
121
  return (
122
    <Modal
123
      id={modalId}
124
      parentElement={parentElement}
125
      visible={visible}
126
      onModalCancel={onModalCancel}
127
      onModalConfirm={onModalCancel}
128
      className="application-experience-dialog"
129
    >
130
      <ExperienceModalHeader
131
        title={intl.formatMessage(messages.modalTitle)}
132
        iconClass="fa-book"
133
      />
134
      <Formik
135
        enableReinitialize
136
        initialValues={initialFormValues}
137
        onSubmit={async (values, actions): Promise<void> => {
138
          await onModalConfirm(formValuesToData(values, originalExperience));
139
          actions.setSubmitting(false);
140
          actions.resetForm();
141
        }}
142
        validationSchema={validationSchema}
143
      >
144
        {(formikProps): React.ReactElement => (
145
          <Form>
146
            <Modal.Body>
147
              <ExperienceDetailsIntro
148
                description={intl.formatMessage(messages.modalDescription)}
149
              />
150
              <EducationDetailsSubform
151
                educationTypes={educationTypes}
152
                educationStatuses={educationStatuses}
153
              />
154
              <ProfileSkillSubform keyPrefix="education" skills={userSkills} />
155
            </Modal.Body>
156
            <ExperienceModalFooter buttonsDisabled={formikProps.isSubmitting} />
157
          </Form>
158
        )}
159
      </Formik>
160
    </Modal>
161
  );
162
};
163
164
export default ProfileEducationModal;
165