resources/assets/js/models/localizedConstants.tsx   A
last analyzed

Complexity

Total Complexity 8
Complexity/F 0

Size

Lines of Code 1323
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 8
eloc 1052
mnd 8
bc 8
fnc 0
dl 0
loc 1323
rs 9.392
bpm 0
cpm 0
noi 0
c 0
b 0
f 0
1
/* eslint camelcase: "off" */
2
import { defineMessages, MessageDescriptor, IntlShape } from "react-intl";
3
import {
4
  AssessmentTypeId,
5
  AssessmentTypeIdValues,
6
  CriteriaTypeId,
7
  CriteriaTypeIdValues,
8
  SkillLevelId,
9
  SkillLevelIdValues,
10
  SkillTypeId,
11
  SkillTypeIdValues,
12
  ProvinceId,
13
  SecurityClearanceId,
14
  LanguageRequirementId,
15
  FrequencyId,
16
  OvertimeRequirementId,
17
  TravelRequirementId,
18
  LocationId,
19
  ResponseScreeningBuckets as ResponseBuckets,
20
  ReviewStatusId,
21
  ReviewStatusName,
22
  GCEmployeeStatus,
23
} from "./lookupConstants";
24
import { getOrThrowError } from "../helpers/queries";
25
import { Experience } from "./types";
26
27
const skillLevelDescriptions = defineMessages({
28
  hardBasic: {
29
    id: "skillLevel.hard.basic.description",
30
    defaultMessage:
31
      "You have the ability to accomplish basic tasks with steady supervision and clear direction. The tasks you’re assigned are clear and don’t involve significant complexity. Their impact is usually locally felt. As you advance in this category, you should be developing the ability to accomplish tasks of moderate complexity with steady supervision. You will also need to be able to accomplish basic tasks with little or no supervision. This level is usually associated with tasks that form the bulk of the work for lower level positions, such as junior analysts or entry level developers.",
32
    description: "Description of basic hard skill level.",
33
  },
34
  hardIntermediate: {
35
    id: "skillLevel.hard.intermediate.description",
36
    defaultMessage:
37
      "You have the ability to accomplish tasks of moderate complexity or moderate impact with supervision. The approach to the tasks, and how they are delivered, is determined by the supervisor. You contribute input and advice. You are able to advance the task, even in the face of small to moderate hurdles and complications. As you advance in this category, you should be developing the ability to accomplish tasks of significant complexity or larger impact with steady supervision. You will also need to be able to accomplish tasks of moderate complexity or impact with little or no supervision. This level is usually associated with tasks that form the bulk of the work for mid-level positions, such as analysts or developers.",
38
    description: "Description of intermediate skill level.",
39
  },
40
  hardAdvanced: {
41
    id: "skillLevel.hard.advanced.description",
42
    defaultMessage:
43
      "You have the ability to accomplish tasks of significant complexity or impact with supervision. You provide advice and input on the approach to the tasks, and how they are delivered, for the supervisor’s consideration. You are able to advance the task, even in the face of moderate to large hurdles and complications. As you advance in this category, you should be developing the ability to accomplish tasks of significant complexity or larger impact with only light levels of supervision, where you are effectively the lead on the initiative. You may also take on a role of training others in this skills set or take on a light supervisory role for those at lower levels. This level is usually associated with tasks that form the bulk of the work for higher level positions, such as senior analysts or senior developers.",
44
    description: "Description of advanced hard skill level.",
45
  },
46
  hardExpert: {
47
    id: "skillLevel.hard.expert.description",
48
    defaultMessage:
49
      "You have the ability to accomplish tasks of significant complexity or impact, where you call the shots and answer to the organization’s senior management for your decisions. You bring forward the tasks, the approach and the delivery plan for senior management consideration. You often supervise others (individuals or teams) in delivering tasks of high complexity or system wide impact. You are able to advance these tasks, even in the face of significant unforeseen hurdles and complications. As you advance in this category, you should be developing the ability to assess others at more junior levels, becoming able to clearly identify the difference between beginner, intermediate and advanced tasks. You should be able to build teams, set direction and provide supervision. This level is usually associated with tasks that form the bulk of the work for management and executive level positions.",
50
    description: "Description of expert hard skill level.",
51
  },
52
  softBasic: {
53
    id: "skillLevel.soft.basic.description",
54
    defaultMessage:
55
      "You’re working on acquiring this skill or attribute. You are able to demonstrate it under favourable conditions (low stress, minimal difficulty) and can apply it in a work context intermittently.",
56
    description: "Description of soft basic skill level.",
57
  },
58
  softIntermediate: {
59
    id: "skillLevel.soft.intermediate.description",
60
    defaultMessage:
61
      "You’re able to consistently demonstrate this skill or attribute in the workplace, including under conditions of low-to-moderate stress or difficulty. Your peers and supervisors are able to attest to the fact that you have been able to demonstrate this skill or attribute on a regular basis.",
62
    description: "Description of soft intermediate skill level.",
63
  },
64
  softAdvanced: {
65
    id: "skillLevel.soft.advanced.description",
66
    defaultMessage:
67
      "You’re able to consistently demonstrate this skill or attribute in the workplace, including under conditions of high stress or difficulty. Your peers and supervisors recognize this as a strength you demonstrate in the workplace.",
68
    description: "Description of soft advanced skill level.",
69
  },
70
  softExpert: {
71
    id: "skillLevel.soft.expert.description",
72
    defaultMessage:
73
      "This is a foundational part of who you are. You consistently demonstrate this skill or attribute, even under conditions of extreme stress or difficulty. Your peers and supervisors recognize this as a significant strength you demonstrate in the workplace, providing an example to others.",
74
    description: "Description of expert soft skill level.",
75
  },
76
  asset: {
77
    id: "skillLevel.asset.description",
78
    defaultMessage:
79
      "This skill isn't required for the employee to do the job, but it provides an added benefit to their skillset and will improve the speed or effectiveness of their work.",
80
    description: "Description of what it means to be an 'Asset' skill.",
81
  },
82
});
83
84
const skillLevelNames = defineMessages({
85
  hardBasic: {
86
    id: "skillLevel.hard.basic.name",
87
    defaultMessage: "Beginner",
88
    description: "Single-word descriptor of basic hard skill level.",
89
  },
90
  hardIntermediate: {
91
    id: "skillLevel.hard.intermediate.name",
92
    defaultMessage: "Intermediate",
93
    description: "Single-word descriptor of intermediate hard skill level.",
94
  },
95
  hardAdvanced: {
96
    id: "skillLevel.hard.advanced.name",
97
    defaultMessage: "Advanced",
98
    description: "Single-word descriptor of advanced hard skill level.",
99
  },
100
  hardExpert: {
101
    id: "skillLevel.hard.expert.name",
102
    defaultMessage: "Expert",
103
    description: "Single-word descriptor of expert hard skill level.",
104
  },
105
  softBasic: {
106
    id: "skillLevel.soft.basic.name",
107
    defaultMessage: "In Early Development",
108
    description: "Single-word descriptor of soft basic skill level.",
109
  },
110
  softIntermediate: {
111
    id: "skillLevel.soft.intermediate.name",
112
    defaultMessage: "Moderately in Evidence",
113
    description: "Single-word descriptor of soft intermediate skill level.",
114
  },
115
  softAdvanced: {
116
    id: "skillLevel.soft.advanced.name",
117
    defaultMessage: "Strongly in Evidence",
118
    description: "Single-word descriptor of soft advanced skill level.",
119
  },
120
  softExpert: {
121
    id: "skillLevel.soft.expert.name",
122
    defaultMessage: "Deep Level Demonstration",
123
    description: "Single-word descriptor of soft expert skill level.",
124
  },
125
  asset: {
126
    id: "skillLevel.asset.name",
127
    defaultMessage: "Asset / No Level Required",
128
    description: "Name for 'Asset' skills.",
129
  },
130
});
131
132
const skillLevelL10n = (
133
  skillLevelId: number,
134
  skillTypeId: number,
135
  l10nObj: Record<
136
    string,
137
    {
138
      id: string;
139
      defaultMessage: string;
140
      description: string;
141
    }
142
  >,
143
): MessageDescriptor => {
144
  if (!SkillLevelIdValues.includes(skillLevelId)) {
145
    throw new Error("invalid SkillLevelIdValue");
146
  }
147
  if (!SkillTypeIdValues.includes(skillTypeId)) {
148
    throw new Error("invalid SkillTypeIdValue");
149
  }
150
  const basicKey = SkillLevelId.Basic.toString();
151
  const intermediateKey = SkillLevelId.Intermediate.toString();
152
  const advancedKey = SkillLevelId.Advanced.toString();
153
  const expertKey = SkillLevelId.Expert.toString();
154
  return {
155
    [SkillTypeId.Hard.toString()]: {
156
      [basicKey]: l10nObj.hardBasic,
157
      [intermediateKey]: l10nObj.hardIntermediate,
158
      [advancedKey]: l10nObj.hardAdvanced,
159
      [expertKey]: l10nObj.hardExpert,
160
    },
161
    [SkillTypeId.Soft.toString()]: {
162
      [basicKey]: l10nObj.softBasic,
163
      [intermediateKey]: l10nObj.softIntermediate,
164
      [advancedKey]: l10nObj.softAdvanced,
165
      [expertKey]: l10nObj.softExpert,
166
    },
167
  }[skillTypeId.toString()][skillLevelId.toString()];
168
};
169
170
export const skillLevelDescription = (
171
  skillLevelId: number,
172
  skillTypeId: number,
173
): MessageDescriptor =>
174
  skillLevelL10n(skillLevelId, skillTypeId, skillLevelDescriptions);
