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

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

Complexity

Total Complexity 5
Complexity/F 0

Size

Lines of Code 146
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

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