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

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

Complexity

Total Complexity 5
Complexity/F 0

Size

Lines of Code 153
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

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