Passed
Push — feature/azure-webapp-pipeline-... ( 271549...3c88ad )
by Grant
07:11 queued 10s
created

resources/assets/js/components/JobBuilder/Review/JobReviewPage.tsx   A

Complexity

Total Complexity 13
Complexity/F 0

Size

Lines of Code 211
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 13
eloc 174
mnd 13
bc 13
fnc 0
dl 0
loc 211
bpm 0
cpm 0
noi 0
c 0
b 0
f 0
rs 10
1
import React, { useEffect } from "react";
2
import { WrappedComponentProps, injectIntl, useIntl } from "react-intl";
3
import nprogress from "nprogress";
4
import { connect, useDispatch } from "react-redux";
5
import ReactDOM from "react-dom";
6
import RootContainer from "../../RootContainer";
7
import {
8
  Job,
9
  JobPosterKeyTask,
10
  Criteria,
11
  Skill,
12
  Manager,
13
  Department,
14
  User,
15
  Classification,
16
} from "../../../models/types";
17
import { managerJobIndex, jobBuilderSkills } from "../../../helpers/routes";
18
import { RootState } from "../../../store/store";
19
import {
20
  getJob,
21
  getTasksByJob,
22
  getCriteriaByJob,
23
} from "../../../store/Job/jobSelector";
24
import { getSkills } from "../../../store/Skill/skillSelector";
25
import { DispatchType } from "../../../configureStore";
26
import { submitJobForReview } from "../../../store/Job/jobActions";
27
import JobBuilderStepContainer from "../JobBuilderStep";
28
import { isJobBuilderComplete } from "../jobBuilderHelpers";
29
import JobReview from "./JobReview";
30
import { getDepartments } from "../../../store/Department/deptSelector";
31
import { getSelectedManager } from "../../../store/Manager/managerSelector";
32
import {
33
  fetchManager,
34
  setSelectedManager,
35
} from "../../../store/Manager/managerActions";
36
import { navigate } from "../../../helpers/router";
37
import { getUserById } from "../../../store/User/userSelector";
38
import { fetchUser } from "../../../store/User/userActions";
39
import { useLoadClassifications } from "../../../hooks/classificationHooks";
40
41
interface JobBuilderReviewPageProps {
42
  jobId: number;
43
  job: Job | null;
44
  skills: Skill[];
45
  keyTasks: JobPosterKeyTask[];
46
  criteria: Criteria[];
47
  departments: Department[];
48
  manager: Manager | null;
49
  user: User | null;
50
  handleSubmitJob: (job: Job) => Promise<void>;
51
  loadManager: (managerId: number) => Promise<void>;
52
  handleFetchUser: (userId: number) => Promise<void>;
53
}
54
55
const JobBuilderReviewPage: React.FunctionComponent<
56
  JobBuilderReviewPageProps & WrappedComponentProps
