Passed
Push — feature/timeline-profile-page ( 23927e...e2d9fc )
by Chris
04:49
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<JobBuilderReviewPageProps &
54
  WrappedComponentProps> = ({
55
  jobId,
56
  job,
57
  skills,
58
  keyTasks,
59
  criteria,
60
  departments,
61
  manager,
62
  user,
63
  handleSubmitJob,
64
  loadManager,
65
  handleFetchUser,
66
}): React.ReactElement => {
67
  const intl = useIntl();
68
  const { locale } = intl;
69
  if (locale !== "en" && locale !== "fr") {
70
    throw new Error("Unexpected locale");
71
  }
72
73
  useEffect((): void => {
74
    if (job && job.manager_id) {
75
      loadManager(job.manager_id);
76
    }
77
  }, [job, loadManager]);
78
79
  // Load user after Manager has loaded
80
  // eslint-disable-next-line camelcase
81
  const userId = manager?.user_id;
82
  useEffect((): void => {
83
    if (userId) {
84
      handleFetchUser(userId);
85
    }
86
  }, [handleFetchUser, userId]);
87
88
  const handleReturn = (): void => {
89
    // Go to Previous page
90
    navigate(jobBuilderSkills(locale, jobId));
91
    nprogress.done();
92
  };
93
  const handleContinue = (): void => {
94
    // Continue to next page
95
    window.location.href = managerJobIndex(locale);
96
    nprogress.start();
97
  };
98
99
  const jobIsComplete =
100
    job !== null && isJobBuilderComplete(job, keyTasks, criteria, locale);
101
102
  return (
103
    <JobBuilderStepContainer jobId={jobId} currentPage="review">
104
      {job !== null && (
105
        <JobReview
106
          job={job}
107
          manager={manager}
108
          user={user}
109
          tasks={keyTasks}
110
          criteria={criteria}
111
          skills={skills}
112
          departments={departments}
113
          validForSubmission={jobIsComplete}
114
          handleSubmit={handleSubmitJob}
115
          handleReturn={handleReturn}
116
          handleContinue={handleContinue}
117
        />
118
      )}
119
    </JobBuilderStepContainer>
120
  );
121
};
122
123
const mapStateToProps = (
124
  state: RootState,
125
  ownProps: { jobId: number },
126
): {
127
  job: Job | null;
128
  skills: Skill[];
129
  keyTasks: JobPosterKeyTask[];
130
  criteria: Criteria[];
131
  departments: Department[];
132
  manager: Manager | null;
133
  user: User | null;
134
} => ({
135
  job: getJob(state, ownProps),
136
  skills: getSkills(state),
137
  keyTasks: getTasksByJob(state, ownProps),
138
  criteria: getCriteriaByJob(state, ownProps),
139
  departments: getDepartments(state),
140
  manager: getSelectedManager(state),
141
  user: getUserById(state, {
142
    // eslint-disable-next-line camelcase, @typescript-eslint/camelcase
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