placementt-core 11.0.533 → 11.0.803
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/constants.d.ts +13 -1
- package/lib/constants.js +86 -1
- package/lib/constants.js.map +1 -1
- package/lib/features/analytics/useAnalytics.d.ts +2 -0
- package/lib/features/analytics/useAnalytics.js +22 -19
- package/lib/features/analytics/useAnalytics.js.map +1 -1
- package/lib/features/global/downtime/useDowntime.d.ts +1 -0
- package/lib/features/global/downtime/useDowntime.js +9 -7
- package/lib/features/global/downtime/useDowntime.js.map +1 -1
- package/lib/features/global/users/useUserFunctions.js +1 -1
- package/lib/features/global/users/useUserFunctions.js.map +1 -1
- package/lib/features/jobs/jobsSlice.d.ts +10 -2
- package/lib/features/jobs/jobsSlice.js +5 -2
- package/lib/features/jobs/jobsSlice.js.map +1 -1
- package/lib/features/placements/studentPlacements/activePlacement.d.ts +5 -1
- package/lib/features/placements/studentPlacements/activePlacement.js +7 -3
- package/lib/features/placements/studentPlacements/activePlacement.js.map +1 -1
- package/lib/features/placements/studentPlacements/completedStudentPlacementsSlice.d.ts +3 -2
- package/lib/features/placements/studentPlacements/completedStudentPlacementsSlice.js +4 -1
- package/lib/features/placements/studentPlacements/completedStudentPlacementsSlice.js.map +1 -1
- package/lib/features/placements/studentPlacements/upcomingStudentPlacementsSlice.d.ts +2 -2
- package/lib/features/placements/studentPlacements/upcomingStudentPlacementsSlice.js +1 -1
- package/lib/features/placements/studentPlacements/upcomingStudentPlacementsSlice.js.map +1 -1
- package/lib/features/placements/studentPlacements/useStudentPlacements.d.ts +2 -12
- package/lib/features/placements/studentPlacements/useStudentPlacements.js +1 -26
- package/lib/features/placements/studentPlacements/useStudentPlacements.js.map +1 -1
- package/lib/features/updates/useUpdates.d.ts +1 -0
- package/lib/features/updates/useUpdates.js +13 -12
- package/lib/features/updates/useUpdates.js.map +1 -1
- package/lib/firebase/firebase.d.ts +5 -3
- package/lib/firebase/firebase.js +15 -9
- package/lib/firebase/firebase.js.map +1 -1
- package/lib/firebase/firebaseConfig.js.map +1 -1
- package/lib/firebase/firebaseQuery.d.ts +6 -2
- package/lib/firebase/firebaseQuery.js +11 -3
- package/lib/firebase/firebaseQuery.js.map +1 -1
- package/lib/firebase/readDatabase.d.ts +2 -4
- package/lib/firebase/readDatabase.js +30 -5
- package/lib/firebase/readDatabase.js.map +1 -1
- package/lib/firebase/writeDatabase.d.ts +6 -2
- package/lib/firebase/writeDatabase.js +2 -1
- package/lib/firebase/writeDatabase.js.map +1 -1
- package/lib/hooks.d.ts +226 -16
- package/lib/hooks.js +938 -146
- package/lib/hooks.js.map +1 -1
- package/lib/reduxHooks.d.ts +56 -4
- package/lib/reduxHooks.js +63 -19
- package/lib/reduxHooks.js.map +1 -1
- package/lib/tasksAndTips.d.ts +7 -5
- package/lib/tasksAndTips.js +487 -23
- package/lib/tasksAndTips.js.map +1 -1
- package/lib/typeDefinitions.d.ts +149 -30
- package/lib/util.d.ts +7 -2
- package/lib/util.js +32 -9
- package/lib/util.js.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +91 -3
- package/src/features/analytics/useAnalytics.tsx +25 -17
- package/src/features/global/downtime/useDowntime.tsx +11 -7
- package/src/features/global/users/useUserFunctions.tsx +1 -1
- package/src/features/jobs/jobsSlice.ts +9 -3
- package/src/features/placements/studentPlacements/activePlacement.ts +8 -3
- package/src/features/placements/studentPlacements/completedStudentPlacementsSlice.ts +5 -2
- package/src/features/placements/studentPlacements/upcomingStudentPlacementsSlice.ts +2 -2
- package/src/features/placements/studentPlacements/useStudentPlacements.tsx +4 -28
- package/src/features/updates/useUpdates.tsx +14 -12
- package/src/firebase/firebase.tsx +19 -12
- package/src/firebase/firebaseConfig.tsx +1 -1
- package/src/firebase/firebaseQuery.tsx +11 -3
- package/src/firebase/readDatabase.tsx +34 -6
- package/src/firebase/writeDatabase.tsx +3 -1
- package/src/hooks.tsx +1124 -166
- package/src/reduxHooks.ts +71 -22
- package/src/tasksAndTips.ts +495 -30
- package/src/typeDefinitions.ts +140 -35
- package/src/util.ts +45 -17
package/lib/hooks.js
CHANGED
|
@@ -5,8 +5,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.useRefDimensions = void 0;
|
|
7
7
|
exports.useStudentPlacementList = useStudentPlacementList;
|
|
8
|
-
exports.useNewInstitutePlacementList = useNewInstitutePlacementList;
|
|
9
8
|
exports.useOldInstitutePlacementList = useOldInstitutePlacementList;
|
|
9
|
+
exports.useNewInstitutePlacementList = useNewInstitutePlacementList;
|
|
10
|
+
exports.useVeryOldInstitutePlacementList = useVeryOldInstitutePlacementList;
|
|
10
11
|
exports.useFilterTablePaginator = useFilterTablePaginator;
|
|
11
12
|
exports.usePlacementListingPaginator = usePlacementListingPaginator;
|
|
12
13
|
exports.useCohortUserPaginator = useCohortUserPaginator;
|
|
@@ -22,6 +23,11 @@ exports.useApplicantWorkflowEditor = useApplicantWorkflowEditor;
|
|
|
22
23
|
exports.useInstitutePlacementListingHandler = useInstitutePlacementListingHandler;
|
|
23
24
|
exports.useGetIndividualPlacementForPlacementPage = useGetIndividualPlacementForPlacementPage;
|
|
24
25
|
exports.useOnboardingPopup = useOnboardingPopup;
|
|
26
|
+
exports.useLoadAddresses = useLoadAddresses;
|
|
27
|
+
exports.useLoadListings = useLoadListings;
|
|
28
|
+
exports.useLoadProviderPlacements = useLoadProviderPlacements;
|
|
29
|
+
exports.useLoadApplications = useLoadApplications;
|
|
30
|
+
exports.useDataViewerPaginator = useDataViewerPaginator;
|
|
25
31
|
const firestore_1 = require("firebase/firestore");
|
|
26
32
|
const react_1 = require("react");
|
|
27
33
|
const constants_1 = require("./constants");
|
|
@@ -60,19 +66,19 @@ function useStudentPlacementList({ user, student, queryConstraint, ql = DEFAULTQ
|
|
|
60
66
|
setStudentId(student.id);
|
|
61
67
|
return;
|
|
62
68
|
}
|
|
63
|
-
if (!user.viewCohorts || !user.
|
|
69
|
+
if (!user.viewCohorts || !user.viewStudents || user.viewCohorts === "none") {
|
|
64
70
|
setStudentId(undefined);
|
|
65
71
|
return;
|
|
66
72
|
}
|
|
67
|
-
if (user.viewCohorts === "all" && user.
|
|
73
|
+
if (user.viewCohorts === "all" && user.viewStudents == "all") {
|
|
68
74
|
setStudentId(student.id);
|
|
69
75
|
}
|
|
70
|
-
if (user.viewCohorts === "some" && ((_a = user.visibleCohorts) === null || _a === void 0 ? void 0 : _a.
|
|
71
|
-
if (user.
|
|
76
|
+
if (user.viewCohorts === "some" && ((_a = user.visibleCohorts) === null || _a === void 0 ? void 0 : _a.includes(student.cohort || ""))) {
|
|
77
|
+
if (user.viewStudents === "all") {
|
|
72
78
|
setStudentId(student.id);
|
|
73
79
|
return;
|
|
74
80
|
}
|
|
75
|
-
if ((_b = user.studentFilterValues) === null || _b === void 0 ? void 0 : _b.
|
|
81
|
+
if ((_b = user.studentFilterValues) === null || _b === void 0 ? void 0 : _b.includes(student.details[user.studentFilter || ""])) {
|
|
76
82
|
setStudentId(student.id);
|
|
77
83
|
return;
|
|
78
84
|
}
|
|
@@ -121,7 +127,7 @@ function useStudentPlacementList({ user, student, queryConstraint, ql = DEFAULTQ
|
|
|
121
127
|
};
|
|
122
128
|
return ({ ...{ placements, loadMoreIcon, loadMorePlacements, setQuery, setInitialQueryLimit, reset, changeQueryConstraints } });
|
|
123
129
|
}
|
|
124
|
-
function
|
|
130
|
+
function useOldInstitutePlacementList({ id, user, cohort, queryConstraint, ql = DEFAULTQUERYLIMIT, inProgress }) {
|
|
125
131
|
const [loadMoreIcon, setLoadMoreIcon] = (0, react_1.useState)(true);
|
|
126
132
|
const [query, setQuery] = (0, react_1.useState)();
|
|
127
133
|
const [initialQueryLimit, setInitialQueryLimit] = (0, react_1.useState)(ql);
|
|
@@ -131,7 +137,6 @@ function useNewInstitutePlacementList({ id, user, cohort, queryConstraint, ql =
|
|
|
131
137
|
const [startPlacementAfter, setStartPlacementAfter] = (0, react_1.useState)(); // uid, pId
|
|
132
138
|
const algoliaClient = (0, algoliasearch_1.default)(process.env.NODE_ENV === "development" ? "A0ZB50I7VS" : "XMPXCMUUOJ", user.algoliaKey);
|
|
133
139
|
const placementsIndex = algoliaClient.initIndex("placements");
|
|
134
|
-
const usersIndex = algoliaClient.initIndex("users");
|
|
135
140
|
(0, react_1.useEffect)(() => {
|
|
136
141
|
if (user.product !== "institutes" || user.userType !== "Staff") {
|
|
137
142
|
setOId(undefined);
|
|
@@ -147,30 +152,6 @@ function useNewInstitutePlacementList({ id, user, cohort, queryConstraint, ql =
|
|
|
147
152
|
}
|
|
148
153
|
const searchPlacements = async () => {
|
|
149
154
|
let placementsFound = {};
|
|
150
|
-
let userSearchString = `userType:Students AND status:active AND oId:${user.oId} AND product:${user.product}`;
|
|
151
|
-
if (cohort) {
|
|
152
|
-
userSearchString = userSearchString + ` AND cohort:${cohort}`;
|
|
153
|
-
}
|
|
154
|
-
if (user.product === "institutes" && user.userType === "Staff") {
|
|
155
|
-
const searchStudentHits = await usersIndex.search(query, {
|
|
156
|
-
filters: userSearchString
|
|
157
|
-
});
|
|
158
|
-
if (searchStudentHits) {
|
|
159
|
-
console.log("FOUND", searchStudentHits.hits.length, "students");
|
|
160
|
-
await Promise.all(searchStudentHits.hits.map(async (hit) => {
|
|
161
|
-
console.log("STUDENT", hit.objectID);
|
|
162
|
-
const constraints = [...(cohort ? [(0, firestore_1.where)("cohort", "==", cohort)] : [])];
|
|
163
|
-
if (inProgress !== undefined) {
|
|
164
|
-
constraints.push(inProgress ? (0, firestore_1.where)("inProgress", "==", true) : (0, firestore_1.where)("completed", "==", true));
|
|
165
|
-
}
|
|
166
|
-
const fPlacements = await (0, readDatabase_1.getPlacementsWhere)({ w: constraints, uid: hit.objectID, oId: hit.oId });
|
|
167
|
-
console.log("PLACEMENTS", fPlacements);
|
|
168
|
-
Object.entries(fPlacements).forEach(([k, v]) => {
|
|
169
|
-
placementsFound[k] = { ...v, student: hit };
|
|
170
|
-
});
|
|
171
|
-
}));
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
155
|
let placementSearchString = `oId:${user.oId} AND ` + (inProgress !== undefined ? (inProgress ? "inProgress:true" : "completed:true") : "");
|
|
175
156
|
if (cohort) {
|
|
176
157
|
placementSearchString = placementSearchString + ` AND cohort:${cohort}`;
|
|
@@ -216,7 +197,7 @@ function useNewInstitutePlacementList({ id, user, cohort, queryConstraint, ql =
|
|
|
216
197
|
}
|
|
217
198
|
setLoadMoreIcon(true);
|
|
218
199
|
let fPlacements = {};
|
|
219
|
-
if (((user.userGroup === "admin" || (cohort && user.viewCohorts === "some" && ((_a = user === null || user === void 0 ? void 0 : user.visibleCohorts) === null || _a === void 0 ? void 0 : _a.
|
|
200
|
+
if (((user.userGroup === "admin" || (cohort && user.viewCohorts === "some" && ((_a = user === null || user === void 0 ? void 0 : user.visibleCohorts) === null || _a === void 0 ? void 0 : _a.includes(cohort))) || (user.viewCohorts === "all" && user.viewStudents === "all")))) {
|
|
220
201
|
const queryConstraintOrdered = Boolean(queryConstraints && queryConstraints.find((v) => v.type === "orderBy"));
|
|
221
202
|
const constraints = (fStartPlacementAfter === null || fStartPlacementAfter === void 0 ? void 0 : fStartPlacementAfter.length) === 2 && fStartPlacementAfter[0] ?
|
|
222
203
|
[(0, firestore_1.limit)(placements ? DEFAULTQUERYLIMIT : initialQueryLimit),
|
|
@@ -227,13 +208,16 @@ function useNewInstitutePlacementList({ id, user, cohort, queryConstraint, ql =
|
|
|
227
208
|
// query && constraints.unshift(where("name", "==", query));
|
|
228
209
|
cohort && constraints.unshift((0, firestore_1.where)("cohort", "==", cohort));
|
|
229
210
|
const placementsQuery = await (0, readDatabase_1.getPlacementsWhere)({ w: constraints, oId: oId, raw: true });
|
|
211
|
+
console.log("PLACEMENTS RETRIEVED", placementsQuery.size);
|
|
230
212
|
const placementsWithStudentData = placementsQuery.empty ? [] : await Promise.all(placementsQuery.docs.map(async (placement) => {
|
|
231
213
|
const pData = placement.data();
|
|
232
214
|
const student = pData.uid === user.id ? user : (await (0, readDatabase_1.getUserById)(pData.uid).catch(() => false));
|
|
233
|
-
|
|
215
|
+
console.log("STUDENT", student, "PLACEMENT", id);
|
|
216
|
+
// if (!student) return false;
|
|
217
|
+
if (user.viewStudents === "some") {
|
|
234
218
|
if (!(user.studentFilter && user.studentFilterValues))
|
|
235
219
|
return false;
|
|
236
|
-
if (!user.studentFilterValues.
|
|
220
|
+
if (!user.studentFilterValues.includes(student.details[user.studentFilter])) {
|
|
237
221
|
return false;
|
|
238
222
|
}
|
|
239
223
|
}
|
|
@@ -258,7 +242,128 @@ function useNewInstitutePlacementList({ id, user, cohort, queryConstraint, ql =
|
|
|
258
242
|
};
|
|
259
243
|
return ({ ...{ placements, loadMoreIcon, loadMorePlacements, setQuery, setInitialQueryLimit, reset, changeQueryConstraints } });
|
|
260
244
|
}
|
|
261
|
-
function
|
|
245
|
+
function useNewInstitutePlacementList({ id, user, filters, view, cohort, queryConstraints, ql = DEFAULTQUERYLIMIT, inProgress }) {
|
|
246
|
+
const [query, setQuery] = (0, react_1.useState)();
|
|
247
|
+
const sorts = {
|
|
248
|
+
["Student Forename - Asc"]: {
|
|
249
|
+
value: "studentForename",
|
|
250
|
+
direction: "asc",
|
|
251
|
+
},
|
|
252
|
+
["Student Forename - Desc"]: {
|
|
253
|
+
value: "studentForename",
|
|
254
|
+
direction: "desc",
|
|
255
|
+
},
|
|
256
|
+
["Student Surname - Asc"]: {
|
|
257
|
+
value: "studentSurname",
|
|
258
|
+
direction: "asc",
|
|
259
|
+
},
|
|
260
|
+
["Student Surname - Desc"]: {
|
|
261
|
+
value: "studentSurname",
|
|
262
|
+
direction: "desc",
|
|
263
|
+
},
|
|
264
|
+
["Student Email - Asc"]: {
|
|
265
|
+
value: "studentEmail",
|
|
266
|
+
direction: "asc",
|
|
267
|
+
},
|
|
268
|
+
["Student Email - Desc"]: {
|
|
269
|
+
value: "studentEmaile",
|
|
270
|
+
direction: "desc",
|
|
271
|
+
},
|
|
272
|
+
["Provider email - Asc"]: {
|
|
273
|
+
value: "providerEmail",
|
|
274
|
+
direction: "asc",
|
|
275
|
+
},
|
|
276
|
+
["Provider email - Desc"]: {
|
|
277
|
+
value: "providerEmail",
|
|
278
|
+
direction: "desc",
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
const additionalProcessing = async (k, placement) => {
|
|
282
|
+
if (user.viewStudents === "some") {
|
|
283
|
+
if (!(user.studentFilter && user.studentFilterValues))
|
|
284
|
+
return false;
|
|
285
|
+
const student = await (0, readDatabase_1.getUserById)(placement.uid).catch(() => false);
|
|
286
|
+
if (!student)
|
|
287
|
+
return;
|
|
288
|
+
if (!user.studentFilterValues.includes(student.details[user.studentFilter])) {
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return { ...placement, id: k };
|
|
293
|
+
};
|
|
294
|
+
const { tableData, pageUp, pageDown, setFilters, page, setView, loading, updateSearch, updateSort, sort } = useDataViewerPaginator({ view, filters, sorts, queryLimit: ql, data: query, additionalEntryProcessing: additionalProcessing, onSearch: async (s, sort, page, filters, limit) => await algoliaPlacementSearch(user, s, sort, page, filters, limit, cohort, inProgress) });
|
|
295
|
+
(0, react_1.useEffect)(() => {
|
|
296
|
+
var _a;
|
|
297
|
+
// Sets the query of for the DataViewerPaginator
|
|
298
|
+
if (user.product !== "institutes" || user.userType !== "Staff") {
|
|
299
|
+
setQuery(undefined);
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
if (((user.userGroup === "admin" || (cohort && user.viewCohorts === "some" && ((_a = user === null || user === void 0 ? void 0 : user.visibleCohorts) === null || _a === void 0 ? void 0 : _a.includes(cohort))) || (user.viewCohorts === "all" && user.viewStudents === "all")))) {
|
|
303
|
+
const constraints = [["oId", "==", user.oId], ["draft", "==", false]];
|
|
304
|
+
cohort && constraints.push(["cohort", "==", cohort]);
|
|
305
|
+
queryConstraints && constraints.unshift(...queryConstraints);
|
|
306
|
+
inProgress !== undefined && constraints.push(["inProgress", "==", inProgress]);
|
|
307
|
+
setQuery([{
|
|
308
|
+
path: ["placements"],
|
|
309
|
+
where: constraints
|
|
310
|
+
}]);
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
setQuery(undefined);
|
|
314
|
+
}, [user, queryConstraints, cohort]);
|
|
315
|
+
return { tableData, page, loading, updateSearch, setFilters, setView, pageUp, pageDown, sorts, updateSort, sort };
|
|
316
|
+
}
|
|
317
|
+
const algoliaPlacementSearch = async (user, query, sort, page, filters, limit, cohort, inProgress) => {
|
|
318
|
+
const algoliaClient = (0, algoliasearch_1.default)(process.env.NODE_ENV === "development" ? "A0ZB50I7VS" : "XMPXCMUUOJ", user.algoliaKey);
|
|
319
|
+
const placementsIndex = algoliaClient.initIndex(sort ? Object.values(sort[1]).join("_") : "placements");
|
|
320
|
+
// const usersIndex = algoliaClient.initIndex("users");
|
|
321
|
+
// let userSearchString = `userType:Students AND status:active AND oId:${user.oId} AND product:${user.product}`
|
|
322
|
+
// if (cohort) {
|
|
323
|
+
// userSearchString = userSearchString + ` AND cohort:${cohort}`;
|
|
324
|
+
// }
|
|
325
|
+
// if (user.product === "institutes" && user.userType === "Staff") {
|
|
326
|
+
// const searchStudentHits = await usersIndex.search<UserData>(query, {
|
|
327
|
+
// filters: userSearchString,
|
|
328
|
+
// hitsPerPage: limit,
|
|
329
|
+
// page: page
|
|
330
|
+
// });
|
|
331
|
+
// if (searchStudentHits) {
|
|
332
|
+
// console.log("FOUND", searchStudentHits.hits.length, "students");
|
|
333
|
+
// await Promise.all(searchStudentHits.hits.map(async (hit) => {
|
|
334
|
+
// console.log("STUDENT", hit.objectID);
|
|
335
|
+
// const constraints = [...(cohort ? [where("cohort", "==", cohort)] : [])]
|
|
336
|
+
// if (inProgress !== undefined) {
|
|
337
|
+
// constraints.push(inProgress ? where("inProgress", "==", true) : where("completed", "==", true));
|
|
338
|
+
// }
|
|
339
|
+
// const fPlacements = await getPlacementsWhere({w: constraints, uid: hit.objectID, oId: hit.oId}) as {[key: string]: StudentPlacementData};
|
|
340
|
+
// console.log("PLACEMENTS", fPlacements)
|
|
341
|
+
// Object.entries(fPlacements).forEach(([k, v]) => {
|
|
342
|
+
// placementsFound[k] = {...v, student: hit};
|
|
343
|
+
// })
|
|
344
|
+
// }))
|
|
345
|
+
// }
|
|
346
|
+
// }
|
|
347
|
+
let placementSearchString = `oId:${user.oId} AND ` + (inProgress !== undefined ? (inProgress ? "inProgress:true" : "completed:true") : "");
|
|
348
|
+
if (cohort) {
|
|
349
|
+
placementSearchString = placementSearchString + ` AND cohort:${cohort}`;
|
|
350
|
+
}
|
|
351
|
+
filters && Object.entries(filters).filter(([, filter]) => filter.value).map(([id, filter]) => {
|
|
352
|
+
placementSearchString = placementSearchString + ` AND ${id}:${filter.value}`;
|
|
353
|
+
});
|
|
354
|
+
const options = {
|
|
355
|
+
filters: placementSearchString,
|
|
356
|
+
hitsPerPage: limit,
|
|
357
|
+
page: page ? page - 1 : undefined,
|
|
358
|
+
};
|
|
359
|
+
const searchPlacementHits = await placementsIndex.search(query || "", options);
|
|
360
|
+
console.log(searchPlacementHits.hits);
|
|
361
|
+
const i = (searchPlacementHits ? (await Promise.all(searchPlacementHits.hits.map(async (hit) => {
|
|
362
|
+
return [hit.objectID, hit];
|
|
363
|
+
}))) : []).filter((e) => e !== undefined);
|
|
364
|
+
return Object.fromEntries(i);
|
|
365
|
+
};
|
|
366
|
+
function useVeryOldInstitutePlacementList({ user, cohort, queryConstraint, ql = DEFAULTQUERYLIMIT }) {
|
|
262
367
|
const [loadMoreIcon, setLoadMoreIcon] = (0, react_1.useState)(true);
|
|
263
368
|
const [query, setQuery] = (0, react_1.useState)("");
|
|
264
369
|
const [initialQueryLimit, setInitialQueryLimit] = (0, react_1.useState)(ql);
|
|
@@ -299,7 +404,7 @@ function useOldInstitutePlacementList({ user, cohort, queryConstraint, ql = DEFA
|
|
|
299
404
|
setLoadMoreIcon(true);
|
|
300
405
|
// If can view all, query placements directly. Otherwise query students.
|
|
301
406
|
let fPlacements = {};
|
|
302
|
-
if (((user.userGroup === "admin" || (cohort && user.viewCohorts === "some" && ((_a = user === null || user === void 0 ? void 0 : user.visibleCohorts) === null || _a === void 0 ? void 0 : _a.
|
|
407
|
+
if (((user.userGroup === "admin" || (cohort && user.viewCohorts === "some" && ((_a = user === null || user === void 0 ? void 0 : user.visibleCohorts) === null || _a === void 0 ? void 0 : _a.includes(cohort))) || (user.viewCohorts === "all" && user.viewStudents === "all") || query) && (fStartPlacementAfter && fStartPlacementAfter[0] === "placement"))) {
|
|
303
408
|
const queryConstraintOrdered = Boolean(queryConstraints && queryConstraints.find((v) => v.type === "orderBy"));
|
|
304
409
|
const constraints = (fStartPlacementAfter === null || fStartPlacementAfter === void 0 ? void 0 : fStartPlacementAfter.length) === 4 && fStartPlacementAfter[1] ?
|
|
305
410
|
[(0, firestore_1.limit)(placements ? DEFAULTQUERYLIMIT : initialQueryLimit),
|
|
@@ -314,10 +419,10 @@ function useOldInstitutePlacementList({ user, cohort, queryConstraint, ql = DEFA
|
|
|
314
419
|
const placementsWithStudentData = placementsQuery.empty ? [] : await Promise.all(placementsQuery.docs.map(async (placement) => {
|
|
315
420
|
const pData = placement.data();
|
|
316
421
|
const student = pData.uid === user.id ? user : (await (0, readDatabase_1.getUserById)(pData.uid).catch(() => false));
|
|
317
|
-
if (user.
|
|
422
|
+
if (user.viewStudents === "some") {
|
|
318
423
|
if (!(user.studentFilter && user.studentFilterValues))
|
|
319
424
|
return false;
|
|
320
|
-
if (!user.studentFilterValues.
|
|
425
|
+
if (!user.studentFilterValues.includes(student.details[user.studentFilter])) {
|
|
321
426
|
return false;
|
|
322
427
|
}
|
|
323
428
|
}
|
|
@@ -342,13 +447,13 @@ function useOldInstitutePlacementList({ user, cohort, queryConstraint, ql = DEFA
|
|
|
342
447
|
return;
|
|
343
448
|
}
|
|
344
449
|
}
|
|
345
|
-
if (!(user.studentFilterValues && user.studentFilter && user.
|
|
450
|
+
if (!(user.studentFilterValues && user.studentFilter && user.viewStudents === "some")) {
|
|
346
451
|
console.log("fenaibn");
|
|
347
452
|
return;
|
|
348
453
|
}
|
|
349
454
|
;
|
|
350
455
|
const getStudentPlacements = async (ffStartPlacementAfter = fStartPlacementAfter, ffPlacements = fPlacements) => {
|
|
351
|
-
var _a
|
|
456
|
+
var _a;
|
|
352
457
|
if (ffStartPlacementAfter && ffStartPlacementAfter[0] === "placement") {
|
|
353
458
|
ffStartPlacementAfter = [undefined, undefined, undefined, 0];
|
|
354
459
|
}
|
|
@@ -358,7 +463,7 @@ function useOldInstitutePlacementList({ user, cohort, queryConstraint, ql = DEFA
|
|
|
358
463
|
[(0, firestore_1.limit)(1), (0, firestore_1.orderBy)((0, firestore_1.documentId)())];
|
|
359
464
|
constraints.push((0, firestore_1.where)("oId", "==", oId), (0, firestore_1.where)("userType", "==", "Students"));
|
|
360
465
|
if (ffStartPlacementAfter && ffStartPlacementAfter[3]) {
|
|
361
|
-
const currentFilter = (_a = user === null || user === void 0 ? void 0 : user.studentFilterValues) === null || _a === void 0 ? void 0 : _a
|
|
466
|
+
const currentFilter = (_a = user === null || user === void 0 ? void 0 : user.studentFilterValues) === null || _a === void 0 ? void 0 : _a[ffStartPlacementAfter[3]];
|
|
362
467
|
if (currentFilter && user.studentFilter) {
|
|
363
468
|
constraints.push((0, firestore_1.where)(user.studentFilter, "==", currentFilter));
|
|
364
469
|
}
|
|
@@ -367,7 +472,7 @@ function useOldInstitutePlacementList({ user, cohort, queryConstraint, ql = DEFA
|
|
|
367
472
|
const student = Object.entries((await firebaseQuery.getDocsWhere("users", constraints)))[0];
|
|
368
473
|
// console.log("student", student);
|
|
369
474
|
// If there is no students but more filters
|
|
370
|
-
if (!student && ffStartPlacementAfter && ffStartPlacementAfter[3] + 1 < ((
|
|
475
|
+
if (!student && ffStartPlacementAfter && ffStartPlacementAfter[3] + 1 < ((user === null || user === void 0 ? void 0 : user.studentFilterValues) || []).length) {
|
|
371
476
|
// console.log("No more students. Calling recursion");
|
|
372
477
|
return await getStudentPlacements(["student", undefined, undefined, ffStartPlacementAfter[3] + 1], ffPlacements);
|
|
373
478
|
}
|
|
@@ -577,7 +682,7 @@ function useFilterTablePaginator({ data }) {
|
|
|
577
682
|
if (!Object.keys(itemList).length)
|
|
578
683
|
return;
|
|
579
684
|
console.log("Fetching filter table updates");
|
|
580
|
-
const itemListUpdateQuery = (0, firestore_1.query)((0, firestore_1.collection)(firebaseConfig_1.db,
|
|
685
|
+
const itemListUpdateQuery = (0, firestore_1.query)((0, firestore_1.collection)(firebaseConfig_1.db, ...querySchema.path), (0, firestore_1.where)((0, firestore_1.documentId)(), "in", Object.keys(itemList)));
|
|
581
686
|
const itemUpdateSnapshot = (0, firestore_1.onSnapshot)(itemListUpdateQuery, (querySnapshot) => {
|
|
582
687
|
querySnapshot.docs.forEach((doc) => {
|
|
583
688
|
setTableData((data) => {
|
|
@@ -747,9 +852,9 @@ function usePlacementListingPaginator({ data, user }) {
|
|
|
747
852
|
setQueryAnchor({ ...currentQueryAnchor, startKey: Object.keys(itemList)[0], endKey: Object.keys(itemList).slice(-1)[0] });
|
|
748
853
|
const finalData = Object.fromEntries(await Promise.all(Object.entries(itemList).map(async ([k, v]) => {
|
|
749
854
|
const placement = await firebaseQuery.getDocData(["placementListings", v.placementId || ""]);
|
|
750
|
-
const address = await firebaseQuery.getDocData(["addresses", placement.addressId || ""]);
|
|
751
|
-
const provider = await firebaseQuery.getDocData(["providers", placement.providerId || ""]);
|
|
752
|
-
const status = getPlacementStatus(provider, placement, v);
|
|
855
|
+
const address = await firebaseQuery.getDocData(["addresses", placement.addressId || ""]).catch(() => ({ ["address-line1"]: "Unknown address" }));
|
|
856
|
+
const provider = await firebaseQuery.getDocData(["providers", placement.providerId || ""]).catch(() => ({ name: "Unknown" }));
|
|
857
|
+
const status = provider.name !== "Unknown" ? getPlacementStatus(provider, placement, v) : "Deleted";
|
|
753
858
|
return [k, { ...address, ...provider, ...placement, email: placement.providerEmail, status: status, savedPlacement: v }];
|
|
754
859
|
})));
|
|
755
860
|
setTableData(finalData);
|
|
@@ -785,10 +890,11 @@ function usePlacementListingPaginator({ data, user }) {
|
|
|
785
890
|
}, [page]);
|
|
786
891
|
return ({ ...{ tableData, setPage, setFilters, page } });
|
|
787
892
|
}
|
|
788
|
-
function useCohortUserPaginator({ user, cohort, data, search, userType }) {
|
|
893
|
+
function useCohortUserPaginator({ user, cohort, data, search, userType, sort }) {
|
|
789
894
|
const [tableData, setTableData] = (0, react_1.useState)({});
|
|
790
|
-
const [queryAnchor, setQueryAnchor] = (0, react_1.useState)({
|
|
895
|
+
const [queryAnchor, setQueryAnchor] = (0, react_1.useState)({ startDoc: undefined, endDoc: undefined, startQueryPos: 0, endQueryPos: 0 });
|
|
791
896
|
const [filters, setFilters] = (0, react_1.useState)();
|
|
897
|
+
const [sortResultsBy, setSortResultsBy] = (0, react_1.useState)(sort);
|
|
792
898
|
const [prevEntryIds, setPrevEntryIds] = (0, react_1.useState)({});
|
|
793
899
|
const [page, setPage] = (0, react_1.useState)([1, 0]);
|
|
794
900
|
const [dataListenerUnsubscribe, setDataListenerUnsubscribe] = (0, react_1.useState)();
|
|
@@ -796,6 +902,14 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
|
|
|
796
902
|
const [prevSearch, setPrevSearch] = (0, react_1.useState)();
|
|
797
903
|
const algoliaClient = (0, algoliasearch_1.default)(process.env.NODE_ENV === "development" ? "A0ZB50I7VS" : "XMPXCMUUOJ", user.algoliaKey);
|
|
798
904
|
const usersIndex = algoliaClient.initIndex("users");
|
|
905
|
+
const sortOptions = {
|
|
906
|
+
["Forename - Asc"]: ["details.forename", "asc"],
|
|
907
|
+
["Forename - Desc"]: ["details.forename", "desc"],
|
|
908
|
+
["Surname - Asc"]: ["details.surname", "desc"],
|
|
909
|
+
["Surname - Desc"]: ["details.surname", "asc"],
|
|
910
|
+
["Email - Asc"]: ["email", "asc"],
|
|
911
|
+
["Email - Desc"]: ["email", "desc"],
|
|
912
|
+
};
|
|
799
913
|
(0, react_1.useEffect)(() => {
|
|
800
914
|
var _a;
|
|
801
915
|
if (user.userType !== "Staff") {
|
|
@@ -805,7 +919,7 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
|
|
|
805
919
|
}
|
|
806
920
|
if ((!user.viewCohorts && user.userGroup !== "admin") ||
|
|
807
921
|
user.viewCohorts === "none" ||
|
|
808
|
-
(user.viewCohorts === "some" && cohort !== "all" && !((_a = user.visibleCohorts) === null || _a === void 0 ? void 0 : _a.
|
|
922
|
+
(user.viewCohorts === "some" && cohort !== "all" && !((_a = user.visibleCohorts) === null || _a === void 0 ? void 0 : _a.includes(cohort || "")))) {
|
|
809
923
|
setQueries(undefined);
|
|
810
924
|
return;
|
|
811
925
|
}
|
|
@@ -821,13 +935,13 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
|
|
|
821
935
|
});
|
|
822
936
|
constraints.push((0, firestore_1.where)("oId", "==", user.oId));
|
|
823
937
|
cohort && cohort !== "all" && constraints.push((0, firestore_1.where)("cohort", "==", cohort));
|
|
824
|
-
if (user.userGroup === "admin" || user.
|
|
938
|
+
if (user.userGroup === "admin" || user.viewStudents === "all") {
|
|
825
939
|
finalConstraints.push(constraints);
|
|
826
940
|
continue;
|
|
827
941
|
}
|
|
828
942
|
if (!user.studentFilter || !user.studentFilterValues)
|
|
829
943
|
continue;
|
|
830
|
-
user.studentFilterValues.
|
|
944
|
+
user.studentFilterValues.forEach((filterValue) => {
|
|
831
945
|
user.studentFilter && finalConstraints.push([...constraints, (0, firestore_1.where)("details." + user.studentFilter, "==", filterValue)]);
|
|
832
946
|
});
|
|
833
947
|
}
|
|
@@ -837,7 +951,7 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
|
|
|
837
951
|
});
|
|
838
952
|
}, []);
|
|
839
953
|
const getDataFromQuery = async (itemList = {}, currentQueryAnchor = queryAnchor, cursorDirection, prevEntries = prevEntryIds, loadMoreFromQuery = false) => {
|
|
840
|
-
if (!queries) {
|
|
954
|
+
if (!(queries === null || queries === void 0 ? void 0 : queries.length)) {
|
|
841
955
|
setTableData({});
|
|
842
956
|
return;
|
|
843
957
|
}
|
|
@@ -854,17 +968,42 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
|
|
|
854
968
|
const createQuery = (mConstraints) => {
|
|
855
969
|
console.log("mConstraints", mConstraints);
|
|
856
970
|
const fConstraints = [...mConstraints];
|
|
971
|
+
let addOrderBy = true;
|
|
857
972
|
filters && Object.entries(filters).forEach(([key, value]) => {
|
|
858
|
-
if (
|
|
973
|
+
if (Array.isArray(value)) {
|
|
974
|
+
value.forEach((v) => {
|
|
975
|
+
if (typeof v === "object") {
|
|
976
|
+
if (v instanceof firestore_1.QueryOrderByConstraint) {
|
|
977
|
+
addOrderBy = false;
|
|
978
|
+
}
|
|
979
|
+
fConstraints.push(v);
|
|
980
|
+
}
|
|
981
|
+
else {
|
|
982
|
+
fConstraints.push((0, firestore_1.where)(key, "==", v));
|
|
983
|
+
}
|
|
984
|
+
});
|
|
985
|
+
}
|
|
986
|
+
else if (typeof value === "object") {
|
|
987
|
+
if (value instanceof firestore_1.QueryOrderByConstraint) {
|
|
988
|
+
addOrderBy = false;
|
|
989
|
+
}
|
|
859
990
|
fConstraints.push(value);
|
|
860
991
|
}
|
|
861
992
|
else {
|
|
862
993
|
fConstraints.push((0, firestore_1.where)(key, "==", value));
|
|
863
994
|
}
|
|
864
995
|
});
|
|
865
|
-
|
|
996
|
+
console.log("Add order by", addOrderBy);
|
|
997
|
+
if (addOrderBy) {
|
|
998
|
+
if (sortResultsBy) {
|
|
999
|
+
fConstraints.push((0, firestore_1.orderBy)(sortOptions[sortResultsBy][0], sortOptions[sortResultsBy][1]));
|
|
1000
|
+
}
|
|
1001
|
+
else {
|
|
1002
|
+
fConstraints.push((0, firestore_1.orderBy)((0, firestore_1.documentId)()));
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
866
1005
|
if (page[0] > page[1] && !cursorDirection) { // Going up
|
|
867
|
-
currentQueryAnchor.
|
|
1006
|
+
currentQueryAnchor.endDoc && fConstraints.push((0, firestore_1.startAfter)(currentQueryAnchor.endDoc));
|
|
868
1007
|
fConstraints.push((0, firestore_1.limit)(10));
|
|
869
1008
|
if (!loadMoreFromQuery) {
|
|
870
1009
|
currentQueryAnchor = { ...currentQueryAnchor, startQueryPos: currentQueryAnchor.endQueryPos };
|
|
@@ -875,11 +1014,11 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
|
|
|
875
1014
|
currentQueryAnchor = { ...currentQueryAnchor, endQueryPos: currentQueryAnchor.startQueryPos };
|
|
876
1015
|
}
|
|
877
1016
|
fConstraints.push((0, firestore_1.limitToLast)(10));
|
|
878
|
-
if (currentQueryAnchor.
|
|
879
|
-
currentQueryAnchor.
|
|
1017
|
+
if (currentQueryAnchor.startDoc) {
|
|
1018
|
+
currentQueryAnchor.startDoc && fConstraints.push((0, firestore_1.endBefore)(currentQueryAnchor.startDoc));
|
|
880
1019
|
}
|
|
881
1020
|
else {
|
|
882
|
-
currentQueryAnchor.
|
|
1021
|
+
currentQueryAnchor.startDoc && fConstraints.push((0, firestore_1.endAt)(currentQueryAnchor.startDoc));
|
|
883
1022
|
}
|
|
884
1023
|
}
|
|
885
1024
|
else {
|
|
@@ -918,9 +1057,7 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
|
|
|
918
1057
|
console.log("Removing ", doc.id, ": E=", prevEntries[doc.id], ", G=", position);
|
|
919
1058
|
return;
|
|
920
1059
|
}
|
|
921
|
-
|
|
922
|
-
item.id = doc.id;
|
|
923
|
-
queryResults[doc.id] = item;
|
|
1060
|
+
queryResults[doc.id] = doc;
|
|
924
1061
|
index = index + 1;
|
|
925
1062
|
if (prevEntries[doc.id])
|
|
926
1063
|
return;
|
|
@@ -942,7 +1079,7 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
|
|
|
942
1079
|
}
|
|
943
1080
|
}
|
|
944
1081
|
if (Object.keys(itemList).length < 10 && queryData.size === 10) {
|
|
945
|
-
return getDataFromQuery(itemList, { ...currentQueryAnchor,
|
|
1082
|
+
return getDataFromQuery(itemList, { ...currentQueryAnchor, startDoc: Object.values(itemList)[0], endDoc: Object.values(itemList).slice(-1)[0] }, undefined, prevEntries, true);
|
|
946
1083
|
}
|
|
947
1084
|
if (queryData.size === 0 &&
|
|
948
1085
|
Object.keys(itemList).length === 0 &&
|
|
@@ -968,8 +1105,8 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
|
|
|
968
1105
|
setDataListenerUnsubscribe(() => itemUpdateSnapshot);
|
|
969
1106
|
};
|
|
970
1107
|
listenForUpdates();
|
|
971
|
-
setQueryAnchor({ ...currentQueryAnchor,
|
|
972
|
-
setTableData(itemList);
|
|
1108
|
+
setQueryAnchor({ ...currentQueryAnchor, startDoc: Object.values(itemList)[0], endDoc: Object.values(itemList).slice(-1)[0] });
|
|
1109
|
+
setTableData(Object.fromEntries(Object.entries(itemList).map(([k, v]) => [k, { id: k, ...v.data() }])));
|
|
973
1110
|
};
|
|
974
1111
|
const searchUsers = async () => {
|
|
975
1112
|
if (!search)
|
|
@@ -1006,10 +1143,10 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
|
|
|
1006
1143
|
setPage([1, 0]);
|
|
1007
1144
|
console.log("Set page");
|
|
1008
1145
|
setTableData({});
|
|
1009
|
-
setQueryAnchor({
|
|
1146
|
+
setQueryAnchor({ startQueryPos: 0, endQueryPos: 0 });
|
|
1010
1147
|
setPrevEntryIds({});
|
|
1011
1148
|
dataListenerUnsubscribe && dataListenerUnsubscribe();
|
|
1012
|
-
}, [filters, search]);
|
|
1149
|
+
}, [filters, search, sortResultsBy]);
|
|
1013
1150
|
// Fetch new data when queries or page change
|
|
1014
1151
|
(0, react_1.useEffect)(() => {
|
|
1015
1152
|
if (search) {
|
|
@@ -1020,7 +1157,8 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
|
|
|
1020
1157
|
getDataFromQuery();
|
|
1021
1158
|
dataListenerUnsubscribe && dataListenerUnsubscribe();
|
|
1022
1159
|
}, [page, queries, prevSearch]);
|
|
1023
|
-
|
|
1160
|
+
const setSort = (s) => setSortResultsBy(s);
|
|
1161
|
+
return ({ ...{ tableData, setPage, page, setFilters, setSort, sortOptions: Object.keys(sortOptions), sortBy: sortResultsBy } });
|
|
1024
1162
|
}
|
|
1025
1163
|
function useAdmissionsPaginator({ data }) {
|
|
1026
1164
|
const [tableData, setTableData] = (0, react_1.useState)({});
|
|
@@ -1109,7 +1247,7 @@ function usePublicPlacementListingLoader({ providerId, number = 5 }) {
|
|
|
1109
1247
|
const applicantWorkflow = (await firebaseQuery.getDocData(["applicantWorkflows", itemObj.applicantWorkflowId])).workflow.filter((i) => i.id === 1)[0];
|
|
1110
1248
|
const applicantFiles = applicantWorkflow.files ? Object.fromEntries(await Promise.all((_a = applicantWorkflow.files) === null || _a === void 0 ? void 0 : _a.map(async (fileId) => {
|
|
1111
1249
|
const file = await firebaseQuery.getDocData(["files", fileId]);
|
|
1112
|
-
file.url = await (0, storage_1.getDownloadURL)((0, storage_1.ref)(firebaseConfig_1.storage, `
|
|
1250
|
+
file.url = await (0, storage_1.getDownloadURL)((0, storage_1.ref)(firebaseConfig_1.storage, `providers/${itemObj.providerId}/${file.fileName}`));
|
|
1113
1251
|
return [fileId, file];
|
|
1114
1252
|
}))) : [];
|
|
1115
1253
|
const applicantForms = applicantWorkflow.forms ? Object.fromEntries(await Promise.all((_b = applicantWorkflow.forms) === null || _b === void 0 ? void 0 : _b.map(async (formId) => {
|
|
@@ -1138,6 +1276,7 @@ function useCreateApplicationRenderer({ user, listingId, listing, provider, appl
|
|
|
1138
1276
|
const [fApplication, setFApplication] = (0, react_1.useState)(application ? applicationWithoutAdditionalData : {
|
|
1139
1277
|
uid: user.userType === "Students" ? user.id : undefined,
|
|
1140
1278
|
listingId: listingId,
|
|
1279
|
+
addressId: listing === null || listing === void 0 ? void 0 : listing.addressId,
|
|
1141
1280
|
stage: 1,
|
|
1142
1281
|
reqUserType: "Students",
|
|
1143
1282
|
status: "draft"
|
|
@@ -1145,7 +1284,7 @@ function useCreateApplicationRenderer({ user, listingId, listing, provider, appl
|
|
|
1145
1284
|
const [fApplicationId, setFApplicationId] = (0, react_1.useState)(applicationId);
|
|
1146
1285
|
const [draftSaved, setDraftSaved] = (0, react_1.useState)(false);
|
|
1147
1286
|
const [fProvider, setFProvider] = (0, react_1.useState)(provider);
|
|
1148
|
-
const [fListing, setFListing] = (0, react_1.useState)(listing);
|
|
1287
|
+
const [fListing, setFListing] = (0, react_1.useState)(Object.keys(listing || {}).length > 5 ? listing : undefined);
|
|
1149
1288
|
const [student, setStudent] = (0, react_1.useState)(user.userType === "Students" ? user : undefined);
|
|
1150
1289
|
const [profileUrl, setProfileUrl] = (0, react_1.useState)();
|
|
1151
1290
|
const [successPopup, setSuccessPopup] = (0, react_1.useState)();
|
|
@@ -1157,30 +1296,35 @@ function useCreateApplicationRenderer({ user, listingId, listing, provider, appl
|
|
|
1157
1296
|
if (!listingId)
|
|
1158
1297
|
return;
|
|
1159
1298
|
console.log("Getting listing");
|
|
1160
|
-
|
|
1161
|
-
const
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1299
|
+
console.log("LISTING PARAM", listing, Object.keys(listing || {}).length > 5);
|
|
1300
|
+
const listingData = (Object.keys(listing || {}).length > 5) ? listing : await firebaseQuery.getDocData(["placementListings", listingId]).catch(() => false);
|
|
1301
|
+
console.log("LISTINGDATA", listingData, Object.keys(listing || {}).length > 5 ? { a: "string" } : "AAA");
|
|
1302
|
+
const address = listingData ? (user.product === "providers" && orgContext) ? orgContext.addresses[listingData.addressId || ""] : await firebaseQuery.getDocData(["addresses", listingData.addressId]) : undefined;
|
|
1303
|
+
const workflow = listingData ? (user.product === "providers" && orgContext) ? orgContext.applicantWorkflows[listingData.applicantWorkflowId || ""] : await firebaseQuery.getDocData(["applicantWorkflows", listingData.applicantWorkflowId]) : undefined;
|
|
1304
|
+
if (workflow && listingData) {
|
|
1305
|
+
workflow.workflow = await Promise.all(workflow.workflow.map(async (s) => {
|
|
1306
|
+
var _a, _b;
|
|
1307
|
+
const applicantFiles = s.files ? Object.fromEntries(await Promise.all((_a = s.files) === null || _a === void 0 ? void 0 : _a.map(async (fileId) => {
|
|
1308
|
+
const file = await firebaseQuery.getDocData(["files", fileId]);
|
|
1309
|
+
file.url = await (0, storage_1.getDownloadURL)((0, storage_1.ref)(firebaseConfig_1.storage, `providers/${listingData === null || listingData === void 0 ? void 0 : listingData.providerId}/${file.fileName}`));
|
|
1310
|
+
return [fileId, file];
|
|
1311
|
+
}))) : [];
|
|
1312
|
+
const applicantForms = s.forms ? Object.fromEntries(await Promise.all((_b = s.forms) === null || _b === void 0 ? void 0 : _b.map(async (formId) => {
|
|
1313
|
+
return [formId, await firebaseQuery.getDocData(["forms", formId])];
|
|
1314
|
+
}))) : [];
|
|
1315
|
+
return { ...s, viewableFiles: applicantFiles, formDetails: applicantForms };
|
|
1316
|
+
}));
|
|
1317
|
+
delete workflow.id;
|
|
1318
|
+
}
|
|
1319
|
+
if (address) {
|
|
1320
|
+
delete address.id;
|
|
1321
|
+
}
|
|
1177
1322
|
console.log("Setting listing");
|
|
1178
|
-
setFListing({ ...listingData, ...address, applicantWorkflow: workflow.workflow });
|
|
1179
|
-
console.log("Getting provider", listingData === null || listingData === void 0 ? void 0 : listingData.providerId);
|
|
1323
|
+
setFListing((listingData && workflow) ? { ...listingData, ...address, applicantWorkflow: workflow.workflow } : false);
|
|
1180
1324
|
if (((fProvider === null || fProvider === void 0 ? void 0 : fProvider.id) === (application === null || application === void 0 ? void 0 : application.providerId)) && user.product === "providers") {
|
|
1181
1325
|
setFProvider({ details: orgContext === null || orgContext === void 0 ? void 0 : orgContext.details, id: user.oId });
|
|
1182
1326
|
}
|
|
1183
|
-
else if (listingData === null || listingData === void 0 ? void 0 : listingData.providerId) {
|
|
1327
|
+
else if (listingData && (listingData === null || listingData === void 0 ? void 0 : listingData.providerId)) {
|
|
1184
1328
|
console.log("Getting provider from DB");
|
|
1185
1329
|
const provider = await firebaseQuery.getDocData(["providers", listingData.providerId]);
|
|
1186
1330
|
console.log("Provider", provider);
|
|
@@ -1200,7 +1344,7 @@ function useCreateApplicationRenderer({ user, listingId, listing, provider, appl
|
|
|
1200
1344
|
}
|
|
1201
1345
|
}, []);
|
|
1202
1346
|
(0, react_1.useEffect)(() => {
|
|
1203
|
-
setFListing(listing);
|
|
1347
|
+
setFListing(Object.keys(listing || {}).length > 5 ? listing : undefined);
|
|
1204
1348
|
}, [listing]);
|
|
1205
1349
|
(0, react_1.useEffect)(() => {
|
|
1206
1350
|
if (provider === null || provider === void 0 ? void 0 : provider.profile)
|
|
@@ -1224,11 +1368,25 @@ function useCreateApplicationRenderer({ user, listingId, listing, provider, appl
|
|
|
1224
1368
|
});
|
|
1225
1369
|
return;
|
|
1226
1370
|
}
|
|
1227
|
-
if (applicationId)
|
|
1371
|
+
if (applicationId) {
|
|
1228
1372
|
setFApplicationId(applicationId);
|
|
1373
|
+
if (application) {
|
|
1374
|
+
let applicationWithoutAdditionalData = { ...(application || {}) };
|
|
1375
|
+
delete applicationWithoutAdditionalData.listing;
|
|
1376
|
+
delete applicationWithoutAdditionalData.address;
|
|
1377
|
+
delete applicationWithoutAdditionalData.provider;
|
|
1378
|
+
setFApplication(applicationWithoutAdditionalData);
|
|
1379
|
+
}
|
|
1380
|
+
else {
|
|
1381
|
+
firebaseQuery.getDocData(["applications", applicationId]).then(setFApplication);
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1229
1384
|
}, [application, applicationId]);
|
|
1230
1385
|
const getCurrentStage = async (stage) => {
|
|
1231
1386
|
var _a, _b, _c, _d;
|
|
1387
|
+
console.log("fLSITING CURRENT STAGE", fListing);
|
|
1388
|
+
if (!fListing)
|
|
1389
|
+
throw new Error("Listing deleted");
|
|
1232
1390
|
if (!(fListing === null || fListing === void 0 ? void 0 : fListing.applicantWorkflowId))
|
|
1233
1391
|
throw new Error("No workflow stage");
|
|
1234
1392
|
const mApplicantWorkflow = await firebaseQuery.getDocData(["applicantWorkflows", fListing.applicantWorkflowId]);
|
|
@@ -1237,7 +1395,7 @@ function useCreateApplicationRenderer({ user, listingId, listing, provider, appl
|
|
|
1237
1395
|
throw new Error("Can't find stage.");
|
|
1238
1396
|
const applicantFiles = stageObj.files ? Object.fromEntries(await Promise.all((_b = stageObj.files) === null || _b === void 0 ? void 0 : _b.map(async (fileId) => {
|
|
1239
1397
|
const file = await firebaseQuery.getDocData(["files", fileId]);
|
|
1240
|
-
file.url = await (0, storage_1.getDownloadURL)((0, storage_1.ref)(firebaseConfig_1.storage, `
|
|
1398
|
+
file.url = await (0, storage_1.getDownloadURL)((0, storage_1.ref)(firebaseConfig_1.storage, `providers/${mApplicantWorkflow === null || mApplicantWorkflow === void 0 ? void 0 : mApplicantWorkflow.oId}/${file.fileName}`));
|
|
1241
1399
|
return [fileId, file];
|
|
1242
1400
|
}))) : [];
|
|
1243
1401
|
const applicantForms = stageObj.forms ? Object.fromEntries(await Promise.all((_c = stageObj.forms) === null || _c === void 0 ? void 0 : _c.map(async (formId) => {
|
|
@@ -1267,11 +1425,12 @@ function useCreateApplicationRenderer({ user, listingId, listing, provider, appl
|
|
|
1267
1425
|
};
|
|
1268
1426
|
const addApplication = async () => {
|
|
1269
1427
|
console.log("ADDING APPLICATION");
|
|
1270
|
-
if (!(fListing === null || fListing === void 0 ? void 0 : fListing.id) || !(fProvider === null || fProvider === void 0 ? void 0 : fProvider.id) || !(student === null || student === void 0 ? void 0 : student.id))
|
|
1428
|
+
if (!fListing || !(fListing === null || fListing === void 0 ? void 0 : fListing.id) || !(fProvider === null || fProvider === void 0 ? void 0 : fProvider.id) || !(student === null || student === void 0 ? void 0 : student.id))
|
|
1271
1429
|
return;
|
|
1272
1430
|
const applicationData = {
|
|
1273
1431
|
uid: student.id,
|
|
1274
1432
|
listingId: fListing === null || fListing === void 0 ? void 0 : fListing.id,
|
|
1433
|
+
addressId: fListing.addressId,
|
|
1275
1434
|
applicantWorkflowId: fListing === null || fListing === void 0 ? void 0 : fListing.applicantWorkflowId,
|
|
1276
1435
|
providerId: fProvider.id,
|
|
1277
1436
|
stage: 1,
|
|
@@ -1288,11 +1447,10 @@ function useCreateApplicationRenderer({ user, listingId, listing, provider, appl
|
|
|
1288
1447
|
};
|
|
1289
1448
|
getUploadedFiles();
|
|
1290
1449
|
console.log("Checking IDs");
|
|
1291
|
-
|
|
1292
|
-
if (!(fListing === null || fListing === void 0 ? void 0 : fListing.id) || !(fProvider === null || fProvider === void 0 ? void 0 : fProvider.id) || !(student === null || student === void 0 ? void 0 : student.id))
|
|
1450
|
+
if (!fListing || !(fListing === null || fListing === void 0 ? void 0 : fListing.id) || !(fProvider === null || fProvider === void 0 ? void 0 : fProvider.id) || !(student === null || student === void 0 ? void 0 : student.id))
|
|
1293
1451
|
return;
|
|
1294
1452
|
if (user.product === "providers")
|
|
1295
|
-
|
|
1453
|
+
return;
|
|
1296
1454
|
console.log("Checking dates and sections");
|
|
1297
1455
|
if (!fApplication.completedSections && !fApplication.startDate && !fApplication.endDate)
|
|
1298
1456
|
return;
|
|
@@ -1361,6 +1519,8 @@ function useCreateApplicationRenderer({ user, listingId, listing, provider, appl
|
|
|
1361
1519
|
return;
|
|
1362
1520
|
if (fApplication.stage === undefined)
|
|
1363
1521
|
throw new Error("Missing applciation stage.");
|
|
1522
|
+
if (!fListing)
|
|
1523
|
+
throw new Error("No associated listing.");
|
|
1364
1524
|
const viewableFiles = (_b = (_a = fListing === null || fListing === void 0 ? void 0 : fListing.applicantWorkflow) === null || _a === void 0 ? void 0 : _a.find((stage) => stage.id === fApplication.stage)) === null || _b === void 0 ? void 0 : _b.viewableFiles;
|
|
1365
1525
|
setFApplication((a) => {
|
|
1366
1526
|
var _a, _b;
|
|
@@ -1413,14 +1573,20 @@ function useCreateApplicationRenderer({ user, listingId, listing, provider, appl
|
|
|
1413
1573
|
openSuccessPopup("draftSaved");
|
|
1414
1574
|
return;
|
|
1415
1575
|
}
|
|
1576
|
+
if (!fApplicationId)
|
|
1577
|
+
return;
|
|
1416
1578
|
// Check all items have been filled in.
|
|
1417
1579
|
if (!fApplication.startDate || !fApplication.endDate)
|
|
1418
1580
|
throw new Error("Please select dates for your placement.");
|
|
1419
1581
|
await (0, firebase_1.executeCallable)("applications-submit", { applicationId: fApplicationId });
|
|
1582
|
+
const newApplication = await firebaseQuery.getDocData(["applications", fApplicationId]);
|
|
1583
|
+
setFApplication(newApplication);
|
|
1420
1584
|
openSuccessPopup("submitted");
|
|
1421
1585
|
};
|
|
1422
1586
|
const progressStage = async (type, e) => {
|
|
1423
1587
|
// Check all stages completed.
|
|
1588
|
+
if (!fApplicationId)
|
|
1589
|
+
return;
|
|
1424
1590
|
if (!currentStageComplete)
|
|
1425
1591
|
throw new Error("Complete all forms before submitting.");
|
|
1426
1592
|
if (fApplication.reqUserType !== user.userType)
|
|
@@ -1428,6 +1594,8 @@ function useCreateApplicationRenderer({ user, listingId, listing, provider, appl
|
|
|
1428
1594
|
if (fApplication.stage === undefined)
|
|
1429
1595
|
throw new Error("Missing applciation stage.");
|
|
1430
1596
|
await (0, firebase_1.executeCallable)("applications-changeStage", { applicationId: fApplicationId, type: type, feedback: e === null || e === void 0 ? void 0 : e.feedback });
|
|
1597
|
+
const newApplication = await firebaseQuery.getDocData(["applications", fApplicationId]);
|
|
1598
|
+
setFApplication(newApplication);
|
|
1431
1599
|
};
|
|
1432
1600
|
return { successText, onFApply, progressStage, currentStageComplete, uploadedFiles, getCurrentStage, setFormComplete, viewFile, addFile, setSuccessPopup, openSuccessPopup, setFApplication, fApplication, draftSaved, profileUrl, successPopup, fApplicationId, fListing, student, fProvider };
|
|
1433
1601
|
}
|
|
@@ -1498,22 +1666,44 @@ function useProposePlacementRenderer({ user, orgContext, placement }) {
|
|
|
1498
1666
|
setFormData(undefined);
|
|
1499
1667
|
};
|
|
1500
1668
|
const proposePlacement = async (draft = false) => {
|
|
1669
|
+
const getPlacementStatus = (startDate, endDate) => {
|
|
1670
|
+
const today = new Date();
|
|
1671
|
+
if (startDate <= today && endDate >= today)
|
|
1672
|
+
return { active: !draft ? true : false, inProgress: true, completed: false };
|
|
1673
|
+
else if (endDate <= today)
|
|
1674
|
+
return { completed: true, inProgress: false, active: false };
|
|
1675
|
+
return { completed: false, inProgress: true, active: false };
|
|
1676
|
+
};
|
|
1501
1677
|
if (!formData || !student) {
|
|
1502
1678
|
throw new Error("Cannot find placement details.");
|
|
1503
1679
|
}
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
throw e;
|
|
1513
|
-
}).then((e) => {
|
|
1680
|
+
try {
|
|
1681
|
+
console.log("formData", formData);
|
|
1682
|
+
const status = getPlacementStatus(new Date(formData.startDate), new Date(formData.endDate));
|
|
1683
|
+
const newFormData = { ...formData, ...status };
|
|
1684
|
+
if (newFormData.id && newFormData.uid && draft === newFormData.draft)
|
|
1685
|
+
await firebaseQuery.update(["placements", newFormData.id], newFormData);
|
|
1686
|
+
else
|
|
1687
|
+
await (0, writeDatabase_1.addPlacement)(newFormData, student.id, draft);
|
|
1514
1688
|
setComplete(true);
|
|
1515
|
-
return
|
|
1516
|
-
}
|
|
1689
|
+
return { status };
|
|
1690
|
+
}
|
|
1691
|
+
catch (error) {
|
|
1692
|
+
console.log("Error:", error);
|
|
1693
|
+
throw error;
|
|
1694
|
+
}
|
|
1695
|
+
/*
|
|
1696
|
+
console.log("STUDENTID", student.id);
|
|
1697
|
+
|
|
1698
|
+
return await addPlacement(formData, student.id, draft).catch((e) => {
|
|
1699
|
+
console.log("error");
|
|
1700
|
+
console.log(e);
|
|
1701
|
+
throw e;
|
|
1702
|
+
}).then((e) => {
|
|
1703
|
+
setComplete(true);
|
|
1704
|
+
return e;
|
|
1705
|
+
});
|
|
1706
|
+
*/
|
|
1517
1707
|
};
|
|
1518
1708
|
const deletePlacement = async (id) => {
|
|
1519
1709
|
return await firebaseQuery.delete(["placements", id]);
|
|
@@ -1598,9 +1788,6 @@ function useUserUploadHandler({ product, oId, userType, user, onComplete, userGr
|
|
|
1598
1788
|
const [alert, setAlert] = (0, react_1.useState)();
|
|
1599
1789
|
const { execute } = (0, firebase_1.useExecuteCallableJob)({ user: user });
|
|
1600
1790
|
const requiredFields = ["forename", "surname", "email"];
|
|
1601
|
-
if (userType === "Students") {
|
|
1602
|
-
requiredFields.push("year");
|
|
1603
|
-
}
|
|
1604
1791
|
const checkData = (userData) => {
|
|
1605
1792
|
setAlert(undefined);
|
|
1606
1793
|
userData = userData.filter((u) => Object.entries(u).some(([, v]) => v));
|
|
@@ -1643,10 +1830,6 @@ function useUserUploadHandler({ product, oId, userType, user, onComplete, userGr
|
|
|
1643
1830
|
}
|
|
1644
1831
|
}
|
|
1645
1832
|
// Add more test cases
|
|
1646
|
-
if (userType === "Students" && (!user.year || !((user.year | 0) > 0 && user.year % 1 === 0))) {
|
|
1647
|
-
setAlert({ msg: "'Year' must be a number, e.g. 10.", severity: "error" });
|
|
1648
|
-
return false;
|
|
1649
|
-
}
|
|
1650
1833
|
}
|
|
1651
1834
|
if (emptyRequiredCell) {
|
|
1652
1835
|
return false;
|
|
@@ -1685,10 +1868,10 @@ function useUserUploadHandler({ product, oId, userType, user, onComplete, userGr
|
|
|
1685
1868
|
setAlert(undefined);
|
|
1686
1869
|
if (fUsers.length) {
|
|
1687
1870
|
console.log("fUsers", fUsers);
|
|
1688
|
-
execute("userManagement-addUsers", { product: product, oId: oId, users: fUsers, userType: userType, userGroupId: userGroupId, cohortId: cohortId });
|
|
1871
|
+
const jobId = await execute("userManagement-addUsers", { product: product, oId: oId, users: fUsers, userType: userType, userGroupId: userGroupId, cohortId: cohortId });
|
|
1872
|
+
onComplete && onComplete(jobId);
|
|
1689
1873
|
}
|
|
1690
1874
|
console.log("Complete", onComplete);
|
|
1691
|
-
onComplete && onComplete();
|
|
1692
1875
|
console.log("Finished");
|
|
1693
1876
|
};
|
|
1694
1877
|
const onChange = () => {
|
|
@@ -2353,6 +2536,9 @@ function useGetIndividualPlacementForPlacementPage({ user, placementId, organisa
|
|
|
2353
2536
|
const [uploadRA, setUploadRA] = (0, react_1.useState)(false);
|
|
2354
2537
|
const [uploadDBS, setUploadDBS] = (0, react_1.useState)(false);
|
|
2355
2538
|
const [onboardingPopup, setOnboardingPopup] = (0, react_1.useState)(false);
|
|
2539
|
+
const [dismissOnboardingPopup, setDismissOnboardingPopup] = (0, react_1.useState)(false);
|
|
2540
|
+
const [addOnboardingDocsPopup, setAddOnboardingDocsPopup] = (0, react_1.useState)(false);
|
|
2541
|
+
const [shareStudentRequestPopup, setShareStudentRequestPopup] = (0, react_1.useState)(false);
|
|
2356
2542
|
const [editable, setEditable] = (0, react_1.useState)(false);
|
|
2357
2543
|
const [withdrawFromPlacementPopup, setWithdrawFromPlacementPopup] = (0, react_1.useState)(false);
|
|
2358
2544
|
const firebaseQuery = new firebaseQuery_1.default();
|
|
@@ -2395,25 +2581,43 @@ function useGetIndividualPlacementForPlacementPage({ user, placementId, organisa
|
|
|
2395
2581
|
setStudent(user);
|
|
2396
2582
|
}
|
|
2397
2583
|
else {
|
|
2398
|
-
|
|
2584
|
+
if (placement.uid) {
|
|
2585
|
+
(0, readDatabase_1.getUserById)(placement.uid, undefined, false).then(setStudent);
|
|
2586
|
+
}
|
|
2587
|
+
else {
|
|
2588
|
+
setStudent({
|
|
2589
|
+
details: {
|
|
2590
|
+
forename: placement.studentForename || "",
|
|
2591
|
+
surname: placement.studentSurname || "",
|
|
2592
|
+
},
|
|
2593
|
+
email: placement.studentEmail || ""
|
|
2594
|
+
});
|
|
2595
|
+
}
|
|
2399
2596
|
}
|
|
2400
2597
|
}, [placement]);
|
|
2401
2598
|
(0, react_1.useEffect)(() => {
|
|
2402
2599
|
if (!workflow || !placement)
|
|
2403
2600
|
return;
|
|
2404
|
-
const
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
currentWorkflowStage.
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2601
|
+
const getAdditionalStageData = async () => {
|
|
2602
|
+
const currentWorkflowStage = { ...workflow.find((obj) => obj.id === placement.status) };
|
|
2603
|
+
// console.log("currentWorkflowStage", currentWorkflowStage)
|
|
2604
|
+
currentWorkflowStage.id = placement.status;
|
|
2605
|
+
// Get form data for current stage
|
|
2606
|
+
if (currentWorkflowStage.forms) {
|
|
2607
|
+
(0, readDatabase_1.getFormsFromId)(["forms"], currentWorkflowStage.forms).then((details) => {
|
|
2608
|
+
currentWorkflowStage.formDetails = details;
|
|
2609
|
+
});
|
|
2610
|
+
}
|
|
2611
|
+
if (currentWorkflowStage.files) {
|
|
2612
|
+
currentWorkflowStage.files = Object.fromEntries(await Promise.all(currentWorkflowStage.files.map(async (file) => {
|
|
2613
|
+
const fileItem = await firebaseQuery.getDocData(["files", file]);
|
|
2614
|
+
const url = await (0, storage_1.getDownloadURL)((0, storage_1.ref)(firebaseConfig_1.storage, `institutes/${placement.oId}/${fileItem.fileName}`));
|
|
2615
|
+
return [file, { name: fileItem.name, url: url }];
|
|
2616
|
+
})));
|
|
2617
|
+
}
|
|
2618
|
+
return currentWorkflowStage;
|
|
2619
|
+
};
|
|
2620
|
+
getAdditionalStageData().then(setWStage);
|
|
2417
2621
|
}, [placement, workflow]);
|
|
2418
2622
|
const editStage = async (nextStageId) => {
|
|
2419
2623
|
if (!placementId || !wStage)
|
|
@@ -2451,10 +2655,7 @@ function useGetIndividualPlacementForPlacementPage({ user, placementId, organisa
|
|
|
2451
2655
|
const onboardingStatus = (placement === null || placement === void 0 ? void 0 : placement.onboarding) ? ((_a = placement.onboarding.completed) === null || _a === void 0 ? void 0 : _a.submitted) ? placement.onboarding.completed.accepted ? "Onboarding docs approved" : "Onboarding docs completed" : (user.userType === "Staff" ? "Onboarding sent" : "Complete onboarding") : "Add onboarding documents";
|
|
2452
2656
|
const signOffPlacements = (0, util_1.getAccess)(user, "signOffPlacements");
|
|
2453
2657
|
let canEdit = false;
|
|
2454
|
-
if (((wStage === null || wStage === void 0 ? void 0 : wStage.userType) === "Staff" && user.product === "
|
|
2455
|
-
canEdit = true;
|
|
2456
|
-
}
|
|
2457
|
-
else if (((wStage === null || wStage === void 0 ? void 0 : wStage.userType) === "Staff" && user.userType === "Staff" && user.product === "institutes") || (user.product === "providers" && (wStage === null || wStage === void 0 ? void 0 : wStage.userType) === "Provider") || user.userType === "Students" && (wStage === null || wStage === void 0 ? void 0 : wStage.userType) === "Students") {
|
|
2658
|
+
if (((wStage === null || wStage === void 0 ? void 0 : wStage.userType) === "Staff" && user.userType === "Staff" && user.product === "institutes") || (user.product === "providers" && (wStage === null || wStage === void 0 ? void 0 : wStage.userType) === "Provider") || user.userType === "Students" && (wStage === null || wStage === void 0 ? void 0 : wStage.userType) === "Students") {
|
|
2458
2659
|
console.log("ALMOST CAN EDIT");
|
|
2459
2660
|
if (user.userType === "Staff" && !signOffPlacements) {
|
|
2460
2661
|
canEdit = false;
|
|
@@ -2463,12 +2664,15 @@ function useGetIndividualPlacementForPlacementPage({ user, placementId, organisa
|
|
|
2463
2664
|
canEdit = true;
|
|
2464
2665
|
}
|
|
2465
2666
|
}
|
|
2466
|
-
const onFlagClick = async (e) => {
|
|
2667
|
+
const onFlagClick = async (e, onClose) => {
|
|
2467
2668
|
if (!placement)
|
|
2468
2669
|
return;
|
|
2469
2670
|
if (e === "completeOnboarding" || e === "reviewOnboarding") {
|
|
2470
2671
|
setOnboardingPopup(true);
|
|
2471
2672
|
}
|
|
2673
|
+
if (e === "studentNotAccepted") {
|
|
2674
|
+
setShareStudentRequestPopup(true);
|
|
2675
|
+
}
|
|
2472
2676
|
if (e === "noInsurance") {
|
|
2473
2677
|
if (!eliURL) {
|
|
2474
2678
|
const storageRef = (0, storage_1.ref)(firebaseConfig_1.storage, `insurance/${placement.providerId}.pdf`);
|
|
@@ -2494,6 +2698,14 @@ function useGetIndividualPlacementForPlacementPage({ user, placementId, organisa
|
|
|
2494
2698
|
}
|
|
2495
2699
|
setExternalDocPopupOpen("dbsCheck");
|
|
2496
2700
|
}
|
|
2701
|
+
if (e === "addOnboarding") {
|
|
2702
|
+
if (onClose) {
|
|
2703
|
+
setDismissOnboardingPopup(true);
|
|
2704
|
+
}
|
|
2705
|
+
else {
|
|
2706
|
+
setAddOnboardingDocsPopup(true);
|
|
2707
|
+
}
|
|
2708
|
+
}
|
|
2497
2709
|
};
|
|
2498
2710
|
const approveELI = async () => {
|
|
2499
2711
|
if (!placement)
|
|
@@ -2553,15 +2765,17 @@ function useGetIndividualPlacementForPlacementPage({ user, placementId, organisa
|
|
|
2553
2765
|
throw new Error("Must be a student to withdraw.");
|
|
2554
2766
|
await (0, firebase_1.executeCallable)("placement-withdraw", { placementId: placementId });
|
|
2555
2767
|
};
|
|
2556
|
-
return { placement, wStage, student, workflow, editable, withdrawFromPlacementPopup, setWithdrawFromPlacementPopup, withdrawFromPlacement, onFlagClick, setUploadInsurance, setUploadProviderDocPopup, setUploadRA, setUploadDBS, onboardingStatus, setSkipStagePopup, onboardingPopup, setViewExternalLinkPopup, setOnboardingPopup, setRejectELIPopup, eliURL, riskAssessmentURL, dbsCheckURL, setExternalLinkCopied, skipStagePopup, snackbar, setSnackbar, cohort, disableEmail, rejectELIPopup, eliPopupOpen, rejectExternalDocPopup, externalDocPopupOpen, viewExternalLinkPopup, externalLinkCopied, uploadInsurance, uploadRA, uploadDBS, editStage, sendEmail, canEdit, approveELI, setEliPopupOpen, uploadProviderDocPopup, rejectELI, setRejectExternalDocPopup, setExternalDocPopupOpen, approveProviderDoc, rejectProviderDoc, manuallyConfigureProvider, institute };
|
|
2768
|
+
return { placement, wStage, student, workflow, editable, withdrawFromPlacementPopup, addOnboardingDocsPopup, setAddOnboardingDocsPopup, dismissOnboardingPopup, setDismissOnboardingPopup, setWithdrawFromPlacementPopup, withdrawFromPlacement, onFlagClick, setUploadInsurance, setUploadProviderDocPopup, setUploadRA, setUploadDBS, onboardingStatus, setSkipStagePopup, onboardingPopup, setViewExternalLinkPopup, setOnboardingPopup, setRejectELIPopup, eliURL, riskAssessmentURL, dbsCheckURL, setExternalLinkCopied, skipStagePopup, snackbar, setSnackbar, cohort, disableEmail, rejectELIPopup, eliPopupOpen, rejectExternalDocPopup, externalDocPopupOpen, viewExternalLinkPopup, externalLinkCopied, uploadInsurance, uploadRA, uploadDBS, editStage, sendEmail, canEdit, approveELI, setEliPopupOpen, uploadProviderDocPopup, rejectELI, setRejectExternalDocPopup, setExternalDocPopupOpen, approveProviderDoc, rejectProviderDoc, manuallyConfigureProvider, institute, shareStudentRequestPopup, setShareStudentRequestPopup };
|
|
2557
2769
|
}
|
|
2558
|
-
function useOnboardingPopup({ onboarding, placementId, user, onClose }) {
|
|
2770
|
+
function useOnboardingPopup({ onboarding, providerId, placementId, user, onClose }) {
|
|
2559
2771
|
const [fileUploadPopup, setFileUploadPopup] = (0, react_1.useState)(false);
|
|
2560
2772
|
const [form, setForm] = (0, react_1.useState)();
|
|
2561
2773
|
const [rejectPopup, setRejectPopup] = (0, react_1.useState)(false);
|
|
2562
2774
|
const [mOnboarding, setMOnboarding] = (0, react_1.useState)(onboarding);
|
|
2563
2775
|
const [completedSections, setCompletedSections] = (0, react_1.useState)();
|
|
2564
2776
|
const [uploadedFiles, setUploadedFiles] = (0, react_1.useState)({});
|
|
2777
|
+
const [viewableFiles, setViewableFiles] = (0, react_1.useState)();
|
|
2778
|
+
const [formDetails, setFormDetails] = (0, react_1.useState)({});
|
|
2565
2779
|
const firebaseQuery = new firebaseQuery_1.default();
|
|
2566
2780
|
const addFile = (files) => {
|
|
2567
2781
|
if (!files.length || fileUploadPopup === false)
|
|
@@ -2571,12 +2785,12 @@ function useOnboardingPopup({ onboarding, placementId, user, onClose }) {
|
|
|
2571
2785
|
};
|
|
2572
2786
|
const viewFile = (file, onOpen) => {
|
|
2573
2787
|
setMOnboarding((a) => {
|
|
2574
|
-
var _a
|
|
2788
|
+
var _a;
|
|
2575
2789
|
const oldA = { ...a };
|
|
2576
2790
|
const viewedFiles = a.completed ? ((_a = a.completed) === null || _a === void 0 ? void 0 : _a.filesViewed) || [] : [];
|
|
2577
2791
|
if (viewedFiles === null || viewedFiles === void 0 ? void 0 : viewedFiles.includes(file))
|
|
2578
2792
|
return a;
|
|
2579
|
-
(
|
|
2793
|
+
(viewableFiles === null || viewableFiles === void 0 ? void 0 : viewableFiles[file].url) && onOpen(viewableFiles === null || viewableFiles === void 0 ? void 0 : viewableFiles[file].url);
|
|
2580
2794
|
viewedFiles === null || viewedFiles === void 0 ? void 0 : viewedFiles.push(file);
|
|
2581
2795
|
const newA = (0, util_1.editNestedObject)(["completed", "filesViewed"], oldA, viewedFiles);
|
|
2582
2796
|
return newA;
|
|
@@ -2597,14 +2811,14 @@ function useOnboardingPopup({ onboarding, placementId, user, onClose }) {
|
|
|
2597
2811
|
const onboardingNew = { ...onboarding };
|
|
2598
2812
|
const onboardingFiles = onboarding.files ? Object.fromEntries(await Promise.all((_a = onboarding.files) === null || _a === void 0 ? void 0 : _a.map(async (fileId) => {
|
|
2599
2813
|
const file = await firebaseQuery.getDocData(["files", fileId]);
|
|
2600
|
-
file.url = await (0, storage_1.getDownloadURL)((0, storage_1.ref)(firebaseConfig_1.storage, `
|
|
2814
|
+
file.url = await (0, storage_1.getDownloadURL)((0, storage_1.ref)(firebaseConfig_1.storage, `providers/${providerId}/${file.fileName}`));
|
|
2601
2815
|
return [fileId, file];
|
|
2602
2816
|
}))) : [];
|
|
2603
2817
|
const onboardingForms = onboarding.forms ? Object.fromEntries(await Promise.all((_b = onboarding.forms) === null || _b === void 0 ? void 0 : _b.map(async (formId) => {
|
|
2604
2818
|
return [formId, await firebaseQuery.getDocData(["forms", formId])];
|
|
2605
2819
|
}))) : [];
|
|
2606
|
-
|
|
2607
|
-
|
|
2820
|
+
setViewableFiles(onboardingFiles);
|
|
2821
|
+
setFormDetails(onboardingForms);
|
|
2608
2822
|
return onboardingNew;
|
|
2609
2823
|
};
|
|
2610
2824
|
getOnboardingData().then(setMOnboarding);
|
|
@@ -2659,7 +2873,8 @@ function useOnboardingPopup({ onboarding, placementId, user, onClose }) {
|
|
|
2659
2873
|
return;
|
|
2660
2874
|
if (!stagesCompleted())
|
|
2661
2875
|
throw new Error("Complete all forms before submitting.");
|
|
2662
|
-
await firebaseQuery.update(["placements", placementId], { ["onboarding.completed.submitted"]: (0, util_1.convertDate)(new Date(), "dbstring") });
|
|
2876
|
+
await firebaseQuery.update(["placements", placementId], { ["onboarding.completed.accepted"]: false, ["onboarding.completed.submitted"]: true, ["onboarding.completed.submittedDate"]: (0, util_1.convertDate)(new Date(), "dbstring") });
|
|
2877
|
+
//executeCallable("sendOnboardingSubmittedEmail", {});
|
|
2663
2878
|
};
|
|
2664
2879
|
(0, react_1.useEffect)(() => {
|
|
2665
2880
|
const getUploadedFiles = async () => {
|
|
@@ -2695,6 +2910,583 @@ function useOnboardingPopup({ onboarding, placementId, user, onClose }) {
|
|
|
2695
2910
|
getUploadedFiles();
|
|
2696
2911
|
addCompletedSectionURLs();
|
|
2697
2912
|
}, [mOnboarding]);
|
|
2698
|
-
return { addFile, viewFile, uploadedFiles, setFormComplete, setRejectPopup, stagesCompleted, setForm, mOnboarding, form, submit, acceptOnboarding, rejectOnboarding, rejectPopup, completedSections, fileUploadPopup, setFileUploadPopup };
|
|
2913
|
+
return { addFile, viewFile, uploadedFiles, setFormComplete, setRejectPopup, stagesCompleted, setForm, mOnboarding, form, submit, acceptOnboarding, rejectOnboarding, rejectPopup, completedSections, fileUploadPopup, setFileUploadPopup, viewableFiles, formDetails };
|
|
2914
|
+
}
|
|
2915
|
+
function useLoadAddresses(user, limitItems, queryConstraint, request) {
|
|
2916
|
+
const [addresses, setAddresses] = (0, react_1.useState)({});
|
|
2917
|
+
const [lastDoc, setLastDoc] = (0, react_1.useState)(null);
|
|
2918
|
+
const [loading, setLoading] = (0, react_1.useState)(false);
|
|
2919
|
+
const firebaseQuery = new firebaseQuery_1.default();
|
|
2920
|
+
const [queryConstraints, setQueryConstraints] = (0, react_1.useState)(queryConstraint || []);
|
|
2921
|
+
const changeQueryConstraints = (e) => {
|
|
2922
|
+
setQueryConstraints([...(queryConstraint || []), ...e]);
|
|
2923
|
+
};
|
|
2924
|
+
const loadAddresses = () => {
|
|
2925
|
+
var _a;
|
|
2926
|
+
const constraints = [(0, firestore_1.where)("oId", "==", user.oId), (0, firestore_1.where)("product", "==", user.product), (0, firestore_1.orderBy)((0, firestore_1.documentId)())];
|
|
2927
|
+
if (limitItems) {
|
|
2928
|
+
constraints.push((0, firestore_1.limit)(limitItems));
|
|
2929
|
+
}
|
|
2930
|
+
if (user.viewAddresses === "all" || user.userGroup === "admin" || request) {
|
|
2931
|
+
if (lastDoc === null || lastDoc === void 0 ? void 0 : lastDoc.id) {
|
|
2932
|
+
constraints.push((0, firestore_1.startAfter)(lastDoc === null || lastDoc === void 0 ? void 0 : lastDoc.id));
|
|
2933
|
+
}
|
|
2934
|
+
}
|
|
2935
|
+
else if (user.viewAddresses === "request") {
|
|
2936
|
+
if (!((_a = user.visibleAddresses) === null || _a === void 0 ? void 0 : _a.length))
|
|
2937
|
+
return;
|
|
2938
|
+
constraints.push((0, firestore_1.where)((0, firestore_1.documentId)(), "in", user.visibleAddresses));
|
|
2939
|
+
if (lastDoc === null || lastDoc === void 0 ? void 0 : lastDoc.id) {
|
|
2940
|
+
constraints.push((0, firestore_1.startAfter)(lastDoc === null || lastDoc === void 0 ? void 0 : lastDoc.id));
|
|
2941
|
+
}
|
|
2942
|
+
}
|
|
2943
|
+
else {
|
|
2944
|
+
setLoading(false);
|
|
2945
|
+
return; // viewAddresses === "none", no need to load anything
|
|
2946
|
+
}
|
|
2947
|
+
queryConstraints && constraints.unshift(...queryConstraints);
|
|
2948
|
+
return firebaseQuery.collectionSnapshot((async (snapshot) => {
|
|
2949
|
+
const deletedAddresses = snapshot.docChanges().map((change) => {
|
|
2950
|
+
if (change.type === "removed") {
|
|
2951
|
+
return change.doc.id;
|
|
2952
|
+
}
|
|
2953
|
+
return;
|
|
2954
|
+
});
|
|
2955
|
+
setAddresses((prev) => Object.fromEntries(Object.entries(prev).filter(([k]) => !deletedAddresses.includes(k))));
|
|
2956
|
+
if (!snapshot.empty) {
|
|
2957
|
+
const newAddresses = snapshot.docs.map(doc => ([doc.id, { id: doc.id, ...doc.data() }]));
|
|
2958
|
+
const withListings = Object.fromEntries(await Promise.all(newAddresses.map(async ([k, address]) => {
|
|
2959
|
+
const listings = await firebaseQuery.getCount("placementListings", [(0, firestore_1.where)("providerId", "==", user.oId), (0, firestore_1.where)("addressId", "==", k)]);
|
|
2960
|
+
return [k, { ...address, listings: listings }];
|
|
2961
|
+
})));
|
|
2962
|
+
setAddresses(prev => ({ ...prev, ...withListings }));
|
|
2963
|
+
setLastDoc(snapshot.docs[snapshot.docs.length - 1]);
|
|
2964
|
+
}
|
|
2965
|
+
setLoading(false);
|
|
2966
|
+
}), "addresses", constraints, undefined, true);
|
|
2967
|
+
};
|
|
2968
|
+
(0, react_1.useEffect)(() => {
|
|
2969
|
+
const unsubscribe = loadAddresses();
|
|
2970
|
+
return () => {
|
|
2971
|
+
if (unsubscribe) {
|
|
2972
|
+
unsubscribe(); // Unsubscribe from the snapshot listener when the component unmounts
|
|
2973
|
+
}
|
|
2974
|
+
};
|
|
2975
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2976
|
+
}, [queryConstraints]);
|
|
2977
|
+
const onScrollBottom = () => {
|
|
2978
|
+
if (!limitItems)
|
|
2979
|
+
return;
|
|
2980
|
+
if (!loading) {
|
|
2981
|
+
setLoading(true);
|
|
2982
|
+
loadAddresses();
|
|
2983
|
+
}
|
|
2984
|
+
};
|
|
2985
|
+
return { addresses, onScrollBottom, loading, changeQueryConstraints };
|
|
2986
|
+
}
|
|
2987
|
+
function useLoadListings(user, queryConstraint, request) {
|
|
2988
|
+
const [listings, setListings] = (0, react_1.useState)([]);
|
|
2989
|
+
const [lastDoc, setLastDoc] = (0, react_1.useState)(null);
|
|
2990
|
+
const [loading, setLoading] = (0, react_1.useState)(false);
|
|
2991
|
+
const firebaseQuery = new firebaseQuery_1.default();
|
|
2992
|
+
const [queryConstraints, setQueryConstraints] = (0, react_1.useState)(queryConstraint || []);
|
|
2993
|
+
const changeQueryConstraints = (e) => {
|
|
2994
|
+
setQueryConstraints([...(queryConstraint || []), ...e]);
|
|
2995
|
+
};
|
|
2996
|
+
const loadListings = () => {
|
|
2997
|
+
var _a, _b;
|
|
2998
|
+
const constraints = [(0, firestore_1.where)("providerId", "==", user.oId), (0, firestore_1.limit)(10), (0, firestore_1.orderBy)((0, firestore_1.documentId)())];
|
|
2999
|
+
if (user.viewPlacementListings === "all" || user.userGroup === "admin" || request) {
|
|
3000
|
+
if (lastDoc === null || lastDoc === void 0 ? void 0 : lastDoc.id) {
|
|
3001
|
+
constraints.push((0, firestore_1.startAfter)(lastDoc));
|
|
3002
|
+
}
|
|
3003
|
+
}
|
|
3004
|
+
else {
|
|
3005
|
+
if (!((_a = user.visibleListings) === null || _a === void 0 ? void 0 : _a.length))
|
|
3006
|
+
return;
|
|
3007
|
+
constraints.push((0, firestore_1.where)((0, firestore_1.documentId)(), 'in', user.visibleListings));
|
|
3008
|
+
if (lastDoc === null || lastDoc === void 0 ? void 0 : lastDoc.id) {
|
|
3009
|
+
constraints.push((0, firestore_1.startAfter)(lastDoc));
|
|
3010
|
+
}
|
|
3011
|
+
}
|
|
3012
|
+
if (user.viewAddresses !== "all" && user.viewPlacementListings === "all" && user.userGroup !== "admin") {
|
|
3013
|
+
if (!((_b = user.visibleAddresses) === null || _b === void 0 ? void 0 : _b.length))
|
|
3014
|
+
return;
|
|
3015
|
+
constraints.push((0, firestore_1.where)('addressId', 'in', user.visibleAddresses));
|
|
3016
|
+
}
|
|
3017
|
+
queryConstraints && constraints.unshift(...queryConstraints);
|
|
3018
|
+
return firebaseQuery.collectionSnapshot((async (snapshot) => {
|
|
3019
|
+
const deletedListings = snapshot.docChanges().map((change) => {
|
|
3020
|
+
if (change.type === "removed") {
|
|
3021
|
+
return change.doc.id;
|
|
3022
|
+
}
|
|
3023
|
+
return;
|
|
3024
|
+
});
|
|
3025
|
+
setListings((prev) => prev.filter(([k]) => !deletedListings.includes(k)));
|
|
3026
|
+
if (!snapshot.empty) {
|
|
3027
|
+
const newListings = snapshot.docs.map(doc => ([doc.id, { ...doc.data(), id: doc.id }]));
|
|
3028
|
+
const listingsWithAdditionalData = await Promise.all(newListings.map(async ([id, listing]) => {
|
|
3029
|
+
const listingWithAdditionalData = { ...listing };
|
|
3030
|
+
if (listingWithAdditionalData.applicants !== undefined)
|
|
3031
|
+
return [id, listingWithAdditionalData];
|
|
3032
|
+
listingWithAdditionalData.applicants = await firebaseQuery.getCount("applications", [(0, firestore_1.where)("providerId", "==", user.oId), (0, firestore_1.where)("placementId", "==", id), (0, firestore_1.where)("status", "==", "submitted")]);
|
|
3033
|
+
listingWithAdditionalData.scheduled = await firebaseQuery.getCount("placements", [(0, firestore_1.where)("providerId", "==", user.oId), (0, firestore_1.where)("placementId", "==", id), (0, firestore_1.where)("inProgress", "==", true), (0, firestore_1.where)("startDate", ">", (0, util_1.convertDate)(new Date(), "dbstring"))]);
|
|
3034
|
+
listingWithAdditionalData.active = await firebaseQuery.getCount("placements", [(0, firestore_1.where)("providerId", "==", user.oId), (0, firestore_1.where)("placementId", "==", id), (0, firestore_1.where)("active", "==", true)]);
|
|
3035
|
+
return [id, listingWithAdditionalData];
|
|
3036
|
+
}));
|
|
3037
|
+
setListings(prev => (Object.entries({ ...Object.fromEntries(prev), ...Object.fromEntries(listingsWithAdditionalData) })));
|
|
3038
|
+
setLastDoc(snapshot.docs[snapshot.docs.length - 1]);
|
|
3039
|
+
}
|
|
3040
|
+
setLoading(false);
|
|
3041
|
+
}), "placementListings", constraints, undefined, true);
|
|
3042
|
+
};
|
|
3043
|
+
(0, react_1.useEffect)(() => {
|
|
3044
|
+
let unsubscribe;
|
|
3045
|
+
loadListings();
|
|
3046
|
+
return () => {
|
|
3047
|
+
if (unsubscribe) {
|
|
3048
|
+
unsubscribe(); // Unsubscribe from the snapshot listener when the component unmounts
|
|
3049
|
+
}
|
|
3050
|
+
};
|
|
3051
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3052
|
+
}, [queryConstraints]);
|
|
3053
|
+
const onScrollBottom = () => {
|
|
3054
|
+
if (!loading) {
|
|
3055
|
+
setLoading(true);
|
|
3056
|
+
loadListings();
|
|
3057
|
+
}
|
|
3058
|
+
};
|
|
3059
|
+
return { listings, onScrollBottom, loading, changeQueryConstraints };
|
|
3060
|
+
}
|
|
3061
|
+
function useLoadProviderPlacements(user, queryConstraint, placementId) {
|
|
3062
|
+
const [placements, setPlacements] = (0, react_1.useState)([]);
|
|
3063
|
+
const [lastDoc, setLastDoc] = (0, react_1.useState)(null);
|
|
3064
|
+
const [loading, setLoading] = (0, react_1.useState)(false);
|
|
3065
|
+
const firebaseQuery = new firebaseQuery_1.default();
|
|
3066
|
+
const [queryConstraints, setQueryConstraints] = (0, react_1.useState)(queryConstraint || []);
|
|
3067
|
+
if (user.product !== "providers")
|
|
3068
|
+
throw new Error("Only providers can use this hook.");
|
|
3069
|
+
const changeQueryConstraints = (e) => {
|
|
3070
|
+
setQueryConstraints([...(queryConstraint || []), ...e]);
|
|
3071
|
+
};
|
|
3072
|
+
const loadListings = () => {
|
|
3073
|
+
var _a, _b;
|
|
3074
|
+
const constraints = [(0, firestore_1.where)("providerId", "==", user.oId), (0, firestore_1.limit)(10), (0, firestore_1.orderBy)((0, firestore_1.documentId)())];
|
|
3075
|
+
if (placementId) {
|
|
3076
|
+
constraints.push((0, firestore_1.where)("placementId", "==", placementId));
|
|
3077
|
+
}
|
|
3078
|
+
if (user.viewPlacementListings === "all" || user.userGroup === "admin") {
|
|
3079
|
+
if (lastDoc === null || lastDoc === void 0 ? void 0 : lastDoc.id) {
|
|
3080
|
+
constraints.push((0, firestore_1.startAfter)(lastDoc));
|
|
3081
|
+
}
|
|
3082
|
+
}
|
|
3083
|
+
else {
|
|
3084
|
+
if (!((_a = user.visibleListings) === null || _a === void 0 ? void 0 : _a.length))
|
|
3085
|
+
return;
|
|
3086
|
+
constraints.push((0, firestore_1.where)("placementId", 'in', user.visibleListings));
|
|
3087
|
+
if (lastDoc === null || lastDoc === void 0 ? void 0 : lastDoc.id) {
|
|
3088
|
+
constraints.push((0, firestore_1.startAfter)(lastDoc));
|
|
3089
|
+
}
|
|
3090
|
+
}
|
|
3091
|
+
if (user.viewAddresses !== "all" && user.viewPlacementListings === "all" && user.userGroup !== "admin") {
|
|
3092
|
+
if (!((_b = user.visibleAddresses) === null || _b === void 0 ? void 0 : _b.length))
|
|
3093
|
+
return;
|
|
3094
|
+
constraints.push((0, firestore_1.where)('addressId', 'in', user.visibleAddresses));
|
|
3095
|
+
}
|
|
3096
|
+
queryConstraints && constraints.unshift(...queryConstraints);
|
|
3097
|
+
return firebaseQuery.collectionSnapshot((async (snapshot) => {
|
|
3098
|
+
const deletedListings = snapshot.docChanges().map((change) => {
|
|
3099
|
+
if (change.type === "removed") {
|
|
3100
|
+
return change.doc.id;
|
|
3101
|
+
}
|
|
3102
|
+
return;
|
|
3103
|
+
});
|
|
3104
|
+
setPlacements((prev) => prev.filter(([k]) => !deletedListings.includes(k)));
|
|
3105
|
+
if (!snapshot.empty) {
|
|
3106
|
+
const newPlacements = snapshot.docs.map(doc => ([doc.id, { ...doc.data(), id: doc.id }]));
|
|
3107
|
+
const withAdditionalData = await Promise.all(newPlacements.map(async ([id, placement]) => {
|
|
3108
|
+
const student = placement.uid ? await firebaseQuery.getDocData(["users", placement.uid || ""]).catch(() => false) :
|
|
3109
|
+
{
|
|
3110
|
+
details: {
|
|
3111
|
+
forename: placement.studentForename,
|
|
3112
|
+
surname: placement.studentSurname,
|
|
3113
|
+
},
|
|
3114
|
+
email: placement.studentEmail
|
|
3115
|
+
};
|
|
3116
|
+
const listing = await firebaseQuery.getDocData(["placementListings", placement.placementId || ""]).catch(() => false);
|
|
3117
|
+
return [id, { ...placement, student: student, listing: listing }];
|
|
3118
|
+
}));
|
|
3119
|
+
setPlacements(prev => (Object.entries({ ...Object.fromEntries(prev), ...Object.fromEntries(withAdditionalData) })));
|
|
3120
|
+
setLastDoc(snapshot.docs[snapshot.docs.length - 1]);
|
|
3121
|
+
}
|
|
3122
|
+
setLoading(false);
|
|
3123
|
+
}), "placements", constraints, undefined, true);
|
|
3124
|
+
};
|
|
3125
|
+
(0, react_1.useEffect)(() => {
|
|
3126
|
+
let unsubscribe;
|
|
3127
|
+
loadListings();
|
|
3128
|
+
return () => {
|
|
3129
|
+
if (unsubscribe) {
|
|
3130
|
+
unsubscribe(); // Unsubscribe from the snapshot listener when the component unmounts
|
|
3131
|
+
}
|
|
3132
|
+
};
|
|
3133
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3134
|
+
}, [queryConstraints]);
|
|
3135
|
+
const onScrollBottom = () => {
|
|
3136
|
+
if (!loading) {
|
|
3137
|
+
setLoading(true);
|
|
3138
|
+
loadListings();
|
|
3139
|
+
}
|
|
3140
|
+
};
|
|
3141
|
+
return { placements: Object.fromEntries(placements), onScrollBottom, loading, changeQueryConstraints };
|
|
3142
|
+
}
|
|
3143
|
+
function useLoadApplications({ user, applicationType, listingId, queryConstraint }) {
|
|
3144
|
+
const [applications, setApplications] = (0, react_1.useState)([]);
|
|
3145
|
+
const [lastDoc, setLastDoc] = (0, react_1.useState)(null);
|
|
3146
|
+
const [loading, setLoading] = (0, react_1.useState)(false);
|
|
3147
|
+
const [type, setType] = (0, react_1.useState)(applicationType || "all");
|
|
3148
|
+
const firebaseQuery = new firebaseQuery_1.default();
|
|
3149
|
+
const [queryConstraints, setQueryConstraints] = (0, react_1.useState)(queryConstraint || []);
|
|
3150
|
+
const changeQueryConstraints = (e) => {
|
|
3151
|
+
setQueryConstraints([...(queryConstraint || []), ...e]);
|
|
3152
|
+
};
|
|
3153
|
+
const loadApplications = () => {
|
|
3154
|
+
var _a, _b;
|
|
3155
|
+
const constraints = [(0, firestore_1.where)("providerId", "==", user.oId), (0, firestore_1.limit)(10), (0, firestore_1.orderBy)((0, firestore_1.documentId)())];
|
|
3156
|
+
if (lastDoc === null || lastDoc === void 0 ? void 0 : lastDoc.id) {
|
|
3157
|
+
constraints.push((0, firestore_1.startAfter)(lastDoc));
|
|
3158
|
+
}
|
|
3159
|
+
switch (type) {
|
|
3160
|
+
case "actionRequired":
|
|
3161
|
+
constraints.push((0, firestore_1.where)("status", "==", "submitted"), (0, firestore_1.where)("reqUserType", "==", "Staff"));
|
|
3162
|
+
break;
|
|
3163
|
+
case "awaitingStudent":
|
|
3164
|
+
constraints.push((0, firestore_1.where)("status", "==", "submitted"), (0, firestore_1.where)("reqUserType", "==", "Students"));
|
|
3165
|
+
break;
|
|
3166
|
+
case "closed":
|
|
3167
|
+
constraints.push((0, firestore_1.where)("status", "in", ["approved", "declined"]));
|
|
3168
|
+
break;
|
|
3169
|
+
default:
|
|
3170
|
+
constraints.push((0, firestore_1.where)("status", "==", "submitted"));
|
|
3171
|
+
}
|
|
3172
|
+
if (listingId) {
|
|
3173
|
+
constraints.push((0, firestore_1.where)("listingId", "==", listingId));
|
|
3174
|
+
}
|
|
3175
|
+
console.log("Constraints before user group check", constraints);
|
|
3176
|
+
if (user.viewAddresses !== "all" && user.userGroup !== "admin") {
|
|
3177
|
+
if (user.viewPlacementListings === "all") {
|
|
3178
|
+
if (!((_a = user.visibleAddresses) === null || _a === void 0 ? void 0 : _a.length))
|
|
3179
|
+
return;
|
|
3180
|
+
constraints.push((0, firestore_1.where)('addressId', 'in', user.visibleAddresses));
|
|
3181
|
+
}
|
|
3182
|
+
else {
|
|
3183
|
+
if (!((_b = user.visibleListings) === null || _b === void 0 ? void 0 : _b.length))
|
|
3184
|
+
return;
|
|
3185
|
+
constraints.push((0, firestore_1.where)('placementId', 'in', user.visibleListings));
|
|
3186
|
+
}
|
|
3187
|
+
}
|
|
3188
|
+
queryConstraints && constraints.unshift(...queryConstraints);
|
|
3189
|
+
console.log("Constraints after user group check", constraints);
|
|
3190
|
+
return firebaseQuery.collectionSnapshot((async (snapshot) => {
|
|
3191
|
+
const deletedApplications = snapshot.docChanges().map((change) => {
|
|
3192
|
+
if (change.type === "removed") {
|
|
3193
|
+
return change.doc.id;
|
|
3194
|
+
}
|
|
3195
|
+
return;
|
|
3196
|
+
});
|
|
3197
|
+
console.log("applicantCount", snapshot.size);
|
|
3198
|
+
setApplications((prev) => prev.filter(([k]) => !deletedApplications.includes(k)));
|
|
3199
|
+
if (!snapshot.empty) {
|
|
3200
|
+
const newApplications = snapshot.docs.map(doc => ([doc.id, { id: doc.id, ...doc.data() }])).filter(([, v]) => v.status !== "draft");
|
|
3201
|
+
setApplications(prev => ([...prev, ...newApplications]));
|
|
3202
|
+
setLastDoc(snapshot.docs[snapshot.docs.length - 1]);
|
|
3203
|
+
}
|
|
3204
|
+
else {
|
|
3205
|
+
setApplications([]);
|
|
3206
|
+
setLastDoc(null);
|
|
3207
|
+
}
|
|
3208
|
+
setLoading(false);
|
|
3209
|
+
}), "applications", constraints, undefined, true);
|
|
3210
|
+
};
|
|
3211
|
+
(0, react_1.useEffect)(() => {
|
|
3212
|
+
let unsubscribe;
|
|
3213
|
+
loadApplications();
|
|
3214
|
+
return () => {
|
|
3215
|
+
if (unsubscribe) {
|
|
3216
|
+
unsubscribe(); // Unsubscribe from the snapshot listener when the component unmounts
|
|
3217
|
+
}
|
|
3218
|
+
};
|
|
3219
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3220
|
+
}, [type, queryConstraints]);
|
|
3221
|
+
const onScrollBottom = () => {
|
|
3222
|
+
if (!loading) {
|
|
3223
|
+
setLoading(true);
|
|
3224
|
+
loadApplications();
|
|
3225
|
+
}
|
|
3226
|
+
};
|
|
3227
|
+
return { applications, type, setType, onScrollBottom, loading, changeQueryConstraints };
|
|
3228
|
+
}
|
|
3229
|
+
function useDataViewerPaginator({ view: initialView, sorts, queryLimit, additionalEntryProcessing, formatItems, snapshot, filters: initialFilters, onSearch, data }) {
|
|
3230
|
+
const [tableData, setTableData] = (0, react_1.useState)(Array.isArray(data) ? Object.fromEntries(Object.entries(data).slice(0, queryLimit)) : {});
|
|
3231
|
+
const [page, setPage] = (0, react_1.useState)([1, 0]);
|
|
3232
|
+
const [view, setView] = (0, react_1.useState)(initialView);
|
|
3233
|
+
const [filters, setFilters] = (0, react_1.useState)(initialFilters);
|
|
3234
|
+
const [queryAnchor, setQueryAnchor] = (0, react_1.useState)({ startKey: "", endKey: "", startQueryPos: 0, endQueryPos: 0 });
|
|
3235
|
+
const [prevEntryIds, setPrevEntryIds] = (0, react_1.useState)({});
|
|
3236
|
+
const [dataListenerUnsubscribe, setDataListenerUnsubscribe] = (0, react_1.useState)();
|
|
3237
|
+
const [loading, setLoading] = (0, react_1.useState)(true);
|
|
3238
|
+
const [searchString, setSearchString] = (0, react_1.useState)();
|
|
3239
|
+
const [sort, setSort] = (0, react_1.useState)();
|
|
3240
|
+
const processedData = async (k, v) => additionalEntryProcessing ? await additionalEntryProcessing(k, v) : v;
|
|
3241
|
+
const setTableDataFromDefinedData = async () => {
|
|
3242
|
+
if (!data || Array.isArray(data))
|
|
3243
|
+
return;
|
|
3244
|
+
const dataWithAdditionalProcessingPossibleNulls = (await Promise.all(Object.entries(data).map(async ([k, v]) => [k, await processedData(k, v)])));
|
|
3245
|
+
const dataWithAdditionalProcessing = dataWithAdditionalProcessingPossibleNulls.filter(([k, v]) => v);
|
|
3246
|
+
const searchedData = searchString ? dataWithAdditionalProcessing.filter(([, v]) => {
|
|
3247
|
+
const values = Object.values(v).join(", ");
|
|
3248
|
+
console.log("VALUESTRING", v);
|
|
3249
|
+
return values.includes(searchString);
|
|
3250
|
+
}) : dataWithAdditionalProcessing;
|
|
3251
|
+
const filteredData = filters && Object.keys(filters).length > 0 ? searchedData.filter(([, dataValue]) => Object.entries(filters).every(([filterKey, filterValue]) => {
|
|
3252
|
+
const value = dataValue[filterKey];
|
|
3253
|
+
if ((typeof value === "number") && value === parseInt(filterValue.value))
|
|
3254
|
+
return true;
|
|
3255
|
+
if ((typeof value === "boolean") && value === (filterValue.value === "true"))
|
|
3256
|
+
return true;
|
|
3257
|
+
if ((typeof value === "boolean") && value === (filterValue.value === "false"))
|
|
3258
|
+
return true;
|
|
3259
|
+
if ((typeof value === "string" || Array.isArray(value)) && value.includes(filterValue.value))
|
|
3260
|
+
return true;
|
|
3261
|
+
return false;
|
|
3262
|
+
})) : searchedData;
|
|
3263
|
+
if (view === "table") {
|
|
3264
|
+
if (!queryLimit)
|
|
3265
|
+
throw new Error("Tables must have a limit defined.");
|
|
3266
|
+
const newData = filteredData.slice((page[0] - 1) * queryLimit, page[0] * queryLimit);
|
|
3267
|
+
setTableData(Object.fromEntries(newData));
|
|
3268
|
+
if (Object.keys(Object.fromEntries(newData)).pop() === Object.keys(data).pop()) {
|
|
3269
|
+
setLoading("loaded");
|
|
3270
|
+
}
|
|
3271
|
+
else {
|
|
3272
|
+
setLoading(false);
|
|
3273
|
+
}
|
|
3274
|
+
return;
|
|
3275
|
+
}
|
|
3276
|
+
if (view === "list") {
|
|
3277
|
+
setTableData(Object.fromEntries(filteredData));
|
|
3278
|
+
setLoading("loaded");
|
|
3279
|
+
}
|
|
3280
|
+
};
|
|
3281
|
+
const getDataFromQuery = async (itemList = {}, currentQueryAnchor = queryAnchor, cursorDirection, prevEntries = prevEntryIds, loadMoreFromQuery = false) => {
|
|
3282
|
+
if (!filters)
|
|
3283
|
+
return;
|
|
3284
|
+
setLoading(true);
|
|
3285
|
+
if (!Array.isArray(data)) {
|
|
3286
|
+
setTableDataFromDefinedData();
|
|
3287
|
+
return;
|
|
3288
|
+
}
|
|
3289
|
+
if (!queryLimit)
|
|
3290
|
+
throw new Error("Firestore queries must have a limit defined.");
|
|
3291
|
+
if (onSearch && (searchString || sort)) {
|
|
3292
|
+
if (typeof onSearch === "boolean")
|
|
3293
|
+
throw new Error("When using Firestore queries, an onSearch function should be passed to retrieve data externally. Additional processing is however completed in this hook.");
|
|
3294
|
+
const data = await onSearch(searchString, sort, page[0], filters, queryLimit);
|
|
3295
|
+
const dataWithAdditionalProcessing = await Promise.all(Object.entries(data).map(async ([k, v]) => [k, await processedData(k, v)]));
|
|
3296
|
+
setTableData((old) => {
|
|
3297
|
+
if (view === "table") {
|
|
3298
|
+
return { ...Object.fromEntries(dataWithAdditionalProcessing) };
|
|
3299
|
+
}
|
|
3300
|
+
return { ...old, ...Object.fromEntries(dataWithAdditionalProcessing) };
|
|
3301
|
+
});
|
|
3302
|
+
if (dataWithAdditionalProcessing.length < queryLimit) {
|
|
3303
|
+
setLoading("loaded");
|
|
3304
|
+
}
|
|
3305
|
+
else {
|
|
3306
|
+
setLoading(false);
|
|
3307
|
+
}
|
|
3308
|
+
return;
|
|
3309
|
+
}
|
|
3310
|
+
let cursorPos;
|
|
3311
|
+
if (page[0] > page[1]) {
|
|
3312
|
+
cursorPos = currentQueryAnchor.endQueryPos;
|
|
3313
|
+
}
|
|
3314
|
+
else {
|
|
3315
|
+
cursorPos = currentQueryAnchor.startQueryPos;
|
|
3316
|
+
}
|
|
3317
|
+
const querySchema = data[cursorPos];
|
|
3318
|
+
const createQuery = (queryData) => {
|
|
3319
|
+
const constraints = [];
|
|
3320
|
+
queryData.where && queryData.where.forEach((w) => {
|
|
3321
|
+
constraints.push((0, firestore_1.where)(...w));
|
|
3322
|
+
});
|
|
3323
|
+
filters && Object.entries(filters).filter(([, value]) => value.value).forEach(([key, value]) => {
|
|
3324
|
+
const filterValue = (value.type === "number" || value.type === "dropdown") ? parseInt(value.value) || value.value : value.value;
|
|
3325
|
+
constraints.push((0, firestore_1.where)(key, "==", filterValue));
|
|
3326
|
+
});
|
|
3327
|
+
constraints.push((0, firestore_1.orderBy)(queryData.orderBy ? queryData.orderBy === "documentId" ? (0, firestore_1.documentId)() : queryData.orderBy : (0, firestore_1.documentId)()));
|
|
3328
|
+
if (page[0] > page[1] && !cursorDirection) { // Going up
|
|
3329
|
+
currentQueryAnchor.endKey && constraints.push((0, firestore_1.startAfter)(currentQueryAnchor.endKey));
|
|
3330
|
+
constraints.push((0, firestore_1.limit)(queryLimit));
|
|
3331
|
+
if (!loadMoreFromQuery) {
|
|
3332
|
+
currentQueryAnchor = { ...currentQueryAnchor, startQueryPos: currentQueryAnchor.endQueryPos };
|
|
3333
|
+
}
|
|
3334
|
+
}
|
|
3335
|
+
else if (page[0] < page[1] && !cursorDirection) { // Going down
|
|
3336
|
+
if (!loadMoreFromQuery) {
|
|
3337
|
+
currentQueryAnchor = { ...currentQueryAnchor, endQueryPos: currentQueryAnchor.startQueryPos };
|
|
3338
|
+
}
|
|
3339
|
+
constraints.push((0, firestore_1.limitToLast)(queryLimit));
|
|
3340
|
+
if (currentQueryAnchor.startKey) {
|
|
3341
|
+
currentQueryAnchor.startKey && constraints.push((0, firestore_1.endBefore)(currentQueryAnchor.startKey));
|
|
3342
|
+
}
|
|
3343
|
+
else {
|
|
3344
|
+
currentQueryAnchor.startKey && constraints.push((0, firestore_1.endAt)(currentQueryAnchor.startKey));
|
|
3345
|
+
}
|
|
3346
|
+
}
|
|
3347
|
+
else {
|
|
3348
|
+
if (cursorDirection === "decrease") {
|
|
3349
|
+
constraints.push((0, firestore_1.limitToLast)(queryLimit));
|
|
3350
|
+
}
|
|
3351
|
+
else {
|
|
3352
|
+
constraints.push((0, firestore_1.limit)(queryLimit));
|
|
3353
|
+
}
|
|
3354
|
+
}
|
|
3355
|
+
return constraints;
|
|
3356
|
+
};
|
|
3357
|
+
const constraints = createQuery(querySchema);
|
|
3358
|
+
const q = (0, firestore_1.query)((0, firestore_1.collection)(firebaseConfig_1.db, ...querySchema.path), ...(constraints));
|
|
3359
|
+
console.log("Fetching docs", constraints);
|
|
3360
|
+
if (snapshot) {
|
|
3361
|
+
// Use onSnapshot to get real-time updates
|
|
3362
|
+
const unsubscribe = (0, firestore_1.onSnapshot)(q, (querySnapshot) => {
|
|
3363
|
+
handleQuerySnapshot(querySnapshot);
|
|
3364
|
+
});
|
|
3365
|
+
// Save the unsubscribe function to state so we can dispose of it later
|
|
3366
|
+
setDataListenerUnsubscribe((d) => ({ ...(d || {}), [cursorPos]: unsubscribe }));
|
|
3367
|
+
return;
|
|
3368
|
+
}
|
|
3369
|
+
else {
|
|
3370
|
+
// Just get the docs without setting up a listener
|
|
3371
|
+
const queryData = await (0, firestore_1.getDocs)(q);
|
|
3372
|
+
handleQuerySnapshot(queryData);
|
|
3373
|
+
}
|
|
3374
|
+
// Function to handle query snapshot
|
|
3375
|
+
async function handleQuerySnapshot(querySnapshot) {
|
|
3376
|
+
if (!Array.isArray(data))
|
|
3377
|
+
throw new Error("Called querySnapshot but data is defined.");
|
|
3378
|
+
if (!queryLimit)
|
|
3379
|
+
throw new Error("Firestore queries must have a limit defined.");
|
|
3380
|
+
const queryResults = {};
|
|
3381
|
+
let index = 0; // Declare the index variable
|
|
3382
|
+
const reverseIfBack = (docs) => page[0] < page[1] ? docs.reverse() : docs;
|
|
3383
|
+
// Process each document in the querySnapshot
|
|
3384
|
+
for (const doc of reverseIfBack(querySnapshot.docs)) {
|
|
3385
|
+
if ((Object.keys(queryResults).length + Object.keys(itemList).length) === queryLimit) {
|
|
3386
|
+
break;
|
|
3387
|
+
}
|
|
3388
|
+
let position = Object.keys(itemList).length + (page[0] - 1) * queryLimit + index + 1;
|
|
3389
|
+
if (page[0] < page[1]) {
|
|
3390
|
+
position = (page[0]) * queryLimit - index - Object.keys(itemList).length;
|
|
3391
|
+
}
|
|
3392
|
+
if (itemList[doc.id] || (prevEntries[doc.id] && prevEntries[doc.id] !== position)) {
|
|
3393
|
+
console.log("Removing ", doc.id, ": E=", prevEntries[doc.id], ", G=", position);
|
|
3394
|
+
continue;
|
|
3395
|
+
}
|
|
3396
|
+
let item = doc.data();
|
|
3397
|
+
item.id = doc.id;
|
|
3398
|
+
// Apply additionalEntryProcessing if provided
|
|
3399
|
+
if (additionalEntryProcessing) {
|
|
3400
|
+
item = await additionalEntryProcessing(doc.id, item);
|
|
3401
|
+
}
|
|
3402
|
+
if (!item)
|
|
3403
|
+
continue;
|
|
3404
|
+
queryResults[doc.id] = item;
|
|
3405
|
+
index += 1;
|
|
3406
|
+
if (prevEntries[doc.id])
|
|
3407
|
+
continue;
|
|
3408
|
+
prevEntries[doc.id] = position;
|
|
3409
|
+
}
|
|
3410
|
+
if (cursorDirection === "decrease" || page[0] < page[1]) {
|
|
3411
|
+
itemList = { ...Object.fromEntries(Object.entries(queryResults).reverse()), ...itemList };
|
|
3412
|
+
}
|
|
3413
|
+
else {
|
|
3414
|
+
itemList = { ...itemList, ...queryResults };
|
|
3415
|
+
}
|
|
3416
|
+
// Updating state with the new data and query anchors
|
|
3417
|
+
setPrevEntryIds(prevEntries);
|
|
3418
|
+
if (querySnapshot.size < queryLimit && Object.keys(itemList).length < queryLimit) {
|
|
3419
|
+
// If we have ran out of entries, increase or decrease the index.
|
|
3420
|
+
if (page[0] > page[1] && cursorPos + 1 < data.length) {
|
|
3421
|
+
return getDataFromQuery(itemList, { ...currentQueryAnchor, endQueryPos: currentQueryAnchor.endQueryPos + 1 }, "increase", prevEntries);
|
|
3422
|
+
}
|
|
3423
|
+
else if (page[0] < page[1] && cursorPos > 0) {
|
|
3424
|
+
return getDataFromQuery(itemList, { ...currentQueryAnchor, startQueryPos: currentQueryAnchor.startQueryPos - 1 }, "decrease", prevEntries);
|
|
3425
|
+
}
|
|
3426
|
+
}
|
|
3427
|
+
if (Object.keys(itemList).length < queryLimit && querySnapshot.size === queryLimit) {
|
|
3428
|
+
console.log("Shorter than ten");
|
|
3429
|
+
return getDataFromQuery(itemList, { ...currentQueryAnchor, startKey: Object.keys(itemList)[0], endKey: Object.keys(itemList).slice(-1)[0] }, undefined, prevEntries, true);
|
|
3430
|
+
}
|
|
3431
|
+
if (querySnapshot.size === 0 &&
|
|
3432
|
+
Object.keys(itemList).length === 0 &&
|
|
3433
|
+
currentQueryAnchor.endQueryPos + 1 === data.length &&
|
|
3434
|
+
page[0] > 1) {
|
|
3435
|
+
setTableData({});
|
|
3436
|
+
setQueryAnchor((a) => ({ ...a, startKey: "" }));
|
|
3437
|
+
return;
|
|
3438
|
+
}
|
|
3439
|
+
if (querySnapshot.size < queryLimit) {
|
|
3440
|
+
setLoading("loaded");
|
|
3441
|
+
}
|
|
3442
|
+
else {
|
|
3443
|
+
setLoading(false);
|
|
3444
|
+
}
|
|
3445
|
+
setQueryAnchor({ ...currentQueryAnchor, startKey: Object.keys(itemList)[0], endKey: Object.keys(itemList).slice(-1)[0] });
|
|
3446
|
+
setTableData((old) => {
|
|
3447
|
+
if (view === "table") {
|
|
3448
|
+
return { ...itemList };
|
|
3449
|
+
}
|
|
3450
|
+
return { ...old, ...itemList };
|
|
3451
|
+
});
|
|
3452
|
+
}
|
|
3453
|
+
};
|
|
3454
|
+
const reset = () => {
|
|
3455
|
+
console.log("Resetting after filters?");
|
|
3456
|
+
setPage([1, 0]);
|
|
3457
|
+
setTableData({});
|
|
3458
|
+
setQueryAnchor({ startKey: "", endKey: "", startQueryPos: 0, endQueryPos: 0 });
|
|
3459
|
+
setPrevEntryIds({});
|
|
3460
|
+
dataListenerUnsubscribe && Object.values(dataListenerUnsubscribe).map((u) => u());
|
|
3461
|
+
setDataListenerUnsubscribe(undefined);
|
|
3462
|
+
};
|
|
3463
|
+
(0, react_1.useEffect)(() => {
|
|
3464
|
+
console.log("Filters updates", filters);
|
|
3465
|
+
if (!filters)
|
|
3466
|
+
return;
|
|
3467
|
+
console.log("Resetting cus filters");
|
|
3468
|
+
reset();
|
|
3469
|
+
}, [filters]);
|
|
3470
|
+
(0, react_1.useEffect)(() => {
|
|
3471
|
+
reset();
|
|
3472
|
+
}, [view, searchString, data, sort]);
|
|
3473
|
+
// Fetch new data when queries or page change
|
|
3474
|
+
(0, react_1.useEffect)(() => {
|
|
3475
|
+
getDataFromQuery();
|
|
3476
|
+
dataListenerUnsubscribe && Object.values(dataListenerUnsubscribe).map((u) => u());
|
|
3477
|
+
}, [page]);
|
|
3478
|
+
const pageUp = () => {
|
|
3479
|
+
setPage((p) => ([p[0] + 1, p[0]]));
|
|
3480
|
+
};
|
|
3481
|
+
const pageDown = () => {
|
|
3482
|
+
setPage((p) => ([p[0] - 1, p[0]]));
|
|
3483
|
+
};
|
|
3484
|
+
const updateSort = (sortLabel) => {
|
|
3485
|
+
if (!sorts || !sorts[sortLabel])
|
|
3486
|
+
return;
|
|
3487
|
+
setSort([sortLabel, sorts[sortLabel]]);
|
|
3488
|
+
};
|
|
3489
|
+
return ({ ...{ tableData, pageUp, pageDown, setFilters, page: page[0], sorts, loading, sort, updateSort: updateSort, setView, updateSearch: setSearchString } });
|
|
2699
3490
|
}
|
|
3491
|
+
;
|
|
2700
3492
|
//# sourceMappingURL=hooks.js.map
|