175
176
export const skillLevelName = (
177
  skillLevelId: number,
178
  skillTypeId: number,
179
): MessageDescriptor =>
180
  skillLevelL10n(skillLevelId, skillTypeId, skillLevelNames);
181
182
const assessmentTypes = defineMessages({
183
  [AssessmentTypeId.NarrativeAssessment]: {
184
    id: "assessmentType.narrativeAssessment",
185
    defaultMessage: "Narrative Review",
186
    description: "Title of an assessment type.",
187
  },
188
  [AssessmentTypeId.ApplicationScreeningQuestion]: {
189
    id: "assessmentType.applicationScreeningQuestion",
190
    defaultMessage: "Application Screening Question",
191
    description: "Title of an assessment type.",
192
  },
193
  [AssessmentTypeId.GroupTest]: {
194
    id: "assessmentType.groupTest",
195
    defaultMessage: "Group Test",
196
    description: "Title of an assessment type.",
197
  },
198
  [AssessmentTypeId.InformalPhoneConversation]: {
199
    id: "assessmentType.informalPhoneConversation",
200
    defaultMessage: "Informal Phone Conversation",
201
    description: "Title of an assessment type.",
202
  },
203
  [AssessmentTypeId.Interview]: {
204
    id: "assessmentType.interview",
205
    defaultMessage: "Interview",
206
    description: "Title of an assessment type.",
207
  },
208
  [AssessmentTypeId.OnlineExam]: {
209
    id: "assessmentType.onlineExam",
210
    defaultMessage: "Online Exam",
211
    description: "Title of an assessment type.",
212
  },
213
  [AssessmentTypeId.OnSiteExam]: {
214
    id: "assessmentType.onSiteExam",
215
    defaultMessage: "On-Site Exam",
216
    description: "Title of an assessment type.",
217
  },
218
  [AssessmentTypeId.TakeHomeExam]: {
219
    id: "assessmentType.takeHomeExam",
220
    defaultMessage: "Take Home Exam",
221
    description: "Title of an assessment type.",
222
  },
223
  [AssessmentTypeId.PortfolioReview]: {
224
    id: "assessmentType.portfolioReview",
225
    defaultMessage: "Portfolio Review",
226
    description: "Title of an assessment type.",
227
  },
228
  [AssessmentTypeId.ReferenceCheck]: {
229
    id: "assessmentType.referenceCheck",
230
    defaultMessage: "Reference Check",
231
    description: "Title of an assessment type.",
232
  },
233
  [AssessmentTypeId.SeriousGames]: {
234
    id: "assessmentType.seriousGames",
235
    defaultMessage: "Serious Games",
236
    description: "Title of an assessment type.",
237
  },
238
});
239
240
export const assetSkillName = (): MessageDescriptor => skillLevelNames.asset;
241
export const assetSkillDescription = (): MessageDescriptor =>
242
  skillLevelDescriptions.asset;
243
244
export const assessmentType = (assessmentTypeId: number): MessageDescriptor =>
245
  getOrThrowError(
246
    assessmentTypes,
247
    assessmentTypeId,
248
    "invalid AssessmentTypeValue",
249
  );
250
251
const criteriaTypes = defineMessages({
252
  [CriteriaTypeId.Asset]: {
253
    id: "criteriaType.asset",
254
    defaultMessage: "Asset",
255
    description: "Title of an asset criteria type.",
256
  },
257
  [CriteriaTypeId.Essential]: {
258
    id: "criteriaType.essential",
259
    defaultMessage: "Essential",
260
    description: "Title of an essential criteria type.",
261
  },
262
});
263
264
export const criteriaType = (criteriaTypeId: number): MessageDescriptor =>
265
  getOrThrowError(criteriaTypes, criteriaTypeId, "invalid CriteriaTypeValue");
