Passed
Push — feature/data-request-hooks ( 562d87...7ed4d3 )
by Tristan
06:17
created

jobBuilderHooks.ts ➔ useLoadTasks   B

Complexity

Conditions 5

Size

Total Lines 27
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 20
dl 0
loc 27
rs 8.9332
c 0
b 0
f 0
cc 5
1
import { useEffect, useState } from "react";
2
import { useSelector } from "react-redux";
3
import { DispatchType } from "../configureStore";
4
import {
5
  Classification,
6
  Criteria,
7
  Department,
8
  Job,
9
  JobPosterKeyTask,
10
  Skill,
11
} from "../models/types";
12
import {
13
  getDepartments,
14
  departmentsIsLoading,
15
} from "../store/Department/deptSelector";
16
import { getDepartments as fetchDepartments } from "../store/Department/deptActions";
17
import {
18
  getCriteriaByJob,
19
  getCriteriaForJobIsUpdating,
20
  getJob,
21
  getJobIsUpdating,
22
  getTasksByJob,
23
  getTasksForJobIsUpdating,
24
} from "../store/Job/jobSelector";
25
import { RootState } from "../store/store";
26
import {
27
  fetchCriteria,
28
  fetchJob,
29
  setSelectedJob,
30
} from "../store/Job/jobActions";
31
import { getSkills, getSkillsUpdating } from "../store/Skill/skillSelector";
32
import { fetchSkills } from "../store/Skill/skillActions";
33
import { getClassifications, classificationsIsLoading } from "../store/Classification/classificationSelector";
34
import { loadClassificationsIntoState } from "../store/Classification/classificationActions";
35
36
export function useLoadJob(
37
  jobId: number | null,
38
  dispatch: DispatchType,
39
): { job: Job | null; isLoadingJob: boolean } {
40
  const job = useSelector((state: RootState) =>
41
    jobId !== null ? getJob(state, { jobId }) : null,
42
  );
43
  const isLoadingJob = useSelector((state: RootState) =>
44
    jobId !== null ? getJobIsUpdating(state, jobId) : false,
45
  );
46
  useEffect(() => {
47
    if (jobId !== null && job === null && !isLoadingJob) {
48
      dispatch(fetchJob(jobId));
49
    }
50
  }, [jobId, job, isLoadingJob, dispatch]);
51
  useEffect(() => {
52
    dispatch(setSelectedJob(jobId));
53
  }, [jobId, dispatch]);
54
  return { job, isLoadingJob };
55
}
56
57
export function useLoadTasks(
58
  jobId: number | null,
59
  dispatch: DispatchType,
60
): { tasks: JobPosterKeyTask[]; isLoadingTasks: boolean } {
61
  const tasks = useSelector((state: RootState) =>
62
    jobId !== null ? getTasksByJob(state, { jobId }) : [],
63
  );
64
  const isLoadingTasks = useSelector((state: RootState) =>
65
    jobId !== null ? getTasksForJobIsUpdating(state, jobId) : false,
66
  );
67
  const [hasFetchedTasks, setHasFetchedTasks] = useState(false);
68
  useEffect((): (() => void) => {
69
    let isSubscribed = true;
70
    if (jobId && tasks.length === 0 && !isLoadingTasks && !hasFetchedTasks) {
71
      setHasFetchedTasks(true);
72
      dispatch(fetchJob(jobId)).catch((): void => {
73
        if (isSubscribed) {
74
          setHasFetchedTasks(false);
75
        }
76
      });
77
    }
78
    return (): void => {
79
      isSubscribed = false;
80
    };
81
  }, [jobId, tasks.length, isLoadingTasks, hasFetchedTasks, dispatch]);
82
  return { tasks, isLoadingTasks };
83
}
84
85
export function useLoadCriteria(
86
  jobId: number | null,
87
  dispatch: DispatchType,
88
): {
89
  criteria: Criteria[];
90
  isLoadingCriteria: boolean;
91
} {
92
  const criteria = useSelector((state: RootState) =>
93
    jobId ? getCriteriaByJob(state, { jobId }) : [],
94
  );
95
  const isLoadingCriteria = useSelector((state: RootState) =>
96
    jobId ? getCriteriaForJobIsUpdating(state, jobId) : false,
97
  );
98
  const [hasFetchedCriteria, setHasFetchedCriteria] = useState(false);
99
  useEffect((): (() => void) => {
100
    let isSubscribed = true;
101
    if (
102
      jobId &&
103
      criteria.length === 0 &&
104
      !isLoadingCriteria &&
105
      !hasFetchedCriteria
106
    ) {
107
      setHasFetchedCriteria(true);
108
      dispatch(fetchCriteria(jobId)).catch((): void => {
109
        if (isSubscribed) {
110
          setHasFetchedCriteria(false);
111
        }
112
      });
113
    }
114
    return (): void => {
115
      isSubscribed = false;
116
    };
117
  }, [jobId, criteria.length, isLoadingCriteria, hasFetchedCriteria, dispatch]);
118
  return { criteria, isLoadingCriteria };
119
}
120
121
export function useLoadDepartments(
122
  dispatch: DispatchType,
123
): {
124
  departments: Department[];
125
  isLoadingDepartments: boolean;
126
} {
127
  const departments = useSelector(getDepartments);
128
  const isLoading = useSelector(departmentsIsLoading);
129
  useEffect((): void => {
130
    if (departments.length === 0 && !isLoading) {
131
      dispatch(fetchDepartments());
132
    }
133
  }, [departments.length, isLoading, dispatch]);
134
  return { departments, isLoadingDepartments: isLoading };
135
}
136
137
export function useLoadClassifications(
138
  dispatch: DispatchType,
139
) : {
140
  classifications: Classification[];
141
  isLoadingClassifications: boolean;
142
} {
143
144
  const classifications = useSelector(getClassifications);
145
  const isLoading = useSelector(classificationsIsLoading);
146
147
  useEffect((): void => {
148
    if (classifications.length === 0 && !isLoading) {
149
      dispatch(loadClassificationsIntoState());
150
    }
151
  }, [classifications.length, isLoading, dispatch]);
152
153
  return { classifications, isLoadingClassifications: isLoading };
154
}
155
156
export function useLoadSkills(
157
  dispatch: DispatchType,
158
): {
159
  skills: Skill[];
160
  isLoadingSkills: boolean;
161
} {
162
  const skills = useSelector(getSkills);
163
  const isLoading = useSelector(getSkillsUpdating);
164
  useEffect((): void => {
165
    if (skills.length === 0 && !isLoading) {
166
      dispatch(fetchSkills());
167
    }
168
  }, [skills.length, isLoading, dispatch]);
169
  return { skills, isLoadingSkills: isLoading };
170
}
171