Passed
Push — feature/applicant-skills-api ( 483488 )
by Tristan
06:29
created

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

Complexity

Total Complexity 11
Complexity/F 0

Size

Lines of Code 201
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

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