266
267
const assessmentTypeDescriptions = defineMessages({
268
  [AssessmentTypeId.NarrativeAssessment]: {
269
    id: "assessmentType.narrativeAssessment.description",
270
    defaultMessage:
271
      "This is a description requested during the application process, in which applicants to self-identify and describe their experience and level of expertise with a skill.",
272
    description:
273
      "Description of an assessment type, to help a manager understand when to use it.",
274
  },
275
  [AssessmentTypeId.ApplicationScreeningQuestion]: {
276
    id: "assessmentType.applicationScreeningQuestion.description",
277
    defaultMessage:
278
      "These questions appear in the application form, and are submitted through Talent Cloud, they allow a first glance at the applicant’s understanding, process, knowledge, or cultural fit for the position.",
279
    description:
280
      "Description of an assessment type, to help a manager understand when to use it.",
281
  },
282
  [AssessmentTypeId.GroupTest]: {
283
    id: "assessmentType.groupTest.description",
284
    defaultMessage:
285
      "Applicants perform this test in real-time in conjunction with other applicants, team members, or facilitators, to determine their skill prowess, team communication, and performance in a collaborative environment.",
286
    description:
287
      "Description of an assessment type, to help a manager understand when to use it.",
288
  },
289
  [AssessmentTypeId.InformalPhoneConversation]: {
290
    id: "assessmentType.informalPhoneConversation.description",
291
    defaultMessage:
292
      "A loose structure chat between a member of the hiring board and an applicant, aimed at discovering the applicant’s knowledge, aptitudes, or personality traits, conversations may vary between applicants.",
293
    description:
294
      "Description of an assessment type, to help a manager understand when to use it.",
295
  },
296
  [AssessmentTypeId.Interview]: {
297
    id: "assessmentType.interview.description",
298
    defaultMessage:
299
      "A formal question-and-answer examination performed in real-time between the hiring-board and an applicant. Questions are aimed at assessing skill expertise, level, and approach. Each question is crafted beforehand and follows the same structure between all interviewed applicants.",
300
    description:
301
      "Description of an assessment type, to help a manager understand when to use it.",
302
  },
303
  [AssessmentTypeId.OnlineExam]: {
304
    id: "assessmentType.onlineExam.description",
305
    defaultMessage:
306
      "Prepared examination that does not require supervision, and can be performed from any location through internet access, with a defined time-frame for completion.",
307
    description:
308
      "Description of an assessment type, to help a manager understand when to use it.",
309
  },
310
  [AssessmentTypeId.OnSiteExam]: {
311
    id: "assessmentType.onSiteExam.description",
312
    defaultMessage:
313
      "Prepared examination that requires the applicant to perform a test at a specific location under supervision, aimed at assessing skill expertise and technique.",
314
    description:
315
      "Description of an assessment type, to help a manager understand when to use it.",
316
  },
317
  [AssessmentTypeId.TakeHomeExam]: {
318
    id: "assessmentType.takeHomeExam.description",
319
    defaultMessage:
320
      "Applicants receive a physical package containing the assessment tools, they complete the assessment at their own leisure and at their preferred location without supervision, and must return the materials before a specific deadline.",
321
    description:
322
      "Description of an assessment type, to help a manager understand when to use it.",
323
  },
324
  [AssessmentTypeId.PortfolioReview]: {
325
    id: "assessmentType.portfolioReview.description",
326
    defaultMessage:
327
      "During the application process, applicants provide access to samples of their work to exhibit their skill level, and back-up their skill claims. ",
328
    description:
329
      "Description of an assessment type, to help a manager understand when to use it.",
330
  },
331
  [AssessmentTypeId.ReferenceCheck]: {
332
    id: "assessmentType.referenceCheck.description",
333
    defaultMessage:
334
      "During the application process, applicants provide contact information to an acquaintance who can validate and confirm their skill expertise, knowledge or aptitude.",
335
    description:
336
      "Description of an assessment type, to help a manager understand when to use it.",
337
  },
338
  [AssessmentTypeId.SeriousGames]: {
339
    id: "assessmentType.seriousGames.description",
340
    defaultMessage:
341
      "Test involving the use of games to explore a candidate’s communication skills, resilience, emotional intelligence, among many other soft skills.",
342
    description:
343
      "Description of an assessment type, to help a manager understand when to use it.",
344
  },
345
});
346
347
export const assessmentTypeDescription = (
348
  assessmentTypeId: number,
349
): MessageDescriptor =>
350
  getOrThrowError(
351
    assessmentTypeDescriptions,
352
    assessmentTypeId,
353
    "invalid AssessmentTypeValue",
354
  );
355
356
const standardAssessmentText = defineMessages({
357
  narrativeReviewQuestion: {
358
    id: "assessmentType.narrativeReview.standardQuestion",
359
    defaultMessage:
360
      "Narrative Review of skill includes all descriptions added by the applicant in their application.",
361
    description:
362
      "Description which replaces 'interview question' for the Narrative Review assessment type.",
363
  },
364
  narrativeReviewAnswer: {
365
    id: "assessmentType.narrativeReview.standardAnswer",
366
    defaultMessage:
367
      "The provided description contains sufficient evidence to advance this candidate to the next screening steps.",
368
    description:
369
      "Standard evaluation statement which replaces 'expected answer' for all skills under the Narrative Review assessment type.",
370
  },
371
});
372
373
const provinceNames = defineMessages({
374
  [ProvinceId.AB]: {
375
    id: "province.ab",
376
    defaultMessage: "Alberta",
377
  },
378
  [ProvinceId.BC]: {
379
    id: "province.bc",
380
    defaultMessage: "British Columbia",
381
  },
382
  [ProvinceId.MB]: {
383
    id: "province.mb",
384
    defaultMessage: "Manitoba",
385
  },
386
  [ProvinceId.NL]: {
387
    id: "province.nl",
388
    defaultMessage: "Newfoundland and Labrador",
389
  },
390
  [ProvinceId.NB]: {
391
    id: "province.nb",
392
    defaultMessage: "New Brunswick",
393
  },
394
  [ProvinceId.NS]: {
395
    id: "province.ns",
396
    defaultMessage: "Nova Scotia",
397
  },
398
  [ProvinceId.NU]: {
399
    id: "province.nu",
400
    defaultMessage: "Nunavut",
401
  },
402
  [ProvinceId.NT]: {
403
    id: "province.nt",
404
    defaultMessage: "Northwest Territories",
405
  },
406
  [ProvinceId.ON]: {
407
    id: "province.on",
408
    defaultMessage: "Ontario",
409
  },
410
  [ProvinceId.PE]: {
411
    id: "province.pe",
412
    defaultMessage: "Prince Edward Island",
413
  },
414
  [ProvinceId.QC]: {
415
    id: "province.qc",
416
    defaultMessage: "Quebec",
417
  },
418
  [ProvinceId.SK]: {
419
    id: "province.sk",
420
    defaultMessage: "Saskatchewan",
421
  },
422
  [ProvinceId.YT]: {
423
    id: "province.yk",
424
    defaultMessage: "Yukon",
425
  },
426
});
427
428
export const provinceName = (provinceId: number): MessageDescriptor =>
429
  getOrThrowError(provinceNames, provinceId, "invalid ProvinceId");