57
> = ({
58
  jobId,
59
  job,
60
  skills,
61
  keyTasks,
62
  criteria,
63
  departments,
64
  manager,
65
  user,
66
  handleSubmitJob,
67
  loadManager,
68
  handleFetchUser,
69
}): React.ReactElement => {
70
  const intl = useIntl();
71
  const { locale } = intl;
72
  if (locale !== "en" && locale !== "fr") {
73
    throw new Error("Unexpected locale");
74
  }
75
76
  const dispatch = useDispatch<DispatchType>();
77
  const { classifications } = useLoadClassifications(dispatch);
78
  const classificationKey: string =
79
    classifications.find(
80
      (item: Classification) => item.id === job?.classification_id,
81
    )?.key || "";
82
83
  useEffect((): void => {
84
    if (job && job.manager_id) {
85
      loadManager(job.manager_id);
86
    }
87
  }, [job, loadManager]);
88
89
  // Load user after Manager has loaded
90
  // eslint-disable-next-line camelcase
91
  const userId = manager?.user_id;
92
  useEffect((): void => {
93
    if (userId) {
94
      handleFetchUser(userId);
95
    }
96
  }, [handleFetchUser, userId]);
97
98
  const handleReturn = (): void => {
99
    // Go to Previous page
100
    navigate(jobBuilderSkills(locale, jobId));
101
    nprogress.done();
102
  };
103
  const handleContinue = (): void => {
104
    // Continue to next page
105
    window.location.href = managerJobIndex(locale);
106
    nprogress.start();
107
  };
108
109
  const jobIsComplete =
110
    job !== null && isJobBuilderComplete(job, keyTasks, criteria, locale);
111
112
  return (
113
    <JobBuilderStepContainer jobId={jobId} currentPage="review">
114
      {job !== null && (
115
        <JobReview
116
          job={job}
117
          classificationKey={classificationKey}
118
          manager={manager}
119
          user={user}
120
          tasks={keyTasks}
121
          criteria={criteria}
122
          skills={skills}
123
          departments={departments}
124
          validForSubmission={jobIsComplete}
125
          handleSubmit={handleSubmitJob}
126
          handleReturn={handleReturn}
127
          handleContinue={handleContinue}
128
        />
129
      )}
130
    </JobBuilderStepContainer>
131
  );
132
};
133
134
const mapStateToProps = (
135
  state: RootState,
136
  ownProps: { jobId: number },
137
): {
138
  job: Job | null;
139
  skills: Skill[];
140
  keyTasks: JobPosterKeyTask[];
141
  criteria: Criteria[];
142
  departments: Department[];
143
  manager: Manager | null;
144
  user: User | null;
145
} => ({
146
  job: getJob(state, ownProps),
147
  skills: getSkills(state),
148
  keyTasks: getTasksByJob(state, ownProps),
149
  criteria: getCriteriaByJob(state, ownProps),
150
  departments: getDepartments(state),
151
  manager: getSelectedManager(state),
152
  user: getUserById(state, {
153
    userId: getSelectedManager(state)?.user_id || 0,
154
  }),
155
});
156
157
const mapDispatchToProps = (
158
  dispatch: DispatchType,
159
): {
160
  handleSubmitJob: (job: Job) => Promise<void>;
161
  loadManager: (managerId: number) => Promise<void>;
162
  handleFetchUser: (userId: number) => Promise<void>;
163
} => ({
164
  handleSubmitJob: async (job: Job): Promise<void> => {
165
    const result = await dispatch(submitJobForReview(job.id));
166
    if (result.error) {
167
      return Promise.reject(result.payload);
168
    }
169
    return Promise.resolve();
170
  },
171
  loadManager: async (managerId: number): Promise<void> => {
172
    const result = await dispatch(fetchManager(managerId));
173
    if (result.error) {
174
      return Promise.reject(result.payload);
175
    }
176
    const resultManager = await result.payload;
177
    dispatch(setSelectedManager(resultManager.id));
178
    return Promise.resolve();
179
  },
180
  handleFetchUser: async (userId: number): Promise<void> => {
181
    const result = await dispatch(fetchUser(userId));
182
    if (!result.error) {
183
      return Promise.resolve();
184
    }
185
    return Promise.reject(result.error);
186
  },
187
});
188
189
const JobReviewPageContainer = connect(
190
  mapStateToProps,
191
  mapDispatchToProps,
192
)(injectIntl(JobBuilderReviewPage));
193
194
export default JobReviewPageContainer;
195
196
if (document.getElementById("job-builder-review")) {
197
  const container = document.getElementById(
198
    "job-builder-review",
199
  ) as HTMLElement;
200
  const jobIdAttr = container.getAttribute("data-job-id");
201
  const jobId = jobIdAttr ? Number(jobIdAttr) : null;
202
  if (jobId) {
203
    ReactDOM.render(
204
      <RootContainer>
205
        <JobReviewPageContainer jobId={jobId} />
206
      </RootContainer>,
207
      container,
208
    );
209
  }
210
}
211