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

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

Complexity

Total Complexity 5
Complexity/F 0

Size

Lines of Code 154
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

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