430
431
const provinceAbbreviations = defineMessages({
432
  [ProvinceId.AB]: {
433
    id: "province.ab.abbreviation",
434
    defaultMessage: "Alb.",
435
  },
436
  [ProvinceId.BC]: {
437
    id: "province.bc.abbreviation",
438
    defaultMessage: "B.C.",
439
  },
440
  [ProvinceId.MB]: {
441
    id: "province.mb.abbreviation",
442
    defaultMessage: "Man.",
443
  },
444
  [ProvinceId.NL]: {
445
    id: "province.nl.abbreviation",
446
    defaultMessage: "N.L.",
447
  },
448
  [ProvinceId.NB]: {
449
    id: "province.nb.abbreviation",
450
    defaultMessage: "N.B.",
451
  },
452
  [ProvinceId.NS]: {
453
    id: "province.ns.abbreviation",
454
    defaultMessage: "N.S.",
455
  },
456
  [ProvinceId.NU]: {
457
    id: "province.nu.abbreviation",
458
    defaultMessage: "Nvt.",
459
  },
460
  [ProvinceId.NT]: {
461
    id: "province.nt.abbreviation",
462
    defaultMessage: "N.W.T.",
463
  },
464
  [ProvinceId.ON]: {
465
    id: "province.on.abbreviation",
466
    defaultMessage: "Ont.",
467
  },
468
  [ProvinceId.PE]: {
469
    id: "province.pe.abbreviation",
470
    defaultMessage: "P.E.I.",
471
  },
472
  [ProvinceId.QC]: {
473
    id: "province.qc.abbreviation",
474
    defaultMessage: "Que.",
475
  },
476
  [ProvinceId.SK]: {
477
    id: "province.sk.abbreviation",
478
    defaultMessage: "Sask.",
479
  },
480
  [ProvinceId.YT]: {
481
    id: "province.yk.abbreviation",
482
    defaultMessage: "Y.T.",
483
  },
484
});
485
486
export const provinceAbbreviation = (provinceId: number): MessageDescriptor =>
487
  getOrThrowError(provinceAbbreviations, provinceId, "invalid ProvinceId");
488
489
const securityClearances = defineMessages({
490
  [SecurityClearanceId.reliability]: {
491
    id: "securityClearance.reliability",
492
    defaultMessage: "Reliability",
493
  },
494
  [SecurityClearanceId.secret]: {
495
    id: "securityClearance.secret",
496
    defaultMessage: "Secret",
497
  },
498
  [SecurityClearanceId.topSecret]: {
499
    id: "securityClearance.topSecret",
500
    defaultMessage: "Top Secret",
501
  },
502
});
503
504
export const securityClearance = (
505
  securityClearanceId: number,
506
): MessageDescriptor =>
507
  getOrThrowError(
508
    securityClearances,
509
    securityClearanceId,
510
    "invalid security clearance id",
511
  );
512
513
const languageRequirements = defineMessages({
514
  [LanguageRequirementId.english]: {
515
    id: "languageRequirement.english",
516
    defaultMessage: "English Essential",
517
  },
518
  [LanguageRequirementId.french]: {
519
    id: "languageRequirement.french",
520
    defaultMessage: "French Essential",
521
  },
522
  [LanguageRequirementId.bilingualIntermediate]: {
523
    id: "languageRequirement.bilingualIntermediate",
524
    defaultMessage: "Bilingual - Intermediate",
525
  },
526
  [LanguageRequirementId.bilingualAdvanced]: {
527
    id: "languageRequirement.bilingualAdvanced",
528
    defaultMessage: "Bilingual - Advanced",
529
  },
530
  [LanguageRequirementId.englishOrFrench]: {
531
    id: "languageRequirement.englishOrFrench",
532
    defaultMessage: "English or French",
533
  },
534
});
535
536
export const languageRequirement = (
537
  languageRequirementId: number,
538
): MessageDescriptor =>
539
  getOrThrowError(
540
    languageRequirements,
541
    languageRequirementId,
542
    "invalid LanguageRequirementId",
543
  );
544
545
const languageRequirementDescriptions = defineMessages({
546
  [LanguageRequirementId.english]: {
547
    id: "languageRequirement.description.english",
548
    defaultMessage:
549
      "This position requires fluency in English in both written and verbal communication. As part of the assessment of your language abilities, the hiring manager may ask you to complete some assessment steps in English, such as interview questions or an exam.",
550
  },
551
  [LanguageRequirementId.french]: {
552
    id: "languageRequirement.description.french",
553
    defaultMessage:
554
      "This position requires fluency in French in both written and verbal communication. As part of the assessment of your language abilities, the hiring manager may ask you to complete some assessment steps in French, such as interview questions or an exam.",
555
  },
556
  [LanguageRequirementId.bilingualIntermediate]: {
557
    id: "languageRequirement.description.bilingualIntermediate",
558
    // TODO: turn "Public Service Commission of Canada" into a link to https://www.canada.ca/en/public-service-commission/jobs/services/gc-jobs/information-candidates/language-requirements-candidates.html
559
    defaultMessage:
560
      "This position requires working knowledge of both French and English. This means that you can take on job duties in either French or English, and you have intermediate reading, writing and verbal communication skills in both official languages. As part of this selection process, your language abilities will be tested by the Public Service Commission of Canada.",
561
  },
562
  [LanguageRequirementId.bilingualAdvanced]: {
563
    id: "languageRequirement.description.bilingualAdvanced",
564
    // TODO: turn "Public Service Commission of Canada" into a link to https://www.canada.ca/en/public-service-commission/jobs/services/gc-jobs/information-candidates/language-requirements-candidates.html
565
    defaultMessage:
566
      "This position requires advanced knowledge of both French and English. This means that you can take on job duties in either French or English, and you have strong reading, writing and verbal communication skills in both official languages. As part of this selection process, your language abilities will be tested by the Public Service Commission of Canada Public Service Commission of Canada.",
567
  },
568
  [LanguageRequirementId.englishOrFrench]: {
569
    id: "languageRequirement.description.englishOrFrench",
570
    defaultMessage:
571
      "For this position, you meet the language requirements if you have strong reading, writing and verbal communication skills in either English or French, or both (bilingual).",
572
  },
573
});
574
575
export const languageRequirementDescription = (
576
  languageRequirementId: number,
577
): MessageDescriptor =>
578
  getOrThrowError(
579
    languageRequirementDescriptions,
580
    languageRequirementId,
581
    "invalid LanguageRequirementId",
582
  );
583
584
const languageRequirementContexts = defineMessages({
585
  basic: {
586
    id: "languageRequirement.context.basic",
587
    defaultMessage:
588
      "You can submit this initial application in either official language of your choice (English or French).",
589
  },
590
  expanded: {
591
    id: "languageRequirement.context.expanded",
592
    defaultMessage:
593
      "You can complete all other steps of this assessment process in the official language of your choice, including the initial application, interview, exam and any other evaluation components.",
594
  },
595
});
596
597
export const languageRequirementContext = (
598
  languageRequirementId: number,
599
): MessageDescriptor => {
600
  switch (languageRequirementId) {
601
    case LanguageRequirementId.bilingualIntermediate:
602
    case LanguageRequirementId.bilingualAdvanced:
603
      return languageRequirementContexts.expanded;
604
605
    case LanguageRequirementId.englishOrFrench:
606
    case LanguageRequirementId.english:
607
    case LanguageRequirementId.french:
608
    default:
609
      return languageRequirementContexts.basic;
610
  }
611
};
612
613
export const narrativeReviewStandardQuestion = (): MessageDescriptor =>
614
  standardAssessmentText.narrativeReviewQuestion;
