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

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

Complexity

Total Complexity 5
Complexity/F 0

Size

Lines of Code 139
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

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