Passed
Push — task/application-handle-step-s... ( d6d197...5a9035 )
by Yonathan
07:49
created

resources/assets/js/components/Application/Experience/Experience.tsx   F

Complexity

Total Complexity 67
Complexity/F 0

Size

Lines of Code 754
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 67
eloc 641
mnd 67
bc 67
fnc 0
dl 0
loc 754
rs 2.999
bpm 0
cpm 0
noi 0
c 0
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like resources/assets/js/components/Application/Experience/Experience.tsx often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/* eslint-disable camelcase */
2
/* eslint-disable @typescript-eslint/camelcase */
3
import * as React from "react";
4
import { FormattedMessage, useIntl, defineMessages } from "react-intl";
5
import {
6
  Skill,
7
  ExperienceEducation,
8
  ExperienceWork,
9
  ExperienceCommunity,
10
  Experience,
11
  ExperiencePersonal,
12
  ExperienceAward,
13
  ExperienceSkill,
14
  Criteria,
15
} from "../../../models/types";
16
import { localizeFieldNonNull, getLocale } from "../../../helpers/localize";
17
import {
18
  SkillTypeId,
19
  CriteriaTypeId,
20
  getKeyByValue,
21
  ClassificationId,
22
} from "../../../models/lookupConstants";
23
import EducationExperienceModal, {
24
  messages as educationMessages,
25
  EducationType,
26
  EducationStatus,
27
  EducationExperienceSubmitData,
28
} from "../ExperienceModals/EducationExperienceModal";
29
30
import WorkExperienceModal, {
31
  messages as workMessages,
32
  WorkExperienceSubmitData,
33
} from "../ExperienceModals/WorkExperienceModal";
34
import CommunityExperienceModal, {
35
  messages as communityMessages,
36
  CommunityExperienceSubmitData,
37
} from "../ExperienceModals/CommunityExperienceModal";
38
import PersonalExperienceModal, {
39
  messages as personalMessages,
40
  PersonalExperienceSubmitData,
41
} from "../ExperienceModals/PersonalExperienceModal";
42
import AwardExperienceModal, {
43
  messages as awardMessages,
44
  AwardRecipientType,
45
  AwardRecognitionType,
46
  AwardExperienceSubmitData,
47
} from "../ExperienceModals/AwardExperienceModal";
48
import ExperienceEducationAccordion from "../ExperienceAccordions/ExperienceEducationAccordion";
49
import ExperienceWorkAccordion from "../ExperienceAccordions/ExperienceWorkAccordion";
50
import ExperienceCommunityAccordion from "../ExperienceAccordions/ExperienceCommunityAccordion";
51
import ExperiencePersonalAccordion from "../ExperienceAccordions/ExperiencePersonalAccordion";
52
import ExperienceAwardAccordion from "../ExperienceAccordions/ExperienceAwardAccordion";
53
import {
54
  getSkillOfCriteria,
55
  getSkillsOfExperience,
56
  getDisconnectedRequiredSkills,
57
} from "../helpers";
58
import { navigationMessages, experienceMessages } from "../applicationMessages";
59
import { notEmpty, removeDuplicatesById } from "../../../helpers/queries";
60
61
const messages = defineMessages({
62
  educationTypeMissing: {
63
    id: "application.experience.educationTypeMissing",
64
    defaultMessage: "Education type not found",
65
    description: "Error message for when the education type cannot be found.",
66
  },
67
  educationStatusMissing: {
68
    id: "application.experience.educationStatusMissing",
69
    defaultMessage: "Education status not found",
70
    description: "Error message for when the education status cannot be found.",
71
  },
72
  awardRecipientMissing: {
73
    id: "application.experience.awardRecipientMissing",
74
    defaultMessage: "Award recipient not found",
75
    description: "Error message for when the award recipient cannot be found.",
76
  },
77
  awardRecognitionMissing: {
78
    id: "application.experience.awardRecognitionMissing",
79
    defaultMessage: "Award recognition not found",
80
    description:
81
      "Error message for when the award recognition cannot be found.",
82
  },
83
  errorRenderingExperience: {
84
    id: "application.experience.errorRenderingExperience",
85
    defaultMessage: "Experience failed to render (experience type missing).",
86
    description: "Error message displayed when experience fails to render.",
87
  },
88
});
89
90
export type ExperienceSubmitData =
91
  | EducationExperienceSubmitData