615
616
export const narrativeReviewStandardAnswer = (): MessageDescriptor =>
617
  standardAssessmentText.narrativeReviewAnswer;
618
619
const frequencyMessages = defineMessages({
620
  [FrequencyId.never]: {
621
    id: "jobBuilder.details.frequencyNeverLabel",
622
    defaultMessage: "Never",
623
    description: "The form label displayed on 'never' frequency options.",
624
  },
625
  [FrequencyId.rarely]: {
626
    id: "jobBuilder.details.frequencyRarelyLabel",
627
    defaultMessage: "Rarely",
628
    description: "The form label displayed on 'rarely' frequency options.",
629
  },
630
  [FrequencyId.occasionally]: {
631
    id: "jobBuilder.details.frequencyOccasionallyLabel",
632
    defaultMessage: "Occasionally",
633
    description:
634
      "The form label displayed on 'occasionally' frequency options.",
635
  },
636
  [FrequencyId.frequently]: {
637
    id: "jobBuilder.details.frequencyFrequentlyLabel",
638
    defaultMessage: "Frequently",
639
    description: "The form label displayed on 'frequently' frequency options.",
640
  },
641
  [FrequencyId.always]: {
642
    id: "jobBuilder.details.frequencyAlwaysLabel",
643
    defaultMessage: "Almost Always",
644
    description: "The form label displayed on 'always' frequency options.",
645
  },
646
});
647
648
export const frequencyName = (frequencyId: number): MessageDescriptor =>
649
  getOrThrowError(frequencyMessages, frequencyId, "invalid FrequencyId");
650
651
const overtimeRequirementDescriptions = defineMessages({
652
  [OvertimeRequirementId.frequently]: {
653
    id: "jobBuilder.details.overtimeFrequentlyLabel",
654
    defaultMessage: "Yes, overtime is frequently required for the position.",
655
    description: "The form label displayed on 'frequently' overtime options",
656
  },
657
  [OvertimeRequirementId.available]: {
658
    id: "jobBuilder.details.overtimeOpportunitiesAvailableLabel",
659
    defaultMessage:
660
      "Yes, overtime opportunities are available for those that are interested.",
661
    description:
662
      "The form label displayed on 'overtime opportunities available' overtime options",
663
  },
664
  [OvertimeRequirementId.none]: {
665
    id: "jobBuilder.details.overtimeNoneRequiredLabel",
666
    defaultMessage: "No, overtime is not required for the position.",
667
    description:
668
      "The form label displayed on 'no overtime required' overtime options",
669
  },
670
});
671
672
export const overtimeRequirementDescription = (
673
  overtimeRequirementId: number,
674
): MessageDescriptor =>
675
  getOrThrowError(
676
    overtimeRequirementDescriptions,
677
    overtimeRequirementId,
678
    "invalid OvertimeRequirementId",
679
  );
680
681
const travelRequirementDescriptions = defineMessages({
682
  [TravelRequirementId.frequently]: {
683
    id: "jobBuilder.details.travelFrequentlyLabel",
684
    defaultMessage: "Yes, travel is frequently required for the position.",
685
    description: "The form label displayed on 'frequently' travel options",
686
  },
687
  [TravelRequirementId.available]: {
688
    id: "jobBuilder.details.travelOpportunitiesAvailableLabel",
689
    defaultMessage:
690
      "Yes, travel opportunities are available for those that are interested.",
691
    description:
692
      "The form label displayed on 'travel opportunities available' travel options",
693
  },
694
  [TravelRequirementId.none]: {
695
    id: "jobBuilder.details.travelNoneRequiredLabel",
696
    defaultMessage: "No, travel is not required for the position.",
697
    description:
698
      "The form label displayed on 'no travel required' travel options",
699
  },
700
});
701
702
export const travelRequirementDescription = (
703
  travelRequirementId: number,
704
): MessageDescriptor =>
705
  getOrThrowError(
706
    travelRequirementDescriptions,
707
    travelRequirementId,
708
    "invalid TravelRequirementId",
709
  );
