Passed
Push — task/job-get-classification ( a25834...653631 )
by
unknown
06:00
created

resources/assets/js/components/AssessmentPlan/RatingGuideNarrativeAssessment.tsx   A

Complexity

Total Complexity 4
Complexity/F 0

Size

Lines of Code 181
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 142
dl 0
loc 181
rs 10
c 0
b 0
f 0
wmc 4
mnd 4
bc 4
fnc 0
bpm 0
cpm 0
noi 0
1
import React from "react";
2
import { connect } from "react-redux";
3
import {
4
  FormattedMessage,
5
  WrappedComponentProps,
6
  injectIntl,
7
} from "react-intl";
8
import { Criteria, Skill } from "../../models/types";
9
import {
10
  assessmentType,
11
  assessmentTypeDescription,
12
  narrativeReviewStandardQuestion,
13
  skillLevelName,
14
  narrativeReviewStandardAnswer,
15
} from "../../models/localizedConstants";
16
import { AssessmentTypeId, SkillTypeId } from "../../models/lookupConstants";
17
import { RootState } from "../../store/store";
18
import {
19
  getCriteriaByJobAndAssessmentType,
20
  getCriteriaToSkills,
21
} from "../../store/Job/jobSelectorComplex";
22
import { getLocale, localizeFieldNonNull } from "../../helpers/localize";
23
24
interface RatingGuideNarrativeAssessmentProps {
25
  /** The id of the job Job Poster this is part of */
26
  jobId: number;
27
  /** Display index of this ratings guide assessment compared to others on the page */
28
  assessmentIndex: number;
29
  assessedCriteria: Criteria[];
30
  /** A map of criteria to their associated skills */
31
  criteriaToSkill: { [criteriaId: number]: Skill | null };
32
}
33
34
export const RatingGuideNarrativeAssessment: React.FunctionComponent<RatingGuideNarrativeAssessmentProps &
35
  WrappedComponentProps> = ({
36
  jobId,
37
  assessmentIndex,
38
  assessedCriteria,
39
  criteriaToSkill,
40
  intl,
41
}): React.ReactElement | null => {
42
  const locale = getLocale(intl.locale);
43
  if (jobId === null) {
44
    return null;
45
  }
46
  const getCriteriaSkillType = (criterionId: number): number => {
47
    const skill = criteriaToSkill[criterionId];
48
    return skill ? skill.skill_type_id : SkillTypeId.Hard; // return hard type by default
49
  };
50
  const getCriteriaSkillName = (criterionId: number): string => {
51
    const skill = criteriaToSkill[criterionId];
52
    return skill ? localizeFieldNonNull(locale, skill, "name") : "";
53
  };
54
  return (
55
    <div>
56
      <h4
57
        data-c-font-size="h4"
58
        data-c-colour="c5"
59
        data-c-font-weight="bold"
60
        data-c-margin="top(double) bottom(normal)"
61
      >
62
        {/** TODO: This FormattedMessage is identical to one in RatingGuideAssessment.
63
                    This special Narrative Review section should be refactored to there. */}
64
        <FormattedMessage
65
          id="ratingGuideBuilder.narrativeSectionTitle"
66
          defaultMessage="Assessment {index}: {assessmentType}"
67
          description="Subtitle for the special Narrative Assessment section in the Rating Guide Builder."
68
          values={{
69
            index: assessmentIndex,
70
            assessmentType: intl.formatMessage(
71
              assessmentType(AssessmentTypeId.NarrativeAssessment),
72
            ),
73
          }}
74
        />
75
      </h4>
76
      <p>
77
        {intl.formatMessage(
78
          assessmentTypeDescription(AssessmentTypeId.NarrativeAssessment),
79
        )}
80
      </p>
81
82
      <div
83
        data-c-background="black(10)"
84
        data-c-border="all(thin, solid, black)"
85
        data-c-margin="top(normal) bottom(normal)"
86
        data-c-padding="bottom(normal)"
87
      >
88
        <div
89
          data-c-background="black(10)"
90
          data-c-border="bottom(thin, solid, black)"
91
          data-c-padding="top(normal) bottom(normal)"
92
        >
93
          <div data-c-grid="gutter middle">
94
            <div
95
              data-c-alignment="center"
96
              data-c-grid-item="base(1of1) tp(1of8)"
97
            >
98
              <strong>{assessmentIndex}.</strong>
99
            </div>
100
            <div data-c-grid-item="base(1of1) tp(7of8)">
101
              <p data-c-font-weight="800">
102
                {intl.formatMessage(narrativeReviewStandardQuestion())}
103
              </p>
104
            </div>
105
          </div>
106
        </div>
107
        {assessedCriteria.map(
108
          (criterion: Criteria): React.ReactElement => {
109
            let skillLevel = "";
110
            if (criteriaToSkill[criterion.id] !== undefined) {
111
              skillLevel = intl.formatMessage(
112
                skillLevelName(
113
                  criterion.skill_level_id,
114
                  getCriteriaSkillType(criterion.id),
115
                ),
116
              );
117
            }
118
            return (
119
              <div
120
                key={`narrative-review-criteria-${criterion.id}`}
121
                data-c-padding="top(normal) bottom(normal)"
122
              >
123
                <div data-c-grid="gutter middle">
124
                  <div data-c-grid-item="base(1of1) tp(1of8)" />
125
                  {criterion && skillLevel.length > 0 && (
126
                    <div data-c-grid-item="base(1of1) tp(2of8)">
127
                      <FormattedMessage
128
                        id="ratingGuideBuilder.criteriaName"
129
                        defaultMessage="{skillName} - {skillLevel}"
130
                        description="How each criteria is listed in Rating Guide Builder."
131
                        values={{
132
                          skillName: getCriteriaSkillName(criterion.id),
133
                          skillLevel,
134
                        }}
135
                      />
136
                    </div>
137
                  )}
138
                  <div data-c-grid-item="base(1of1) tp(5of8)">
139
                    {intl.formatMessage(narrativeReviewStandardAnswer())}
140
                  </div>
141
                </div>
142
              </div>
143
            );
144
          },
145
        )}
146
      </div>
147
    </div>
148
  );
149
};
150
151
interface RatingGuideNarrativeAssessmentContainerProps {
152
  jobId: number;
153
  assessmentIndex: number;
154
}
155
156
const mapStateToProps = (
157
  state: RootState,
158
  ownProps: RatingGuideNarrativeAssessmentContainerProps,
159
): {
160
  assessedCriteria: Criteria[];
161
  criteriaToSkill: { [criteriaId: number]: Skill | null };
162
} => {
163
  const narrativeCriteria: Criteria[] = getCriteriaByJobAndAssessmentType(
164
    state,
165
    {
166
      jobId: ownProps.jobId,
167
      assessmentTypeId: AssessmentTypeId.NarrativeAssessment,
168
    },
169
  );
170
  return {
171
    assessedCriteria: narrativeCriteria,
172
    criteriaToSkill: getCriteriaToSkills(state),
173
  };
174
};
175
176
const RatingGuideNarrativeAssessmentContainer = connect(mapStateToProps)(
177
  injectIntl(RatingGuideNarrativeAssessment),
178
);
179
180
export default RatingGuideNarrativeAssessmentContainer;
181