placementt-core 1.20.217 → 1.20.219

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/hooks.js CHANGED
@@ -7,6 +7,7 @@ exports.useRefDimensions = void 0;
7
7
  exports.useStudentPlacementList = useStudentPlacementList;
8
8
  exports.useOldInstitutePlacementList = useOldInstitutePlacementList;
9
9
  exports.useNewInstitutePlacementList = useNewInstitutePlacementList;
10
+ exports.useAlumniPaginator = useAlumniPaginator;
10
11
  exports.useVeryOldInstitutePlacementList = useVeryOldInstitutePlacementList;
11
12
  exports.useFilterTablePaginator = useFilterTablePaginator;
12
13
  exports.usePlacementListingPaginator = usePlacementListingPaginator;
@@ -137,7 +138,6 @@ function useOldInstitutePlacementList({ id, user, cohort, queryConstraint, ql =
137
138
  const [startPlacementAfter, setStartPlacementAfter] = (0, react_1.useState)(); // uid, pId
138
139
  const algoliaClient = (0, algoliasearch_1.default)(process.env.NODE_ENV === "development" ? "A0ZB50I7VS" : "XMPXCMUUOJ", user.algoliaKey);
139
140
  const placementsIndex = algoliaClient.initIndex("placements");
140
- const usersIndex = algoliaClient.initIndex("users");
141
141
  (0, react_1.useEffect)(() => {
142
142
  if (user.product !== "institutes" || user.userType !== "Staff") {
143
143
  setOId(undefined);
@@ -153,30 +153,6 @@ function useOldInstitutePlacementList({ id, user, cohort, queryConstraint, ql =
153
153
  }
154
154
  const searchPlacements = async () => {
155
155
  let placementsFound = {};
156
- let userSearchString = `userType:Students AND status:active AND oId:${user.oId} AND product:${user.product}`;
157
- if (cohort) {
158
- userSearchString = userSearchString + ` AND cohort:${cohort}`;
159
- }
160
- if (user.product === "institutes" && user.userType === "Staff") {
161
- const searchStudentHits = await usersIndex.search(query, {
162
- filters: userSearchString
163
- });
164
- if (searchStudentHits) {
165
- console.log("FOUND", searchStudentHits.hits.length, "students");
166
- await Promise.all(searchStudentHits.hits.map(async (hit) => {
167
- console.log("STUDENT", hit.objectID);
168
- const constraints = [...(cohort ? [(0, firestore_1.where)("cohort", "==", cohort)] : [])];
169
- if (inProgress !== undefined) {
170
- constraints.push(inProgress ? (0, firestore_1.where)("inProgress", "==", true) : (0, firestore_1.where)("completed", "==", true));
171
- }
172
- const fPlacements = await (0, readDatabase_1.getPlacementsWhere)({ w: constraints, uid: hit.objectID, oId: hit.oId });
173
- console.log("PLACEMENTS", fPlacements);
174
- Object.entries(fPlacements).forEach(([k, v]) => {
175
- placementsFound[k] = { ...v, student: hit };
176
- });
177
- }));
178
- }
179
- }
180
156
  let placementSearchString = `oId:${user.oId} AND ` + (inProgress !== undefined ? (inProgress ? "inProgress:true" : "completed:true") : "");
181
157
  if (cohort) {
182
158
  placementSearchString = placementSearchString + ` AND cohort:${cohort}`;
@@ -267,24 +243,59 @@ function useOldInstitutePlacementList({ id, user, cohort, queryConstraint, ql =
267
243
  };
268
244
  return ({ ...{ placements, loadMoreIcon, loadMorePlacements, setQuery, setInitialQueryLimit, reset, changeQueryConstraints } });
269
245
  }
270
- function useNewInstitutePlacementList({ id, user, view, cohort, queryConstraints, ql = DEFAULTQUERYLIMIT, inProgress }) {
246
+ function useNewInstitutePlacementList({ id, user, filters, view, cohort, queryConstraints, ql = DEFAULTQUERYLIMIT, inProgress }) {
271
247
  const [query, setQuery] = (0, react_1.useState)();
248
+ const sorts = {
249
+ ["Student Forename - Asc"]: {
250
+ value: "studentForename",
251
+ direction: "asc",
252
+ },
253
+ ["Student Forename - Desc"]: {
254
+ value: "studentForename",
255
+ direction: "desc",
256
+ },
257
+ ["Student Surname - Asc"]: {
258
+ value: "studentSurname",
259
+ direction: "asc",
260
+ },
261
+ ["Student Surname - Desc"]: {
262
+ value: "studentSurname",
263
+ direction: "desc",
264
+ },
265
+ ["Student Email - Asc"]: {
266
+ value: "studentEmail",
267
+ direction: "asc",
268
+ },
269
+ ["Student Email - Desc"]: {
270
+ value: "studentEmaile",
271
+ direction: "desc",
272
+ },
273
+ ["Provider email - Asc"]: {
274
+ value: "providerEmail",
275
+ direction: "asc",
276
+ },
277
+ ["Provider email - Desc"]: {
278
+ value: "providerEmail",
279
+ direction: "desc",
280
+ }
281
+ };
272
282
  const additionalProcessing = async (k, placement) => {
273
- const student = await (0, readDatabase_1.getUserById)(placement.uid).catch(() => false);
274
- if (!student)
275
- return;
276
283
  if (user.viewStudents === "some") {
277
284
  if (!(user.studentFilter && user.studentFilterValues))
278
285
  return false;
286
+ const student = await (0, readDatabase_1.getUserById)(placement.uid).catch(() => false);
287
+ if (!student)
288
+ return;
279
289
  if (!user.studentFilterValues.includes(student.details[user.studentFilter])) {
280
290
  return false;
281
291
  }
282
292
  }
283
- return { ...placement, student: student, id: k };
293
+ return { ...placement, id: k };
284
294
  };
285
- const { tableData, pageUp, pageDown, setFilters, page, loading, updateSearch } = useDataViewerPaginator({ view, queryLimit: ql, data: query, additionalEntryProcessing: additionalProcessing, onSearch: async (s) => await algoliaPlacementSearch(user, s, cohort, inProgress) });
295
+ 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) });
286
296
  (0, react_1.useEffect)(() => {
287
297
  var _a;
298
+ // Sets the query of for the DataViewerPaginator
288
299
  if (user.product !== "institutes" || user.userType !== "Staff") {
289
300
  setQuery(undefined);
290
301
  return;
@@ -302,56 +313,125 @@ function useNewInstitutePlacementList({ id, user, view, cohort, queryConstraints
302
313
  }
303
314
  setQuery(undefined);
304
315
  }, [user, queryConstraints, cohort]);
305
- return { tableData, page, loading, updateSearch, setFilters, pageUp, pageDown };
316
+ return { tableData, page, loading, updateSearch, setFilters, setView, pageUp, pageDown, sorts, updateSort, sort };
306
317
  }
307
- const algoliaPlacementSearch = async (user, query, cohort, inProgress) => {
308
- const algoliaClient = (0, algoliasearch_1.default)(process.env.NODE_ENV === "development" ? "A0ZB50I7VS" : "XMPXCMUUOJ", user.algoliaKey);
309
- const placementsIndex = algoliaClient.initIndex("placements");
310
- const usersIndex = algoliaClient.initIndex("users");
311
- let placementsFound = {};
312
- let userSearchString = `userType:Students AND status:active AND oId:${user.oId} AND product:${user.product}`;
313
- if (cohort) {
314
- userSearchString = userSearchString + ` AND cohort:${cohort}`;
315
- }
316
- if (user.product === "institutes" && user.userType === "Staff") {
317
- const searchStudentHits = await usersIndex.search(query, {
318
- filters: userSearchString
318
+ function useAlumniPaginator({ user, alumniConvoUser, filters, view, school, queryConstraints, ql = DEFAULTQUERYLIMIT }) {
319
+ const [query, setQuery] = (0, react_1.useState)();
320
+ const sorts = {};
321
+ const { tableData, pageUp, pageDown, setFilters, page, setView, loading } = useDataViewerPaginator({ view, filters, sorts, queryLimit: ql, data: query });
322
+ const firebaseQuery = new firebaseQuery_1.default();
323
+ (0, react_1.useEffect)(() => {
324
+ const createQuery = async () => {
325
+ // Sets the query of for the DataViewerPaginator
326
+ const getQueryAccess = async () => {
327
+ var _a;
328
+ const constraints = [];
329
+ if (user) {
330
+ constraints.push(["oId", "==", user.oId]);
331
+ if (user.userGroup === "admin" && user.userType === "Staff")
332
+ return constraints;
333
+ if (user.userType === "Staff") {
334
+ if (user.viewSchools === "all")
335
+ return constraints;
336
+ if (user.viewSchools === "none")
337
+ return false;
338
+ if (user.viewSchools === "some") {
339
+ if (!school)
340
+ return false;
341
+ if ((_a = user === null || user === void 0 ? void 0 : user.visibleSchools) === null || _a === void 0 ? void 0 : _a.includes(school))
342
+ return constraints;
343
+ }
344
+ return false;
345
+ }
346
+ return false;
347
+ }
348
+ if (alumniConvoUser) {
349
+ constraints.push(["oId", "==", alumniConvoUser.oId]);
350
+ console.log("ALUMNI CONVO USER");
351
+ if ((school || alumniConvoUser.schoolId) && school === alumniConvoUser.schoolId)
352
+ return constraints;
353
+ console.log("ALUMNI ACCESS TRUE");
354
+ if (alumniConvoUser.schoolId) {
355
+ const school = await firebaseQuery.getDocData(["schools", alumniConvoUser.schoolId]);
356
+ console.log("SCHOOL ACCESS", school, school.alumniConversations);
357
+ return school.alumniConversations ? constraints : false;
358
+ }
359
+ else {
360
+ const institute = await firebaseQuery.getDocData(["institutes", alumniConvoUser.oId]);
361
+ return institute.alumniConversations ? constraints : false;
362
+ }
363
+ }
364
+ return false;
365
+ };
366
+ const constraints = await getQueryAccess();
367
+ console.log("CONSTRAINTS", constraints);
368
+ if (!constraints)
369
+ return;
370
+ school && constraints.push(["schoolId", "==", school]);
371
+ queryConstraints && constraints.unshift(...queryConstraints);
372
+ return constraints;
373
+ };
374
+ console.log("Creating query");
375
+ createQuery().then((constraints) => {
376
+ setQuery([{
377
+ path: ["alumni"],
378
+ where: constraints
379
+ }]);
319
380
  });
320
- if (searchStudentHits) {
321
- console.log("FOUND", searchStudentHits.hits.length, "students");
322
- await Promise.all(searchStudentHits.hits.map(async (hit) => {
323
- console.log("STUDENT", hit.objectID);
324
- const constraints = [...(cohort ? [(0, firestore_1.where)("cohort", "==", cohort)] : [])];
325
- if (inProgress !== undefined) {
326
- constraints.push(inProgress ? (0, firestore_1.where)("inProgress", "==", true) : (0, firestore_1.where)("completed", "==", true));
327
- }
328
- const fPlacements = await (0, readDatabase_1.getPlacementsWhere)({ w: constraints, uid: hit.objectID, oId: hit.oId });
329
- console.log("PLACEMENTS", fPlacements);
330
- Object.entries(fPlacements).forEach(([k, v]) => {
331
- placementsFound[k] = { ...v, student: hit };
332
- });
333
- }));
334
- }
335
- }
381
+ }, [user, queryConstraints, school]);
382
+ (0, react_1.useEffect)(() => {
383
+ console.log("Alumni data", query, tableData);
384
+ }, [tableData]);
385
+ return { tableData, page, loading, setFilters, setView, pageUp, pageDown, sorts };
386
+ }
387
+ const algoliaPlacementSearch = async (user, query, sort, page, filters, limit, cohort, inProgress) => {
388
+ const algoliaClient = (0, algoliasearch_1.default)(process.env.NODE_ENV === "development" ? "A0ZB50I7VS" : "XMPXCMUUOJ", user.algoliaKey);
389
+ const placementsIndex = algoliaClient.initIndex(sort ? Object.values(sort[1]).join("_") : "placements");
390
+ // const usersIndex = algoliaClient.initIndex("users");
391
+ // let userSearchString = `userType:Students AND status:active AND oId:${user.oId} AND product:${user.product}`
392
+ // if (cohort) {
393
+ // userSearchString = userSearchString + ` AND cohort:${cohort}`;
394
+ // }
395
+ // if (user.product === "institutes" && user.userType === "Staff") {
396
+ // const searchStudentHits = await usersIndex.search<UserData>(query, {
397
+ // filters: userSearchString,
398
+ // hitsPerPage: limit,
399
+ // page: page
400
+ // });
401
+ // if (searchStudentHits) {
402
+ // console.log("FOUND", searchStudentHits.hits.length, "students");
403
+ // await Promise.all(searchStudentHits.hits.map(async (hit) => {
404
+ // console.log("STUDENT", hit.objectID);
405
+ // const constraints = [...(cohort ? [where("cohort", "==", cohort)] : [])]
406
+ // if (inProgress !== undefined) {
407
+ // constraints.push(inProgress ? where("inProgress", "==", true) : where("completed", "==", true));
408
+ // }
409
+ // const fPlacements = await getPlacementsWhere({w: constraints, uid: hit.objectID, oId: hit.oId}) as {[key: string]: StudentPlacementData};
410
+ // console.log("PLACEMENTS", fPlacements)
411
+ // Object.entries(fPlacements).forEach(([k, v]) => {
412
+ // placementsFound[k] = {...v, student: hit};
413
+ // })
414
+ // }))
415
+ // }
416
+ // }
336
417
  let placementSearchString = `oId:${user.oId} AND ` + (inProgress !== undefined ? (inProgress ? "inProgress:true" : "completed:true") : "");
337
418
  if (cohort) {
338
419
  placementSearchString = placementSearchString + ` AND cohort:${cohort}`;
339
420
  }
340
- const searchPlacementHits = await placementsIndex.search(query, {
341
- filters: placementSearchString
421
+ filters && Object.entries(filters).filter(([, filter]) => filter.value).map(([id, filter]) => {
422
+ placementSearchString = placementSearchString + ` AND ${id}:${filter.value}`;
342
423
  });
424
+ const options = {
425
+ filters: placementSearchString,
426
+ hitsPerPage: limit,
427
+ page: page ? page - 1 : undefined,
428
+ };
429
+ const searchPlacementHits = await placementsIndex.search(query || "", options);
430
+ console.log(searchPlacementHits.hits);
343
431
  const i = (searchPlacementHits ? (await Promise.all(searchPlacementHits.hits.map(async (hit) => {
344
- const student = hit.uid === user.id ?
345
- user : (await (0, readDatabase_1.getUserById)(hit.uid)
346
- .catch(() => false));
347
- if (!student)
348
- return;
349
- console.log("STUDENNT", hit.objectID, student);
350
- const finalData = { ...hit, student: student };
351
- return [hit.objectID, finalData];
432
+ return [hit.objectID, hit];
352
433
  }))) : []).filter((e) => e !== undefined);
353
- console.log("FOUND", i.length, "placement");
354
- return { ...Object.fromEntries(i), ...placementsFound };
434
+ return Object.fromEntries(i);
355
435
  };
356
436
  function useVeryOldInstitutePlacementList({ user, cohort, queryConstraint, ql = DEFAULTQUERYLIMIT }) {
357
437
  const [loadMoreIcon, setLoadMoreIcon] = (0, react_1.useState)(true);
@@ -842,7 +922,7 @@ function usePlacementListingPaginator({ data, user }) {
842
922
  setQueryAnchor({ ...currentQueryAnchor, startKey: Object.keys(itemList)[0], endKey: Object.keys(itemList).slice(-1)[0] });
843
923
  const finalData = Object.fromEntries(await Promise.all(Object.entries(itemList).map(async ([k, v]) => {
844
924
  const placement = await firebaseQuery.getDocData(["placementListings", v.placementId || ""]);
845
- const address = await firebaseQuery.getDocData(["addresses", placement.addressId || ""]);
925
+ const address = await firebaseQuery.getDocData(["addresses", placement.addressId || ""]).catch(() => ({ ["address-line1"]: "Unknown address" }));
846
926
  const provider = await firebaseQuery.getDocData(["providers", placement.providerId || ""]).catch(() => ({ name: "Unknown" }));
847
927
  const status = provider.name !== "Unknown" ? getPlacementStatus(provider, placement, v) : "Deleted";
848
928
  return [k, { ...address, ...provider, ...placement, email: placement.providerEmail, status: status, savedPlacement: v }];
@@ -880,10 +960,11 @@ function usePlacementListingPaginator({ data, user }) {
880
960
  }, [page]);
881
961
  return ({ ...{ tableData, setPage, setFilters, page } });
882
962
  }
883
- function useCohortUserPaginator({ user, cohort, data, search, userType }) {
963
+ function useCohortUserPaginator({ user, cohort, data, search, userType, sort }) {
884
964
  const [tableData, setTableData] = (0, react_1.useState)({});
885
- const [queryAnchor, setQueryAnchor] = (0, react_1.useState)({ startKey: "", endKey: "", startQueryPos: 0, endQueryPos: 0 });
965
+ const [queryAnchor, setQueryAnchor] = (0, react_1.useState)({ startDoc: undefined, endDoc: undefined, startQueryPos: 0, endQueryPos: 0 });
886
966
  const [filters, setFilters] = (0, react_1.useState)();
967
+ const [sortResultsBy, setSortResultsBy] = (0, react_1.useState)(sort);
887
968
  const [prevEntryIds, setPrevEntryIds] = (0, react_1.useState)({});
888
969
  const [page, setPage] = (0, react_1.useState)([1, 0]);
889
970
  const [dataListenerUnsubscribe, setDataListenerUnsubscribe] = (0, react_1.useState)();
@@ -891,6 +972,14 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
891
972
  const [prevSearch, setPrevSearch] = (0, react_1.useState)();
892
973
  const algoliaClient = (0, algoliasearch_1.default)(process.env.NODE_ENV === "development" ? "A0ZB50I7VS" : "XMPXCMUUOJ", user.algoliaKey);
893
974
  const usersIndex = algoliaClient.initIndex("users");
975
+ const sortOptions = {
976
+ ["Forename - Asc"]: ["details.forename", "asc"],
977
+ ["Forename - Desc"]: ["details.forename", "desc"],
978
+ ["Surname - Asc"]: ["details.surname", "desc"],
979
+ ["Surname - Desc"]: ["details.surname", "asc"],
980
+ ["Email - Asc"]: ["email", "asc"],
981
+ ["Email - Desc"]: ["email", "desc"],
982
+ };
894
983
  (0, react_1.useEffect)(() => {
895
984
  var _a;
896
985
  if (user.userType !== "Staff") {
@@ -899,8 +988,8 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
899
988
  return;
900
989
  }
901
990
  if ((!user.viewCohorts && user.userGroup !== "admin") ||
902
- user.viewCohorts === "none" ||
903
- (user.viewCohorts === "some" && cohort !== "all" && !((_a = user.visibleCohorts) === null || _a === void 0 ? void 0 : _a.includes(cohort || "")))) {
991
+ (user.viewCohorts === "none" && user.userGroup !== "admin") ||
992
+ (user.viewCohorts === "some" && user.userGroup !== "admin" && cohort !== "all" && !((_a = user.visibleCohorts) === null || _a === void 0 ? void 0 : _a.includes(cohort || "")))) {
904
993
  setQueries(undefined);
905
994
  return;
906
995
  }
@@ -976,10 +1065,15 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
976
1065
  });
977
1066
  console.log("Add order by", addOrderBy);
978
1067
  if (addOrderBy) {
979
- fConstraints.push((0, firestore_1.orderBy)((0, firestore_1.documentId)()));
1068
+ if (sortResultsBy) {
1069
+ fConstraints.push((0, firestore_1.orderBy)(sortOptions[sortResultsBy][0], sortOptions[sortResultsBy][1]));
1070
+ }
1071
+ else {
1072
+ fConstraints.push((0, firestore_1.orderBy)((0, firestore_1.documentId)()));
1073
+ }
980
1074
  }
981
1075
  if (page[0] > page[1] && !cursorDirection) { // Going up
982
- currentQueryAnchor.endKey && fConstraints.push((0, firestore_1.startAfter)(currentQueryAnchor.endKey));
1076
+ currentQueryAnchor.endDoc && fConstraints.push((0, firestore_1.startAfter)(currentQueryAnchor.endDoc));
983
1077
  fConstraints.push((0, firestore_1.limit)(10));
984
1078
  if (!loadMoreFromQuery) {
985
1079
  currentQueryAnchor = { ...currentQueryAnchor, startQueryPos: currentQueryAnchor.endQueryPos };
@@ -990,11 +1084,11 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
990
1084
  currentQueryAnchor = { ...currentQueryAnchor, endQueryPos: currentQueryAnchor.startQueryPos };
991
1085
  }
992
1086
  fConstraints.push((0, firestore_1.limitToLast)(10));
993
- if (currentQueryAnchor.startKey) {
994
- currentQueryAnchor.startKey && fConstraints.push((0, firestore_1.endBefore)(currentQueryAnchor.startKey));
1087
+ if (currentQueryAnchor.startDoc) {
1088
+ currentQueryAnchor.startDoc && fConstraints.push((0, firestore_1.endBefore)(currentQueryAnchor.startDoc));
995
1089
  }
996
1090
  else {
997
- currentQueryAnchor.startKey && fConstraints.push((0, firestore_1.endAt)(currentQueryAnchor.startKey));
1091
+ currentQueryAnchor.startDoc && fConstraints.push((0, firestore_1.endAt)(currentQueryAnchor.startDoc));
998
1092
  }
999
1093
  }
1000
1094
  else {
@@ -1033,9 +1127,7 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
1033
1127
  console.log("Removing ", doc.id, ": E=", prevEntries[doc.id], ", G=", position);
1034
1128
  return;
1035
1129
  }
1036
- const item = doc.data();
1037
- item.id = doc.id;
1038
- queryResults[doc.id] = item;
1130
+ queryResults[doc.id] = doc;
1039
1131
  index = index + 1;
1040
1132
  if (prevEntries[doc.id])
1041
1133
  return;
@@ -1057,7 +1149,7 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
1057
1149
  }
1058
1150
  }
1059
1151
  if (Object.keys(itemList).length < 10 && queryData.size === 10) {
1060
- return getDataFromQuery(itemList, { ...currentQueryAnchor, startKey: Object.keys(itemList)[0], endKey: Object.keys(itemList).slice(-1)[0] }, undefined, prevEntries, true);
1152
+ return getDataFromQuery(itemList, { ...currentQueryAnchor, startDoc: Object.values(itemList)[0], endDoc: Object.values(itemList).slice(-1)[0] }, undefined, prevEntries, true);
1061
1153
  }
1062
1154
  if (queryData.size === 0 &&
1063
1155
  Object.keys(itemList).length === 0 &&
@@ -1083,8 +1175,8 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
1083
1175
  setDataListenerUnsubscribe(() => itemUpdateSnapshot);
1084
1176
  };
1085
1177
  listenForUpdates();
1086
- setQueryAnchor({ ...currentQueryAnchor, startKey: Object.keys(itemList)[0], endKey: Object.keys(itemList).slice(-1)[0] });
1087
- setTableData(itemList);
1178
+ setQueryAnchor({ ...currentQueryAnchor, startDoc: Object.values(itemList)[0], endDoc: Object.values(itemList).slice(-1)[0] });
1179
+ setTableData(Object.fromEntries(Object.entries(itemList).map(([k, v]) => [k, { id: k, ...v.data() }])));
1088
1180
  };
1089
1181
  const searchUsers = async () => {
1090
1182
  if (!search)
@@ -1121,10 +1213,10 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
1121
1213
  setPage([1, 0]);
1122
1214
  console.log("Set page");
1123
1215
  setTableData({});
1124
- setQueryAnchor({ startKey: "", endKey: "", startQueryPos: 0, endQueryPos: 0 });
1216
+ setQueryAnchor({ startQueryPos: 0, endQueryPos: 0 });
1125
1217
  setPrevEntryIds({});
1126
1218
  dataListenerUnsubscribe && dataListenerUnsubscribe();
1127
- }, [filters, search]);
1219
+ }, [filters, search, sortResultsBy]);
1128
1220
  // Fetch new data when queries or page change
1129
1221
  (0, react_1.useEffect)(() => {
1130
1222
  if (search) {
@@ -1135,7 +1227,8 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
1135
1227
  getDataFromQuery();
1136
1228
  dataListenerUnsubscribe && dataListenerUnsubscribe();
1137
1229
  }, [page, queries, prevSearch]);
1138
- return ({ ...{ tableData, setPage, page, setFilters } });
1230
+ const setSort = (s) => setSortResultsBy(s);
1231
+ return ({ ...{ tableData, setPage, page, setFilters, setSort, sortOptions: Object.keys(sortOptions), sortBy: sortResultsBy } });
1139
1232
  }
1140
1233
  function useAdmissionsPaginator({ data }) {
1141
1234
  const [tableData, setTableData] = (0, react_1.useState)({});
@@ -1626,11 +1719,9 @@ function useProposePlacementRenderer({ user, orgContext, placement }) {
1626
1719
  }, [cohort]);
1627
1720
  const submitSection = (type, data) => {
1628
1721
  setFormData((f) => {
1629
- const { id, ...values } = data;
1630
1722
  return {
1631
1723
  ...f,
1632
- ...values,
1633
- id: ((placement === null || placement === void 0 ? void 0 : placement.placementId) || (formData === null || formData === void 0 ? void 0 : formData.id))
1724
+ ...data
1634
1725
  };
1635
1726
  });
1636
1727
  if ((placement === null || placement === void 0 ? void 0 : placement.placementId) && type === "dates") {
@@ -2500,7 +2591,7 @@ function useGetIndividualPlacementForPlacementPage({ user, placementId, organisa
2500
2591
  const [disableEmail, setDisableEmail] = (0, react_1.useState)({ parent: false, provider: false });
2501
2592
  const [rejectELIPopup, setRejectELIPopup] = (0, react_1.useState)(false);
2502
2593
  const [eliPopupOpen, setEliPopupOpen] = (0, react_1.useState)(false);
2503
- const [eliURL, setELIURL] = (0, react_1.useState)("");
2594
+ const [eliData, setELIData] = (0, react_1.useState)();
2504
2595
  const [rejectExternalDocPopup, setRejectExternalDocPopup] = (0, react_1.useState)(false);
2505
2596
  const [externalDocPopupOpen, setExternalDocPopupOpen] = (0, react_1.useState)(false);
2506
2597
  const [riskAssessmentURL, setRiskAssessmentURL] = (0, react_1.useState)("");
@@ -2651,10 +2742,10 @@ function useGetIndividualPlacementForPlacementPage({ user, placementId, organisa
2651
2742
  setShareStudentRequestPopup(true);
2652
2743
  }
2653
2744
  if (e === "noInsurance") {
2654
- if (!eliURL) {
2745
+ if (!eliData) {
2655
2746
  const storageRef = (0, storage_1.ref)(firebaseConfig_1.storage, `insurance/${placement.providerId}.pdf`);
2656
- const file = await (0, storage_1.getDownloadURL)(storageRef);
2657
- setELIURL(file);
2747
+ const file = await (0, storage_1.getDownloadURL)(storageRef).catch(() => placement.insuranceSkippedReason);
2748
+ setELIData(file);
2658
2749
  }
2659
2750
  setEliPopupOpen(true);
2660
2751
  }
@@ -2742,7 +2833,7 @@ function useGetIndividualPlacementForPlacementPage({ user, placementId, organisa
2742
2833
  throw new Error("Must be a student to withdraw.");
2743
2834
  await (0, firebase_1.executeCallable)("placement-withdraw", { placementId: placementId });
2744
2835
  };
2745
- 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 };
2836
+ return { placement, wStage, student, workflow, editable, withdrawFromPlacementPopup, addOnboardingDocsPopup, setAddOnboardingDocsPopup, dismissOnboardingPopup, setDismissOnboardingPopup, setWithdrawFromPlacementPopup, withdrawFromPlacement, onFlagClick, setUploadInsurance, setUploadProviderDocPopup, setUploadRA, setUploadDBS, onboardingStatus, setSkipStagePopup, onboardingPopup, setViewExternalLinkPopup, setOnboardingPopup, setRejectELIPopup, eliData, 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 };
2746
2837
  }
2747
2838
  function useOnboardingPopup({ onboarding, providerId, placementId, user, onClose }) {
2748
2839
  const [fileUploadPopup, setFileUploadPopup] = (0, react_1.useState)(false);
@@ -3203,15 +3294,17 @@ function useLoadApplications({ user, applicationType, listingId, queryConstraint
3203
3294
  };
3204
3295
  return { applications, type, setType, onScrollBottom, loading, changeQueryConstraints };
3205
3296
  }
3206
- function useDataViewerPaginator({ view, queryLimit, additionalEntryProcessing, formatItems, snapshot, filters: initialFilters, onSearch, data }) {
3297
+ function useDataViewerPaginator({ view: initialView, sorts, queryLimit = 10, additionalEntryProcessing, formatItems, snapshot, filters: initialFilters, onSearch, data }) {
3207
3298
  const [tableData, setTableData] = (0, react_1.useState)(Array.isArray(data) ? Object.fromEntries(Object.entries(data).slice(0, queryLimit)) : {});
3208
3299
  const [page, setPage] = (0, react_1.useState)([1, 0]);
3300
+ const [view, setView] = (0, react_1.useState)(initialView);
3209
3301
  const [filters, setFilters] = (0, react_1.useState)(initialFilters);
3210
3302
  const [queryAnchor, setQueryAnchor] = (0, react_1.useState)({ startKey: "", endKey: "", startQueryPos: 0, endQueryPos: 0 });
3211
3303
  const [prevEntryIds, setPrevEntryIds] = (0, react_1.useState)({});
3212
3304
  const [dataListenerUnsubscribe, setDataListenerUnsubscribe] = (0, react_1.useState)();
3213
3305
  const [loading, setLoading] = (0, react_1.useState)(true);
3214
3306
  const [searchString, setSearchString] = (0, react_1.useState)();
3307
+ const [sort, setSort] = (0, react_1.useState)();
3215
3308
  const processedData = async (k, v) => additionalEntryProcessing ? await additionalEntryProcessing(k, v) : v;
3216
3309
  const setTableDataFromDefinedData = async () => {
3217
3310
  if (!data || Array.isArray(data))
@@ -3254,22 +3347,33 @@ function useDataViewerPaginator({ view, queryLimit, additionalEntryProcessing, f
3254
3347
  }
3255
3348
  };
3256
3349
  const getDataFromQuery = async (itemList = {}, currentQueryAnchor = queryAnchor, cursorDirection, prevEntries = prevEntryIds, loadMoreFromQuery = false) => {
3257
- console.log("Fetching data");
3350
+ // if (!filters) return;
3258
3351
  setLoading(true);
3259
3352
  if (!Array.isArray(data)) {
3260
3353
  setTableDataFromDefinedData();
3261
3354
  return;
3262
3355
  }
3263
- if (onSearch && searchString) {
3356
+ if (!queryLimit)
3357
+ throw new Error("Firestore queries must have a limit defined.");
3358
+ if (onSearch && (searchString || sort)) {
3264
3359
  if (typeof onSearch === "boolean")
3265
3360
  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.");
3266
- const data = await onSearch(searchString, page[0], queryLimit);
3361
+ const data = await onSearch(searchString, sort, page[0], filters, queryLimit);
3267
3362
  const dataWithAdditionalProcessing = await Promise.all(Object.entries(data).map(async ([k, v]) => [k, await processedData(k, v)]));
3268
- setTableData(Object.fromEntries(dataWithAdditionalProcessing));
3363
+ setTableData((old) => {
3364
+ if (view === "table") {
3365
+ return { ...Object.fromEntries(dataWithAdditionalProcessing) };
3366
+ }
3367
+ return { ...old, ...Object.fromEntries(dataWithAdditionalProcessing) };
3368
+ });
3369
+ if (dataWithAdditionalProcessing.length < queryLimit) {
3370
+ setLoading("loaded");
3371
+ }
3372
+ else {
3373
+ setLoading(false);
3374
+ }
3269
3375
  return;
3270
3376
  }
3271
- if (!queryLimit)
3272
- throw new Error("Firestore queries must have a limit defined.");
3273
3377
  let cursorPos;
3274
3378
  if (page[0] > page[1]) {
3275
3379
  cursorPos = currentQueryAnchor.endQueryPos;
@@ -3278,7 +3382,6 @@ function useDataViewerPaginator({ view, queryLimit, additionalEntryProcessing, f
3278
3382
  cursorPos = currentQueryAnchor.startQueryPos;
3279
3383
  }
3280
3384
  const querySchema = data[cursorPos];
3281
- console.log("QUERY SCHEMA", querySchema);
3282
3385
  const createQuery = (queryData) => {
3283
3386
  const constraints = [];
3284
3387
  queryData.where && queryData.where.forEach((w) => {
@@ -3318,7 +3421,6 @@ function useDataViewerPaginator({ view, queryLimit, additionalEntryProcessing, f
3318
3421
  }
3319
3422
  return constraints;
3320
3423
  };
3321
- console.log("Building query");
3322
3424
  const constraints = createQuery(querySchema);
3323
3425
  const q = (0, firestore_1.query)((0, firestore_1.collection)(firebaseConfig_1.db, ...querySchema.path), ...(constraints));
3324
3426
  console.log("Fetching docs", constraints);
@@ -3378,31 +3480,30 @@ function useDataViewerPaginator({ view, queryLimit, additionalEntryProcessing, f
3378
3480
  else {
3379
3481
  itemList = { ...itemList, ...queryResults };
3380
3482
  }
3381
- console.log("ITEM LIST", itemList);
3382
3483
  // Updating state with the new data and query anchors
3383
3484
  setPrevEntryIds(prevEntries);
3384
3485
  if (querySnapshot.size < queryLimit && Object.keys(itemList).length < queryLimit) {
3385
3486
  // If we have ran out of entries, increase or decrease the index.
3386
3487
  if (page[0] > page[1] && cursorPos + 1 < data.length) {
3387
- console.log("Increase query index");
3388
3488
  return getDataFromQuery(itemList, { ...currentQueryAnchor, endQueryPos: currentQueryAnchor.endQueryPos + 1 }, "increase", prevEntries);
3389
3489
  }
3390
3490
  else if (page[0] < page[1] && cursorPos > 0) {
3391
- console.log("Decrease query index");
3392
3491
  return getDataFromQuery(itemList, { ...currentQueryAnchor, startQueryPos: currentQueryAnchor.startQueryPos - 1 }, "decrease", prevEntries);
3393
3492
  }
3394
3493
  }
3395
3494
  if (Object.keys(itemList).length < queryLimit && querySnapshot.size === queryLimit) {
3396
3495
  console.log("Shorter than ten");
3397
- // if(loadMoreFromQuery){return}
3398
3496
  return getDataFromQuery(itemList, { ...currentQueryAnchor, startKey: Object.keys(itemList)[0], endKey: Object.keys(itemList).slice(-1)[0] }, undefined, prevEntries, true);
3399
3497
  }
3400
3498
  if (querySnapshot.size === 0 &&
3401
3499
  Object.keys(itemList).length === 0 &&
3402
3500
  currentQueryAnchor.endQueryPos + 1 === data.length &&
3403
3501
  page[0] > 1) {
3404
- setTableData({});
3502
+ if (view === "table") {
3503
+ setTableData({});
3504
+ }
3405
3505
  setQueryAnchor((a) => ({ ...a, startKey: "" }));
3506
+ setLoading("loaded");
3406
3507
  return;
3407
3508
  }
3408
3509
  if (querySnapshot.size < queryLimit) {
@@ -3411,7 +3512,6 @@ function useDataViewerPaginator({ view, queryLimit, additionalEntryProcessing, f
3411
3512
  else {
3412
3513
  setLoading(false);
3413
3514
  }
3414
- console.log({ ...currentQueryAnchor, startKey: Object.keys(itemList)[0], endKey: Object.keys(itemList).slice(-1)[0] });
3415
3515
  setQueryAnchor({ ...currentQueryAnchor, startKey: Object.keys(itemList)[0], endKey: Object.keys(itemList).slice(-1)[0] });
3416
3516
  setTableData((old) => {
3417
3517
  if (view === "table") {
@@ -3422,6 +3522,7 @@ function useDataViewerPaginator({ view, queryLimit, additionalEntryProcessing, f
3422
3522
  }
3423
3523
  };
3424
3524
  const reset = () => {
3525
+ console.log("Resetting after filters?");
3425
3526
  setPage([1, 0]);
3426
3527
  setTableData({});
3427
3528
  setQueryAnchor({ startKey: "", endKey: "", startQueryPos: 0, endQueryPos: 0 });
@@ -3430,17 +3531,30 @@ function useDataViewerPaginator({ view, queryLimit, additionalEntryProcessing, f
3430
3531
  setDataListenerUnsubscribe(undefined);
3431
3532
  };
3432
3533
  (0, react_1.useEffect)(() => {
3534
+ console.log("Filters updates", filters);
3433
3535
  if (!filters)
3434
3536
  return;
3435
- console.log("Data filters", filters);
3537
+ console.log("Resetting cus filters");
3436
3538
  reset();
3437
3539
  }, [filters]);
3438
3540
  (0, react_1.useEffect)(() => {
3541
+ console.log("View reset.");
3542
+ reset();
3543
+ }, [view]);
3544
+ (0, react_1.useEffect)(() => {
3545
+ console.log("search reset.");
3546
+ reset();
3547
+ }, [searchString]);
3548
+ (0, react_1.useEffect)(() => {
3549
+ console.log("data reset.");
3439
3550
  reset();
3440
- }, [view, searchString, data]);
3551
+ }, [data]);
3552
+ (0, react_1.useEffect)(() => {
3553
+ console.log("sort reset.");
3554
+ reset();
3555
+ }, [sort]);
3441
3556
  // Fetch new data when queries or page change
3442
3557
  (0, react_1.useEffect)(() => {
3443
- console.log("SETTING TABLE DATA");
3444
3558
  getDataFromQuery();
3445
3559
  dataListenerUnsubscribe && Object.values(dataListenerUnsubscribe).map((u) => u());
3446
3560
  }, [page]);
@@ -3450,7 +3564,12 @@ function useDataViewerPaginator({ view, queryLimit, additionalEntryProcessing, f
3450
3564
  const pageDown = () => {
3451
3565
  setPage((p) => ([p[0] - 1, p[0]]));
3452
3566
  };
3453
- return ({ ...{ tableData, pageUp, pageDown, setFilters, page: page[0], loading, updateSearch: setSearchString } });
3567
+ const updateSort = (sortLabel) => {
3568
+ if (!sorts || !sorts[sortLabel])
3569
+ return;
3570
+ setSort([sortLabel, sorts[sortLabel]]);
3571
+ };
3572
+ return ({ ...{ tableData, pageUp, pageDown, setFilters, page: page[0], sorts, loading, sort, updateSort: updateSort, setView, updateSearch: setSearchString } });
3454
3573
  }
3455
3574
  ;
3456
3575
  //# sourceMappingURL=hooks.js.map