710
711
export const generalLocations = defineMessages({
712
  [LocationId.jobGeneric]: {
713
    id: "activityfeed.locations.review",
714
    defaultMessage: "Job Poster Builder",
715
    description: "Location where the activity is located.",
716
  },
717
  [LocationId.summary]: {
718
    id: "activityfeed.locations.hr.summary",
719
    defaultMessage: "HR Summary Page",
720
    description: "Location where the activity is located.",
721
  },
722
  [LocationId.preview]: {
723
    id: "activityfeed.locations.hr.preview",
724
    defaultMessage: "HR Preview Page",
725
    description: "Location where the activity is located.",
726
  },
727
  [LocationId.applicantsGeneric]: {
728
    id: "activityfeed.locations.applications",
729
    defaultMessage: "Applicant Review Page",
730
    description: "Location where the activity is located.",
731
  },
732
  [LocationId.screeningPlan]: {
733
    id: "activityfeed.locations.screeningPlan",
734
    defaultMessage: "Assessment Plan",
735
    description: "Location where the activity is located.",
736
  },
737
  notFound: {
738
    id: "activityfeed.locations.notFound",
739
    defaultMessage: "Location not found",
740
    description: "Error message if location id is not recognized",
741
  },
742
});
743
744
export const generalLocationOption = (
745
  locationId: string,
746
): MessageDescriptor => {
747
  switch (locationId) {
748
    /* Job Poster Review Page */
749
    case LocationId.jobGeneric:
750
    case LocationId.heading:
751
    case LocationId.basicInfo:
752
    case LocationId.impact:
753
    case LocationId.tasks:
754
    case LocationId.skills:
755
    case LocationId.langRequirements:
756
    case LocationId.environment:
757
      return generalLocations[LocationId.jobGeneric];
758
    /* Applicant Review Page */
759
    case LocationId.applicantsGeneric:
760
    case LocationId.underConsideration:
761
    case LocationId.optionalConsideration:
762
    case LocationId.notUnderConsideration:
763
      return generalLocations[LocationId.applicantsGeneric];
764
    /* Assessment Plan */
765
    case LocationId.screeningPlan:
766
    case LocationId.screeningPlanBuilder:
767
    case LocationId.screeningPlanSummary:
768
    case LocationId.screeningPlanRatings:
769
      return generalLocations[LocationId.screeningPlan];
770
    /* Hr Portal */
771
    case LocationId.summary:
772
      return generalLocations[LocationId.summary];
773
    case LocationId.preview:
774
      return generalLocations[LocationId.preview];
775
776
    default:
777
      return generalLocations.notFound;
778
  }
779
};
780
781
export const jobReviewLocations = defineMessages({
782
  [LocationId.jobGeneric]: {
783
    id: "activityfeed.locations.review.general",
784
    defaultMessage: "General",
785
    description: "Location of the activity.",
786
  },
787
  [LocationId.heading]: {
788
    id: "activityfeed.locations.review.heading",
789
    defaultMessage: "Job Page Heading",
790
    description: "Location of the activity.",
791
  },
792
  [LocationId.basicInfo]: {
793
    id: "activityfeed.locations.review.basicInfo",
794
    defaultMessage: "Basic Information",
795
    description: "Location of the activity.",
796
  },
797
  [LocationId.impact]: {
798
    id: "activityfeed.locations.review.impact",
799
    defaultMessage: "Impact",
800
    description: "Location of the activity.",
801
  },
802
  [LocationId.tasks]: {
803
    id: "activityfeed.locations.review.tasks",
804
    defaultMessage: "Tasks",
805
    description: "Location of the activity.",
806
  },
807
  [LocationId.skills]: {
808
    id: "activityfeed.locations.review.skills",
809
    defaultMessage: "Skills",
810
    description: "Location of the activity.",
811
  },
812
  [LocationId.langRequirements]: {
813
    id: "activityfeed.locations.review.langRequirements",
814
    defaultMessage: "Language Requirements",
815
    description: "Location of the activity.",
816
  },
817
  [LocationId.environment]: {
818
    id: "activityfeed.locations.review.environment",
819
    defaultMessage: "Environment",
820
    description: "Location of the activity.",
821
  },
822
});
823
824
export const applicantReviewLocations = defineMessages({
825
  [LocationId.applicantsGeneric]: {
826
    id: "activityfeed.locations.applicantReview.general",
827
    defaultMessage: "General",
828
    description: "Location of the activity.",
829
  },
830
  [LocationId.underConsideration]: {
831
    id: "activityfeed.locations.applicantReview.underConsideration",
832
    defaultMessage: "Under Consideration",
833
    description: "Location of the activity.",
834
  },
835
  [LocationId.optionalConsideration]: {
836
    id: "activityfeed.locations.applicantReview.optionalConsideration",
837
    defaultMessage: "Optional Consideration",
838
    description: "Location of the activity.",
839
  },
840
  [LocationId.notUnderConsideration]: {
841
    id: "activityfeed.locations.applicantReview.notUnderConsideration",
842
    defaultMessage: "No Longer Under Consideration",
843
    description: "Location of the activity.",
844
  },
845
});
846
847
export const screeningPlanLocations = defineMessages({
848
  [LocationId.screeningPlan]: {
849
    id: "activityfeed.locations.screeningPlan.general",
850
    defaultMessage: "General",
851
    description: "Location of the activity.",
852
  },
853
  [LocationId.screeningPlanBuilder]: {
854
    id: "activityfeed.locations.screeningPlan.builder",
855
    defaultMessage: "Assessment Plan Builder",
856
    description: "Location of the activity.",
857
  },
858
  [LocationId.screeningPlanSummary]: {
859
    id: "activityfeed.locations.screeningPlan.summary",
860
    defaultMessage: "Assessment Plan Summary",
861
    description: "Location of the activity.",
862
  },
863
  [LocationId.screeningPlanRatings]: {
864
    id: "activityfeed.locations.screeningPlan.ratings",
865
    defaultMessage: "Ratings Guide Builder",
866
    description: "Location of the activity.",
867
  },
868
});
869
export const hrPortalLocations = {
870
  [LocationId.summary]: jobReviewLocations[LocationId.jobGeneric],
871
  [LocationId.preview]: jobReviewLocations[LocationId.jobGeneric],
872
};
873
874
export const specificLocationOption = (locationId: string): MessageDescriptor =>
875
  getOrThrowError(
876
    {
877
      ...jobReviewLocations,
878
      ...applicantReviewLocations,
879
      ...hrPortalLocations,
880
      ...screeningPlanLocations,
881
    },
882
    locationId,
883
    "Invalid LocationId",
884
  );