92
  | WorkExperienceSubmitData
93
  | CommunityExperienceSubmitData
94
  | PersonalExperienceSubmitData
95
  | AwardExperienceSubmitData;
96
97
interface ExperienceProps {
98
  experiences: Experience[];
99
  educationStatuses: EducationStatus[];
100
  educationTypes: EducationType[];
101
  experienceSkills: ExperienceSkill[];
102
  criteria: Criteria[];
103
  skills: Skill[];
104
  jobId: number;
105
  jobClassificationId: number | null;
106
  jobEducationRequirements: string | null;
107
  recipientTypes: AwardRecipientType[];
108
  recognitionTypes: AwardRecognitionType[];
109
  handleSubmitExperience: (data: ExperienceSubmitData) => Promise<void>;
110
  handleDeleteExperience: (
111
    id: number,
112
    type: Experience["type"],
113
  ) => Promise<void>;
114
  handleContinue: () => void;
115
  handleQuit: () => void;
116
  handleReturn: () => void;
117
}
118
119
const MyExperience: React.FunctionComponent<ExperienceProps> = ({
120
  experiences,
121
  educationStatuses,
122
  educationTypes,
123
  experienceSkills,
124
  criteria,
125
  skills,
126
  handleSubmitExperience,
127
  handleDeleteExperience,
128
  jobId,
129
  jobClassificationId,
130
  jobEducationRequirements,
131
  recipientTypes,
132
  recognitionTypes,
133
  handleContinue,
134
  handleQuit,
135
  handleReturn,
136
}) => {
137
  const intl = useIntl();
138
  const locale = getLocale(intl.locale);
139
140
  const jobClassification =
141
    jobClassificationId !== null
142
      ? getKeyByValue(ClassificationId, jobClassificationId)
143
      : "";
144
145
  const [experienceData, setExperienceData] = React.useState<
146
    | (Experience & {
147
        savedOptionalSkills: Skill[];
148
        savedRequiredSkills: Skill[];
149
      })
150
    | null
151
  >(null);
152
153
  const [isModalVisible, setIsModalVisible] = React.useState<{
154
    id: Experience["type"] | "";
155
    visible: boolean;
156
  }>({
157
    id: "",
158
    visible: false,
159
  });
160
161
  const filteredSkills = criteria.reduce(
162
    (result, criterion): { essential: Skill[]; asset: Skill[] } => {
163
      const skillOfCriterion = getSkillOfCriteria(criterion, skills);
164
      if (skillOfCriterion) {
165
        if (criterion.criteria_type_id === CriteriaTypeId.Essential) {
166
          result.essential.push(skillOfCriterion);
167
        }
168
        if (criterion.criteria_type_id === CriteriaTypeId.Asset) {
169
          result.asset.push(skillOfCriterion);
170
        }
171
      }
172
      return result;
173
    },
174
    { essential: [], asset: [] } as { essential: Skill[]; asset: Skill[] },
175
  );
176
177
  const essentialSkills = removeDuplicatesById(filteredSkills.essential);
178
  const assetSkills = removeDuplicatesById(filteredSkills.asset);
179
180
  const disconnectedRequiredSkills = getDisconnectedRequiredSkills(
181
    experiences,
182
    experienceSkills,
183
    essentialSkills,
184
  );
185
186
  const openModal = (id: Experience["type"]): void => {
187
    setIsModalVisible({ id, visible: true });
188
  };
189
190
  const closeModal = (): void => {
191
    setExperienceData(null);
192
    setIsModalVisible({ id: "", visible: false });
193
  };
194
195
  const submitExperience = (data: ExperienceSubmitData): Promise<void> =>
196
    handleSubmitExperience(data).then(closeModal);
197
198
  const editExperience = (
199
    experience: Experience,
200
    savedOptionalSkills: Skill[],
201
    savedRequiredSkills: Skill[],
202
  ): void => {
203
    setExperienceData({
204
      ...experience,
205
      savedOptionalSkills,
206
      savedRequiredSkills,
207
    });
208
    setIsModalVisible({ id: experience.type, visible: true });
209
  };
210
211
  const deleteExperience = (experience: Experience): Promise<void> =>
212
    handleDeleteExperience(experience.id, experience.type).then(closeModal);
213
214
  const softSkills = removeDuplicatesById(
215
    [...assetSkills, ...essentialSkills].filter(
216
      (skill) => skill.skill_type_id === SkillTypeId.Soft,
217
    ),
218
  );
219
220
  const modalButtons: {
221
    [key: string]: { id: Experience["type"]; title: string; icon: string };
222
  } = {
223
    education: {
224
      id: "experience_education",
225
      title: intl.formatMessage(educationMessages.modalTitle),
226
      icon: "fas fa-book",
227
    },
228
    work: {
229
      id: "experience_work",
230
      title: intl.formatMessage(workMessages.modalTitle),
231
      icon: "fas fa-briefcase",
232
    },
233
    community: {
234
      id: "experience_community",
235
      title: intl.formatMessage(communityMessages.modalTitle),
236
      icon: "fas fa-people-carry",
237
    },
238
    personal: {
239
      id: "experience_personal",
240
      title: intl.formatMessage(personalMessages.modalTitle),
241
      icon: "fas fa-mountain",
242
    },
243
    award: {
244
      id: "experience_award",
245
      title: intl.formatMessage(awardMessages.modalTitle),
246
      icon: "fas fa-trophy",
247
    },
248
  };
249
250
  const modalButton = ({ id, title, icon }): React.ReactElement => (
251
    <div key={id} data-c-grid-item="base(1of2) tp(1of3) tl(1of5)">
252
      <button
253
        className="application-experience-trigger"
254
        data-c-card
255
        data-c-background="c1(100)"
256
        data-c-radius="rounded"
257
        title={title}
258
        data-c-dialog-id={id}
259
        data-c-dialog-action="open"
260
        type="button"
261
        onClick={(): void => openModal(id)}
262
      >
263
        <i className={icon} aria-hidden="true" />
264
        <span data-c-font-size="regular" data-c-font-weight="bold">
265
          {title}
266
        </span>
267
      </button>
268
    </div>
269
  );
270
271
  const modalRoot = document.getElementById("modal-root");
272
273
  const experienceAccordion = (
274
    experience: Experience,
275
    irrelevantSkillCount: number,
276
    relevantSkills: ExperienceSkill[],
277
    handleEdit: () => void,
278
    handleDelete: () => Promise<void>,
279
  ): React.ReactElement => {
280
    switch (experience.type) {
281
      case "experience_education":
282
        return (
283
          <ExperienceEducationAccordion
284
            key={`${experience.id}-${experience.type}`}
285
            areaOfStudy={experience.area_of_study}
286
            educationType={localizeFieldNonNull(
287
              locale,
288
              experience,
289
              "education_type",
290
            )}
291
            endDate={experience.end_date}
292
            handleDelete={handleDelete}
293
            handleEdit={handleEdit}
294
            institution={experience.institution}
295
            irrelevantSkillCount={irrelevantSkillCount}
296
            isActive={experience.is_active}
297
            isEducationJustification={experience.is_education_requirement}
298
            relevantSkills={relevantSkills}
299
            skills={skills}
300
            showButtons
301
            showSkillDetails
302
            startDate={experience.start_date}
303
            status={localizeFieldNonNull(
304
              locale,
305
              experience,
306
              "education_status",
307
            )}
308
            thesisTitle={experience.thesis_title}
309
          />
310
        );
311
      case "experience_work":
312
        return (
313
          <ExperienceWorkAccordion
314
            key={`${experience.id}-${experience.type}`}
315
            endDate={experience.end_date}
316
            group={experience.group}
317
            handleDelete={handleDelete}
318
            handleEdit={handleEdit}
319
            irrelevantSkillCount={irrelevantSkillCount}
320
            isActive={experience.is_active}
321
            isEducationJustification={experience.is_education_requirement}
322
            organization={experience.organization}
323
            relevantSkills={relevantSkills}
324
            skills={skills}
325
            showButtons
326
            showSkillDetails
327
            startDate={experience.start_date}
328
            title={experience.title}
329
          />
330
        );
331
      case "experience_community":
332
        return (
333
          <ExperienceCommunityAccordion
334
            key={`${experience.id}-${experience.type}`}
335
            endDate={experience.end_date}
336
            group={experience.group}
337
            handleDelete={handleDelete}
338
            handleEdit={handleEdit}
339
            irrelevantSkillCount={irrelevantSkillCount}
340
            isActive={experience.is_active}
341
            isEducationJustification={experience.is_education_requirement}
342
            project={experience.project}
343
            relevantSkills={relevantSkills}
344
            skills={skills}
345
            showButtons
346
            showSkillDetails
347
            startDate={experience.start_date}
348
            title={experience.title}
349
          />
350
        );
351
      case "experience_personal":
352
        return (
353
          <ExperiencePersonalAccordion
354
            key={`${experience.id}-${experience.type}`}
355
            description={experience.description}
356
            endDate={experience.end_date}
357
            handleDelete={handleDelete}
358
            handleEdit={handleEdit}
359
            irrelevantSkillCount={irrelevantSkillCount}
360
            isActive={experience.is_active}
361
            isEducationJustification={experience.is_education_requirement}
362
            isShareable={experience.is_shareable}
363
            relevantSkills={relevantSkills}
364
            skills={skills}
365
            showButtons
366
            showSkillDetails
367
            startDate={experience.start_date}
368
            title={experience.title}
369
          />
370
        );
371
      case "experience_award":
372
        return (
373
          <ExperienceAwardAccordion
374
            key={`${experience.id}-${experience.type}`}
375
            awardedDate={experience.awarded_date}
376
            handleDelete={handleDelete}
377
            handleEdit={handleEdit}
378
            irrelevantSkillCount={irrelevantSkillCount}
379
            isEducationJustification={experience.is_education_requirement}
380
            issuer={experience.issued_by}
381
            recipient={localizeFieldNonNull(
382
              locale,
383
              experience,
384
              "award_recipient_type",
385
            )}
386
            relevantSkills={relevantSkills}
387
            skills={skills}
388
            scope={localizeFieldNonNull(
389
              locale,
390
              experience,
391
              "award_recognition_type",
392
            )}
393
            showButtons
394
            showSkillDetails
395
            title={experience.title}
396
          />
397
        );
398
      default:
399
        return (
400
          <div
401
            data-c-background="gray(10)"
402
            data-c-radius="rounded"
403
            data-c-border="all(thin, solid, gray)"
404
            data-c-margin="top(1)"
405
            data-c-padding="all(1)"
406
          >
407
            <div data-c-align="base(center)">
408
              <p data-c-color="stop">
409
                {intl.formatMessage(messages.errorRenderingExperience)}
410
              </p>
411
            </div>
412
          </div>
413
        );
414
    }
415
  };
416
417
  return (
418
    <>
419
      <div data-c-container="medium">
420
        <h2 data-c-heading="h2" data-c-margin="top(3) bottom(1)">
421
          {intl.formatMessage(experienceMessages.heading)}
422
        </h2>
423
        <p data-c-margin="bottom(1)">
424
          <FormattedMessage
425
            id="application.experience.preamble"
426
            defaultMessage="Use the buttons below to add experiences you want to share with the manager. Experiences you have added in the past also appear below, and you can edit them to link them to skills required for this job when necessary."
427
            description="First section of text on the experience step of the Application Timeline."
428
          />
429
        </p>
430
        <div data-c-grid="gutter(all, 1)">
431
          {essentialSkills.length > 0 && (
432
            <div data-c-grid-item="tl(1of2)">
433
              <p data-c-margin="bottom(.5)">
434
                <FormattedMessage
435
                  id="application.experience.essentialSkillsListIntro"
436
                  description="Text before the list of essential skills on the experience step of the Application Timeline."
437
                  defaultMessage="This job <span>requires</span> the following skills:"
438
                  values={{
439
                    span: (chunks): React.ReactElement => (
440
                      <span data-c-font-weight="bold" data-c-color="c2">
441
                        {chunks}
442
                      </span>
443
                    ),
444
                  }}
445
                />
446
              </p>
447
              <ul data-c-margin="bottom(1)">
448
                {essentialSkills.map((skill) => (
449
                  <li key={skill.id}>
450
                    {localizeFieldNonNull(locale, skill, "name")}
451
                  </li>
452
                ))}
453
              </ul>
454
            </div>
455
          )}
456
          {assetSkills.length > 0 && (
457
            <div data-c-grid-item="tl(1of2)">
458
              <p data-c-margin="bottom(.5)">
459
                <FormattedMessage
460
                  id="application.experience.assetSkillsListIntro"
461
                  defaultMessage="These skills are beneficial, but not required:"
462
                  description="Text before the list of asset skills on the experience step of the Application Timeline."
463
                />
464
              </p>
465
              <ul data-c-margin="bottom(1)">
466
                {assetSkills.map((skill) => (
467
                  <li key={skill.id}>
468
                    {localizeFieldNonNull(locale, skill, "name")}
469
                  </li>
470
                ))}
471
              </ul>
472
            </div>
473
          )}
474
        </div>
475
        <p data-c-color="gray" data-c-margin="bottom(2)">
476
          <FormattedMessage
477
            id="application.experience.softSkillsList"
478
            defaultMessage="Don't forget, {skill} will be evaluated later in the hiring process."
479
            description="List of soft skills that will be evaluated later."
480
            values={{
481
              skill: (
482
                <>
483
                  {softSkills.map((skill, index) => {
484
                    const and = " and ";
485
                    const lastElement = index === softSkills.length - 1;
486
                    return (
487
                      <React.Fragment key={skill.id}>
488
                        {lastElement && softSkills.length > 1 && and}
489
                        <span key={skill.id} data-c-font-weight="bold">
490
                          {localizeFieldNonNull(locale, skill, "name")}
491
                        </span>
492
                        {!lastElement && softSkills.length > 2 && ", "}
493
                      </React.Fragment>
494
                    );
495
                  })}
496
                </>
497
              ),
498
            }}
499
          />
500
        </p>
501
        {/* Experience Modal Buttons */}
502
        <div data-c-grid="gutter(all, 1)">
503
          {Object.keys(modalButtons).map((id) => modalButton(modalButtons[id]))}
504
        </div>
505
        {/* Experience Accordion List */}
506
        {experiences && experiences.length > 0 ? (
507
          <div className="experience-list" data-c-margin="top(2)">
508
            <div data-c-accordion-group>
509
              {experiences.map((experience) => {
510
                const savedOptionalSkills = getSkillsOfExperience(
511
                  experienceSkills,
512
                  experience,
513
                  assetSkills,
514
                );
515
                const savedRequiredSkills = getSkillsOfExperience(
516
                  experienceSkills,
517
                  experience,
518
                  essentialSkills,
519
                );
520
                const relevantSkills: ExperienceSkill[] = savedRequiredSkills
521
                  .map((skill) => {
522
                    return experienceSkills.find(
523
                      ({ experience_id, experience_type, skill_id }) =>
524
                        experience_id === experience.id &&
525
                        skill_id === skill.id &&
526
                        experience_type === experience.type,
527
                    );
528
                  })
529
                  .filter(notEmpty);
530
531
                // Number of skills attached to Experience but are not part of the jobs skill criteria.
532
                const irrelevantSkillCount =
533
                  experienceSkills.filter(
534
                    (experienceSkill) =>
535
                      experienceSkill.experience_id === experience.id &&
536
                      experienceSkill.experience_type === experience.type,
537
                  ).length -
538
                  (savedOptionalSkills.length + savedRequiredSkills.length);
539
540
                return experienceAccordion(
541
                  experience,
542
                  irrelevantSkillCount,
543
                  relevantSkills,
544
                  () =>
545
                    editExperience(
546
                      experience,
547
                      savedOptionalSkills,
548
                      savedRequiredSkills,
549
                    ),
550
                  () => deleteExperience(experience),
551
                );
552
              })}
553
            </div>
554
          </div>
555
        ) : (
556
          <div
557
            data-c-background="gray(10)"
558
            data-c-radius="rounded"
559
            data-c-border="all(thin, solid, gray)"
560
            data-c-margin="top(2)"
561
            data-c-padding="all(1)"
562
          >
563
            <div data-c-align="base(center)">
564
              <p data-c-color="gray">
565
                <FormattedMessage
566
                  id="application.experience.noExperiences"
567
                  defaultMessage="Looks like you don't have any experience added yet. Use the buttons above to add experience. Don't forget that experience will always be saved to your profile so that you can use it on future applications!"
568
                  description="Message displayed when application has no experiences."
569
                />
570
              </p>
571
            </div>
572
          </div>
573
        )}
574
        {disconnectedRequiredSkills && disconnectedRequiredSkills.length > 0 && (
575
          <p data-c-color="stop" data-c-margin="top(2)">
576
            <FormattedMessage
577
              id="application.experience.unconnectedSkills"
578
              defaultMessage="The following required skill(s) are not connected to your experience:"
579
              description="Message showing list of required skills that are not connected to a experience."
580
            />{" "}
581
            {disconnectedRequiredSkills.map((skill) => (
582
              <React.Fragment key={skill.id}>
583
                <span
584
                  data-c-tag="stop"
585
                  data-c-radius="pill"
586
                  data-c-font-size="small"
587
                >
588
                  {localizeFieldNonNull(locale, skill, "name")}
589
                </span>{" "}
590
              </React.Fragment>
591
            ))}
592
          </p>
593
        )}
594
      </div>
595
      <div data-c-container="medium" data-c-padding="tb(2)">
596
        <hr data-c-hr="thin(c1)" data-c-margin="bottom(2)" />
597
        <div data-c-grid="gutter">
598
          <div
599
            data-c-alignment="base(centre) tp(left)"
600
            data-c-grid-item="tp(1of2)"
601
          >
602
            <button
603
              data-c-button="outline(c2)"
604
              data-c-radius="rounded"
605
              type="button"
606
              onClick={(): void => handleReturn()}
607
            >
608
              {intl.formatMessage(navigationMessages.return)}
609
            </button>
610
          </div>
611
          <div
612
            data-c-alignment="base(centre) tp(right)"
613
            data-c-grid-item="tp(1of2)"
614
          >
615
            <button
616
              data-c-button="outline(c2)"
617
              data-c-radius="rounded"
618
              type="button"
619
              onClick={(): void => handleQuit()}
620
            >
621
              {intl.formatMessage(navigationMessages.quit)}
622
            </button>
623
            <button
624
              data-c-button="solid(c1)"
625
              data-c-radius="rounded"
626
              data-c-margin="left(1)"
627
              type="button"
628
              onClick={(): void => handleContinue()}
629
            >
630
              {intl.formatMessage(navigationMessages.continue)}
631
            </button>
632
          </div>
633
        </div>
634
      </div>
635
636
      <div data-c-dialog-overlay={isModalVisible.visible ? "active" : ""} />
637
      <EducationExperienceModal
638
        educationStatuses={educationStatuses}
639
        educationTypes={educationTypes}
640
        experienceEducation={experienceData as ExperienceEducation}
641
        experienceableId={experienceData?.experienceable_id ?? 0}
642
        experienceableType={
643
          experienceData?.experienceable_type ?? "application"
644
        }
645
        jobId={jobId}
646
        jobClassification={jobClassification}
647
        jobEducationRequirements={jobEducationRequirements}
648
        modalId={modalButtons.education.id}
649
        onModalCancel={closeModal}
650
        onModalConfirm={submitExperience}
651
        optionalSkills={assetSkills}
652
        parentElement={modalRoot}
653
        requiredSkills={essentialSkills}
654
        savedOptionalSkills={experienceData?.savedOptionalSkills ?? []}
655
        savedRequiredSkills={experienceData?.savedRequiredSkills ?? []}
656
        visible={
657
          isModalVisible.visible &&
658
          isModalVisible.id === modalButtons.education.id
659
        }
660
      />
661
      <WorkExperienceModal
662
        experienceWork={experienceData as ExperienceWork}
663
        experienceableId={experienceData?.experienceable_id ?? 0}
664
        experienceableType={
665
          experienceData?.experienceable_type ?? "application"
666
        }
667
        jobId={jobId}
668
        jobClassification={jobClassification}
669
        jobEducationRequirements={jobEducationRequirements}
670
        modalId={modalButtons.work.id}
671
        onModalCancel={closeModal}
672
        onModalConfirm={submitExperience}
673
        optionalSkills={assetSkills}
674
        parentElement={modalRoot}
675
        requiredSkills={essentialSkills}
676
        savedOptionalSkills={experienceData?.savedOptionalSkills ?? []}
677
        savedRequiredSkills={experienceData?.savedRequiredSkills ?? []}
678
        visible={
679
          isModalVisible.visible && isModalVisible.id === modalButtons.work.id
680
        }
681
      />
682
      <CommunityExperienceModal
683
        experienceCommunity={experienceData as ExperienceCommunity}
684
        experienceableId={experienceData?.experienceable_id ?? 0}
685
        experienceableType={
686
          experienceData?.experienceable_type ?? "application"
687
        }
688
        jobId={jobId}
689
        jobClassification={jobClassification}
690
        jobEducationRequirements={jobEducationRequirements}
691
        modalId={modalButtons.community.id}
692
        onModalCancel={closeModal}
693
        onModalConfirm={submitExperience}
694
        optionalSkills={assetSkills}
695
        parentElement={modalRoot}
696
        requiredSkills={essentialSkills}
697
        savedOptionalSkills={experienceData?.savedOptionalSkills ?? []}
698
        savedRequiredSkills={experienceData?.savedRequiredSkills ?? []}
699
        visible={
700
          isModalVisible.visible &&
701
          isModalVisible.id === modalButtons.community.id
702
        }
703
      />
704
      <PersonalExperienceModal
705
        experiencePersonal={experienceData as ExperiencePersonal}
706
        experienceableId={experienceData?.experienceable_id ?? 0}
707
        experienceableType={
708
          experienceData?.experienceable_type ?? "application"
709
        }
710
        jobId={jobId}
711
        jobClassification={jobClassification}
712
        jobEducationRequirements={jobEducationRequirements}
713
        modalId={modalButtons.personal.id}
714
        onModalCancel={closeModal}
715
        onModalConfirm={submitExperience}
716
        optionalSkills={assetSkills}
717
        parentElement={modalRoot}
718
        requiredSkills={essentialSkills}
719
        savedOptionalSkills={experienceData?.savedOptionalSkills ?? []}
720
        savedRequiredSkills={experienceData?.savedRequiredSkills ?? []}
721
        visible={
722
          isModalVisible.visible &&
723
          isModalVisible.id === modalButtons.personal.id
724
        }
725
      />
726
      <AwardExperienceModal
727
        experienceAward={experienceData as ExperienceAward}
728
        experienceableId={experienceData?.experienceable_id ?? 0}
729
        experienceableType={
730
          experienceData?.experienceable_type ?? "application"
731
        }
732
        jobId={jobId}
733
        jobClassification={jobClassification}
734
        jobEducationRequirements={jobEducationRequirements}
735
        modalId={modalButtons.award.id}
736
        onModalCancel={closeModal}
737
        onModalConfirm={submitExperience}
738
        optionalSkills={assetSkills}
739
        parentElement={modalRoot}
740
        recipientTypes={recipientTypes}
741
        recognitionTypes={recognitionTypes}
742
        requiredSkills={essentialSkills}
743
        savedOptionalSkills={experienceData?.savedOptionalSkills ?? []}
744
        savedRequiredSkills={experienceData?.savedRequiredSkills ?? []}
745
        visible={
746
          isModalVisible.visible && isModalVisible.id === modalButtons.award.id
747
        }
748
      />
749
    </>
750
  );
751
};
752
753
export default MyExperience;
754