885
886
export const ResponseScreeningBuckets = {
887
  [ResponseBuckets.Consideration]: defineMessages({
888
    title: {
889
      id: "responseScreening.buckets.consideration.title",
890
      defaultMessage: "Employees Under Consideration",
891
      description:
892
        "Label for the 'Under Consideration' response screening bucket.",
893
    },
894
    description: {
895
      id: "responseScreening.buckets.consideration.description",
896
      defaultMessage:
897
        "Employees in this category have volunteered to be placed in a team with a critical needs shortage. Employees in this category are: Pending initial application review ({iconReceived}), indicating that a submission has been received, but it has not yet been assessed by a member of the review team; Ready for reference checks and home-department approval ({iconReady}), indicating that the employee is heading to the Ready to Allocate category if references and approval are in order; and Further Assessment Required ({iconAssessment}), indicating that the review team is unsure of their qualifications for this role and is undertaking further assessment.",
898
      description:
899
        "Descriptive text for the 'Under Consideration' response screening bucket. Takes three icons (iconReceived, iconReady, and iconAssessment) as input.",
900
    },
901
  }),
902
  [ResponseBuckets.ReadyToAllocate]: defineMessages({
903
    title: {
904
      id: "responseScreening.buckets.readyToAllocate.title",
905
      defaultMessage: "Ready to Allocate",
906
      description:
907
        "Label for the 'Ready to Allocate' response screening bucket.",
908
    },
909
    description: {
910
      id: "responseScreening.buckets.readyToAllocate.description",
911
      defaultMessage:
912
        "Employees in this category have the necessary skills for this stream of work, have successfully completed reference checks and have been given preliminary authorization to participate by a member of their management team. They are currently working in their substantive position, awaiting a request from a department with a critical talent gap.",
913
      description:
914
        "Descriptive text for the 'Ready to Allocate' response screening bucket.",
915
    },
916
  }),
917
  [ResponseBuckets.Allocated]: defineMessages({
918
    title: {
919
      id: "responseScreening.buckets.allocated.title",
920
      defaultMessage: "Allocated",
921
      description: "Label for the 'Allocated' response screening bucket.",
922
    },
923
    description: {
924
      id: "responseScreening.buckets.allocated.description",
925
      defaultMessage:
926
        'Employees in this category have been allocated to a department. Their name has been removed from all other GC Reserve processes to which they have applied (and will appear in those processes under "Not Currently Available".) Following the completion of an allocation, employees may elect to be placed back in the Ready to Allocate category, should they be needed again.',
927
      description:
928
        "Descriptive text for the 'Allocated' response screening bucket.",
929
    },
930
  }),
931
  [ResponseBuckets.Unavailable]: defineMessages({
932
    title: {
933
      id: "responseScreening.buckets.unavailable.title",
934
      defaultMessage: "Currently Unavailable",
935
      description: "Label for the 'Unavailable' response screening bucket.",
936
    },
937
    description: {
938
      id: "responseScreening.buckets.unavailable.description",
939
      defaultMessage:
940
        "Employees in this stream have been allocated to a department in need or have temporarily removed their names from consideration for a specific period of time (e.g. illness, family care needs), and wish to be considered for allocation at a later date. Employees in this category have been qualified for this talent stream, and will be placed back into the Ready to Allocate when they become available again. (If an employee permanently withdraws their name, their submission will be removed from the GC Talent Reserve.)",
941
      description:
942
        "Descriptive text for the 'Currently Unavailable' response screening bucket.",
943
    },
944
  }),
945
  [ResponseBuckets.DoesNotQualify]: defineMessages({
946
    title: {
947
      id: "responseScreening.buckets.doesNotQualify.title",
948
      defaultMessage: "Does Not Qualify",
949
      description:
950
        "Label for the 'Does Not Qualify' response screening bucket.",
951
    },
952
    description: {
953
      id: "responseScreening.buckets.doesNotQualify.description",
954
      defaultMessage:
955
        "Employees in this category have volunteered their names, but a review of their application and/or reference checks has led the review team to conclude that the employee would not be an asset to a department needing to fill a critical talent gap in this field of work. This determination is, in no way, reflected in the employee's performance status with their home department, and does not affect their evaluation for other GC Reserve talent streams to which they may have applied.",
956
      description:
957
        "Descriptive text for the 'Does Not Qualify' response screening bucket.",
958
    },
959
  }),
960
};
961
962
export const ReviewStatusMessages = defineMessages({
963
  screened_out: {
964
    id: "reviewStatus.screenedOut",
965
    defaultMessage: "Screened Out",
966
    description: "Select option text for the 'Screened Out' review status.",
967
  },
968
  still_thinking: {
969
    id: "reviewStatus.stillThinking",
970
    defaultMessage: "Still Thinking",
971
    description: "Select option text for the 'Still Thinking' review status.",
972
  },
973
  still_in: {
974
    id: "reviewStatus.stillIn",
975
    defaultMessage: "Still In",
976
    description: "Select option text for the 'Still In' review status.",
977
  },
978
});
979
980
export const ReviewStatuses: {
981
  [key in ReviewStatusName]: { id: ReviewStatusId; name: MessageDescriptor };
982
} = {
983
  screened_out: {
984
    id: ReviewStatusId.ScreenedOut,
985
    name: ReviewStatusMessages.screened_out,
986
  },
987
  still_thinking: {
988
    id: ReviewStatusId.StillThinking,
989
    name: ReviewStatusMessages.still_thinking,
990
  },
991
  still_in: {
992
    id: ReviewStatusId.StillIn,
993
    name: ReviewStatusMessages.still_in,
994
  },
995
};
996
997
export const ResponseReviewStatusMessages = defineMessages({
998
  screened_out: {
999
    id: "responseReviewStatus.screenedOut",
1000
    defaultMessage: "Does Not Qualify",
1001
    description: "Select option text for the 'Does Not Qualify' review status.",
1002
  },
1003
  ready_for_reference: {
1004
    id: "responseReviewStatus.readyForReference",
1005
    defaultMessage: "Ready for Reference Check",
1006
    description:
1007
      "Select option text for the 'Ready for Reference Check' review status.",
1008
  },
1009
  ready_to_allocate: {
1010
    id: "responseReviewStatus.readyToAllocate",
1011
    defaultMessage: "Ready to Allocate",
1012
    description:
1013
      "Select option text for the 'Ready to Allocate' review status.",
1014
  },
1015
  assessment_required: {
1016
    id: "responseReviewStatus.assessmentRequired",
1017
    defaultMessage: "Further Assessment Required",
1018
    description:
1019
      "Select option text for the 'Further Assessment Required' review status.",
1020
  },
1021
  allocated: {
1022
    id: "responseReviewStatus.allocated",
1023
    defaultMessage: "Allocated",
1024
    description: "Select option text for the 'Allocated' review status.",
1025
  },
1026
  not_available: {
1027
    id: "responseReviewStatus.notAvailable",
1028
    defaultMessage: "Not Available",
1029
    description: "Select option text for the 'Not Available' review status.",
1030
  },
1031
});
1032
1033
export const ResponseReviewStatuses = {
1034
  assessment_required: {
1035
    id: 6,
1036
    name: ResponseReviewStatusMessages.assessment_required,
1037
  },
1038
  ready_for_reference: {
1039
    id: 4,
1040
    name: ResponseReviewStatusMessages.ready_for_reference,
1041
  },
1042
  ready_to_allocate: {
1043
    id: 5,
1044
    name: ResponseReviewStatusMessages.ready_to_allocate,
1045
  },
1046
  allocated: {
1047
    id: 7,
1048
    name: ResponseReviewStatusMessages.allocated,
1049
  },
1050
  not_available: {
1051
    id: 8,
1052
    name: ResponseReviewStatusMessages.not_available,
1053
  },
1054
  screened_out: {
1055
    id: 1,
1056
    name: ResponseReviewStatusMessages.screened_out,
1057
  },
1058
};
1059
1060
const experienceHeadings = defineMessages({
1061
  award: {
1062
    id: "application.skills.awardHeading",
1063
    defaultMessage: "{title} from {issuedBy}",
1064
    description: "Accordion heading for experience on the Skills page.",
1065
  },
1066
  community: {
1067
    id: "application.skills.communityHeading",
1068
    defaultMessage: "{title} with {group}",
1069
    description: "Accordion heading for experience on the Skills page.",
1070
  },
1071
  education: {
1072
    id: "application.skills.educationHeading",
1073
    defaultMessage: "{areaOfStudy} at {institution}",
1074
    description: "Accordion heading for experience on the Skills page.",
1075
  },
1076
  personal: {
1077
    id: "application.skills.personalHeading",
1078
    defaultMessage: "{title}",
1079
    description: "Accordion heading for experience on the Skills page.",
1080
  },
1081
  work: {
1082
    id: "application.skills.workHeading",
1083
    defaultMessage: "{title} at {organization}",
1084
    description: "Accordion heading for experience on the Skills page.",
1085
  },
1086
  unknown: {
1087
    id: "application.skills.unknownHeading",
1088
    defaultMessage: "Error: Unknown experience type.",
1089
    description:
1090
      "Accordion heading error when an unknown experience type is used.",
1091
  },
1092
});
1093
1094
/**
1095
 * Returns a formatted localized heading for the accordion on
1096
 * the Skill UI page of the Job Application. Makes use of experienceHeadings
1097
 * messages defined above.
1098
 *
1099
 * @param experience Given Experience of multiple types defined by the user to apply to a certain Criteria.
1100
 * @param intl react-intl object used in formatting messages.
1101
 *
1102
 * @returns Formatted localized string.
1103
 */
1104
export const getExperienceHeading = (
1105
  experience: Experience,
1106
  intl: IntlShape,
1107
): string => {
1108
  let heading: string;
1109
1110
  switch (experience.type) {
1111
    case "experience_award":
1112
      heading = intl.formatMessage(experienceHeadings.award, {
1113
        title: experience.title,
1114
        issuedBy: experience.issued_by,
1115
      });
1116
      break;
1117
    case "experience_community":
1118
      heading = intl.formatMessage(experienceHeadings.community, {
1119
        title: experience.title,
1120
        group: experience.group,
1121
      });
1122
      break;
1123
    case "experience_education":
1124
      heading = intl.formatMessage(experienceHeadings.education, {
1125
        areaOfStudy: experience.area_of_study,
1126
        institution: experience.institution,
1127
      });
1128
      break;
1129
    case "experience_personal":
1130
      heading = intl.formatMessage(experienceHeadings.personal, {
1131
        title: experience.title,
1132
      });
1133
      break;
1134
    case "experience_work":
1135
      heading = intl.formatMessage(experienceHeadings.work, {
1136
        title: experience.title,
1137
        organization: experience.organization,
1138
      });
1139
      break;
1140
    default:
1141
      heading = intl.formatMessage(experienceHeadings.unknown);
1142
  }
1143
1144
  return heading;
1145
};
1146
1147
/**
1148
 * Returns a formatted localized subheading for the accordion on
1149
 * the Skill UI page of the Job Application. Makes use of date formatting
1150
 * to provide a range.
1151
 *
1152
 * @param experience Given Experience of multiple types defined by the user to apply to a certain Criteria.
1153
 * @param intl react-intl object used in formatting messages.
1154
 *
1155
 * @returns Formatted localized string.
1156
 */
1157
export const getExperienceSubheading = (
1158
  experience: Experience,
1159
  intl: IntlShape,
1160
): string => {
1161
  let subHeading: string;
1162
  let startDate: string;
1163
  let endDate: string;
1164
1165
  switch (experience.type) {
1166
    case "experience_award":
1167
      subHeading = intl.formatDate(experience.awarded_date, {
1168
        month: "short",
1169
        year: "numeric",
1170
      });
1171
      break;
1172
    case "experience_community":
1173
    case "experience_education":
1174
    case "experience_personal":
1175
    case "experience_work":
1176
      startDate = intl.formatDate(experience.start_date, {
1177
        month: "short",
1178
        year: "numeric",
1179
      });
1180
1181
      if (experience.end_date !== null && !experience.is_active) {
1182
        endDate = intl.formatDate(experience.end_date, {
1183
          month: "short",
1184
          year: "numeric",
1185
        });
1186
      } else {
1187
        endDate = intl.formatMessage({
1188
          id: "application.skills.currentSubheading",
1189
          defaultMessage: "Current",
1190
          description:
1191
            "Text for the end date of a current experience on the Skills page.",
1192
        });
1193
      }
1194
1195
      subHeading = `${startDate} - ${endDate}`;
1196
      break;
1197
    default:
1198
      subHeading = intl.formatMessage(experienceHeadings.unknown);
1199
  }
1200
1201
  return subHeading;
1202
};
1203
1204
const experienceJustificationLabels = defineMessages({
1205
  award: {
1206
    id: "application.skills.awardJustificationLabel",
1207
    defaultMessage: "How I used {skillName} to achieve {title}",
1208
    description: "Accordion heading for experience on the Skills page.",
1209
  },
1210
  community: {
1211
    id: "application.skills.communityJustificationLabel",
1212
    defaultMessage: "How I used {skillName} with {group}",
1213
    description: "Accordion heading for experience on the Skills page.",
1214
  },
1215
  education: {
1216
    id: "application.skills.educationJustificationLabel",
1217
    defaultMessage: "How I used {skillName} at {institution}",
1218
    description: "Accordion heading for experience on the Skills page.",
1219
  },
1220
  personal: {
1221
    id: "application.skills.personalJustificationLabel",
1222
    defaultMessage: "How I used {skillName} for {title}",
1223
    description: "Accordion heading for experience on the Skills page.",
1224
  },
1225
  work: {
1226
    id: "application.skills.workJustificationLabel",
1227
    defaultMessage: "How I used {skillName} at {organization}",
1228
    description: "Accordion heading for experience on the Skills page.",
1229
  },
1230
  unknown: {
1231
    id: "application.skills.unknownJustificationLabel",
1232
    defaultMessage: "Error: Unknown experience type.",
1233
    description:
1234
      "Accordion heading error when an unknown experience type is used.",
1235
  },
1236
});
1237
1238
/**
1239
 * Returns a formatted localized input label for the text area
1240
 * inside the experience accordion on the Skill UI page of the
1241
 * Job Application. Makes use of experienceJustificationLabels
1242
 * messages defined above.
1243
 *
1244
 * @param experience Given Experience of multiple types defined by the user to apply to a certain Criteria.
1245
 * @param intl react-intl object used in formatting messages.
1246
 *
1247
 * @returns Formatted localized string.
1248
 */
1249
export const getExperienceJustificationLabel = (
1250
  experience: Experience,
1251
  intl: IntlShape,
1252
  skillName: string,
1253
): string => {
1254
  let label: string;
1255
1256
  switch (experience.type) {
1257
    case "experience_award":
1258
      label = intl.formatMessage(experienceJustificationLabels.award, {
1259
        skillName,
1260
        title: experience.title,
1261
      });
1262
      break;
1263
    case "experience_community":
1264
      label = intl.formatMessage(experienceJustificationLabels.community, {
1265
        skillName,
1266
        group: experience.group,
1267
      });
1268
      break;
1269
    case "experience_education":
1270
      label = intl.formatMessage(experienceJustificationLabels.education, {
1271
        skillName,
1272
        institution: experience.institution,
1273
      });
1274
      break;
1275
    case "experience_personal":
1276
      label = intl.formatMessage(experienceJustificationLabels.personal, {
1277
        skillName,
1278
        title: experience.title,
1279
      });
1280
      break;
1281
    case "experience_work":
1282
      label = intl.formatMessage(experienceJustificationLabels.work, {
1283
        skillName,
1284
        organization: experience.organization,
1285
      });
1286
      break;
1287
    default:
1288
      label = intl.formatMessage(experienceHeadings.unknown);
1289
  }
1290
1291
  return label;
1292
};
1293
1294
export const gcEmployeeStatuses = defineMessages({
1295
  [GCEmployeeStatus.current]: {
1296
    id: "application.basicInfo.gcEmployeeStatus.current",
1297
    defaultMessage:
1298
      "Yes - I am currently an employee of the Government of Canada.",
1299
    description: "Select option text for the 'Yes' GC employee status.",
1300
  },
1301
  [GCEmployeeStatus.no]: {
1302
    id: "application.basicInfo.gcEmployeeStatus.no",
1303
    defaultMessage:
1304
      "No - I am not, and have never been, an employee of the Government of Canada.",
1305
    description: "Select option text for the 'No' GC employee status.",
1306
  },
1307
  [GCEmployeeStatus.past]: {
1308
    id: "application.basicInfo.gcEmployeeStatus.past",
1309
    defaultMessage:
1310
      "I was previously, but am no longer, an employee of the Government of Canada.",
1311
    description: "Select option text for the 'Previous' GC employee status.",
1312
  },
1313
});
1314
1315
export const gcEmployeeStatus = (
1316
  gcEmployeeStatusId: number,
1317
): MessageDescriptor =>
1318
  getOrThrowError(
1319
    gcEmployeeStatuses,
1320
    gcEmployeeStatusId,
1321
    "invalid GC employee Status",
1322
  );
1323