placementt-core 1.20.217 → 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.
Files changed (86) hide show
  1. package/.eslintrc.js +40 -40
  2. package/.gitattributes +2 -2
  3. package/lib/constants.js +10 -1
  4. package/lib/constants.js.map +1 -1
  5. package/lib/features/config.d.ts +133 -133
  6. package/lib/features/config.js +35 -35
  7. package/lib/features/contacts/contacts.d.ts +75 -75
  8. package/lib/features/contacts/contacts.js +105 -105
  9. package/lib/features/downtime/useDowntime.d.ts +11 -11
  10. package/lib/features/downtime/useDowntime.js +22 -22
  11. package/lib/features/placements/studentPlacements/studentPlacementsSlice.d.ts +63 -63
  12. package/lib/features/placements/studentPlacements/studentPlacementsSlice.js +81 -81
  13. package/lib/features/providerPlacements/providerPlacementsSlice.d.ts +19 -19
  14. package/lib/features/providerPlacements/providerPlacementsSlice.js +24 -24
  15. package/lib/features/studentPlacements/studentPlacementsSlice.d.ts +62 -62
  16. package/lib/features/studentPlacements/studentPlacementsSlice.js +87 -87
  17. package/lib/features/studentPlacements/useStudentPlacements.d.ts +6 -6
  18. package/lib/features/studentPlacements/useStudentPlacements.js +18 -18
  19. package/lib/features/userSlice.d.ts +26 -26
  20. package/lib/features/userSlice.js +23 -23
  21. package/lib/features/users/useUserFunctions.d.ts +25 -25
  22. package/lib/features/users/useUserFunctions.js +124 -124
  23. package/lib/features/users/userSlice.d.ts +46 -46
  24. package/lib/features/users/userSlice.js +48 -48
  25. package/lib/firebase/firebase.d.ts +1 -1
  26. package/lib/firebase/firebase.js +6 -2
  27. package/lib/firebase/firebase.js.map +1 -1
  28. package/lib/firebase/readDatabase.js +3 -1
  29. package/lib/firebase/readDatabase.js.map +1 -1
  30. package/lib/hooks.d.ts +33 -5
  31. package/lib/hooks.js +143 -107
  32. package/lib/hooks.js.map +1 -1
  33. package/lib/images/GatsbyBenchmarks.d.ts +1 -2
  34. package/lib/reduxHooks.d.ts +1 -66
  35. package/lib/reduxHooks.js +9 -69
  36. package/lib/reduxHooks.js.map +1 -1
  37. package/lib/tasksAndTips.d.ts +2 -2
  38. package/lib/tasksAndTips.js +37 -6
  39. package/lib/tasksAndTips.js.map +1 -1
  40. package/lib/typeDefinitions.d.ts +50 -5
  41. package/lib/util.d.ts +1 -1
  42. package/lib/util.js +12 -1
  43. package/lib/util.js.map +1 -1
  44. package/package.json +52 -56
  45. package/src/DatabaseDefinitions.ts +18 -18
  46. package/src/apiCalls.ts +128 -128
  47. package/src/config.ts +50 -50
  48. package/src/constants.ts +796 -787
  49. package/src/databaseTypes.ts +42 -42
  50. package/src/features/analytics/useAnalytics.tsx +63 -63
  51. package/src/features/contacts/contactsSlice.ts +147 -147
  52. package/src/features/contacts/useContacts.tsx +73 -73
  53. package/src/features/dropdown/useDropdown.tsx +52 -52
  54. package/src/features/global/downtime/useDowntime.tsx +23 -23
  55. package/src/features/global/users/useUserFunctions.tsx +132 -132
  56. package/src/features/jobs/jobsSlice.ts +71 -71
  57. package/src/features/placements/studentPlacements/activePlacement.ts +68 -68
  58. package/src/features/placements/studentPlacements/completedStudentPlacementsSlice.ts +97 -97
  59. package/src/features/placements/studentPlacements/upcomingStudentPlacementsSlice.ts +108 -108
  60. package/src/features/placements/studentPlacements/useStudentPlacements.tsx +9 -9
  61. package/src/features/placements/types.ts +10 -10
  62. package/src/features/referrals/useReferrals.tsx +56 -56
  63. package/src/features/updates/useUpdates.tsx +38 -38
  64. package/src/firebase/firebase.tsx +149 -145
  65. package/src/firebase/firebaseConfig.tsx +45 -45
  66. package/src/firebase/firebaseQuery.tsx +151 -151
  67. package/src/firebase/persistence.ts +84 -84
  68. package/src/firebase/readDatabase.tsx +236 -235
  69. package/src/firebase/util.tsx +352 -352
  70. package/src/firebase/writeDatabase.tsx +77 -77
  71. package/src/hooks.tsx +4353 -4323
  72. package/src/images/GatsbyBenchmarks.tsx +711 -711
  73. package/src/images/LogFuturePlacement.jsx +64 -64
  74. package/src/images/LogPreviousPlacement.jsx +228 -228
  75. package/src/images/gatsby_benchmarks.svg +466 -466
  76. package/src/images/log_future_placement.svg +114 -114
  77. package/src/images/log_previous_placement.svg +199 -199
  78. package/src/index.ts +34 -34
  79. package/src/readDatabase.tsx +3 -3
  80. package/src/reduxHooks.ts +232 -297
  81. package/src/tasksAndTips.ts +1209 -1177
  82. package/src/tutorialTips.ts +58 -58
  83. package/src/typeDefinitions.ts +1003 -958
  84. package/src/util.ts +160 -150
  85. package/tsconfig.dev.json +5 -5
  86. package/tsconfig.json +21 -22
package/lib/hooks.js CHANGED
@@ -137,7 +137,6 @@ function useOldInstitutePlacementList({ id, user, cohort, queryConstraint, ql =
137
137
  const [startPlacementAfter, setStartPlacementAfter] = (0, react_1.useState)(); // uid, pId
138
138
  const algoliaClient = (0, algoliasearch_1.default)(process.env.NODE_ENV === "development" ? "A0ZB50I7VS" : "XMPXCMUUOJ", user.algoliaKey);
139
139
  const placementsIndex = algoliaClient.initIndex("placements");
140
- const usersIndex = algoliaClient.initIndex("users");
141
140
  (0, react_1.useEffect)(() => {
142
141
  if (user.product !== "institutes" || user.userType !== "Staff") {
143
142
  setOId(undefined);
@@ -153,30 +152,6 @@ function useOldInstitutePlacementList({ id, user, cohort, queryConstraint, ql =
153
152
  }
154
153
  const searchPlacements = async () => {
155
154
  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
155
  let placementSearchString = `oId:${user.oId} AND ` + (inProgress !== undefined ? (inProgress ? "inProgress:true" : "completed:true") : "");
181
156
  if (cohort) {
182
157
  placementSearchString = placementSearchString + ` AND cohort:${cohort}`;
@@ -267,24 +242,59 @@ function useOldInstitutePlacementList({ id, user, cohort, queryConstraint, ql =
267
242
  };
268
243
  return ({ ...{ placements, loadMoreIcon, loadMorePlacements, setQuery, setInitialQueryLimit, reset, changeQueryConstraints } });
269
244
  }
270
- function useNewInstitutePlacementList({ id, user, view, cohort, queryConstraints, ql = DEFAULTQUERYLIMIT, inProgress }) {
245
+ function useNewInstitutePlacementList({ id, user, filters, view, cohort, queryConstraints, ql = DEFAULTQUERYLIMIT, inProgress }) {
271
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
+ };
272
281
  const additionalProcessing = async (k, placement) => {
273
- const student = await (0, readDatabase_1.getUserById)(placement.uid).catch(() => false);
274
- if (!student)
275
- return;
276
282
  if (user.viewStudents === "some") {
277
283
  if (!(user.studentFilter && user.studentFilterValues))
278
284
  return false;
285
+ const student = await (0, readDatabase_1.getUserById)(placement.uid).catch(() => false);
286
+ if (!student)
287
+ return;
279
288
  if (!user.studentFilterValues.includes(student.details[user.studentFilter])) {
280
289
  return false;
281
290
  }
282
291
  }
283
- return { ...placement, student: student, id: k };
292
+ return { ...placement, id: k };
284
293
  };
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) });
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) });
286
295
  (0, react_1.useEffect)(() => {
287
296
  var _a;
297
+ // Sets the query of for the DataViewerPaginator
288
298
  if (user.product !== "institutes" || user.userType !== "Staff") {
289
299
  setQuery(undefined);
290
300
  return;
@@ -302,56 +312,56 @@ function useNewInstitutePlacementList({ id, user, view, cohort, queryConstraints
302
312
  }
303
313
  setQuery(undefined);
304
314
  }, [user, queryConstraints, cohort]);
305
- return { tableData, page, loading, updateSearch, setFilters, pageUp, pageDown };
315
+ return { tableData, page, loading, updateSearch, setFilters, setView, pageUp, pageDown, sorts, updateSort, sort };
306
316
  }
307
- const algoliaPlacementSearch = async (user, query, cohort, inProgress) => {
317
+ const algoliaPlacementSearch = async (user, query, sort, page, filters, limit, cohort, inProgress) => {
308
318
  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
319
- });
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
- }
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
+ // }
336
347
  let placementSearchString = `oId:${user.oId} AND ` + (inProgress !== undefined ? (inProgress ? "inProgress:true" : "completed:true") : "");
337
348
  if (cohort) {
338
349
  placementSearchString = placementSearchString + ` AND cohort:${cohort}`;
339
350
  }
340
- const searchPlacementHits = await placementsIndex.search(query, {
341
- filters: placementSearchString
351
+ filters && Object.entries(filters).filter(([, filter]) => filter.value).map(([id, filter]) => {
352
+ placementSearchString = placementSearchString + ` AND ${id}:${filter.value}`;
342
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);
343
361
  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];
362
+ return [hit.objectID, hit];
352
363
  }))) : []).filter((e) => e !== undefined);
353
- console.log("FOUND", i.length, "placement");
354
- return { ...Object.fromEntries(i), ...placementsFound };
364
+ return Object.fromEntries(i);
355
365
  };
356
366
  function useVeryOldInstitutePlacementList({ user, cohort, queryConstraint, ql = DEFAULTQUERYLIMIT }) {
357
367
  const [loadMoreIcon, setLoadMoreIcon] = (0, react_1.useState)(true);
@@ -842,7 +852,7 @@ function usePlacementListingPaginator({ data, user }) {
842
852
  setQueryAnchor({ ...currentQueryAnchor, startKey: Object.keys(itemList)[0], endKey: Object.keys(itemList).slice(-1)[0] });
843
853
  const finalData = Object.fromEntries(await Promise.all(Object.entries(itemList).map(async ([k, v]) => {
844
854
  const placement = await firebaseQuery.getDocData(["placementListings", v.placementId || ""]);
845
- const address = await firebaseQuery.getDocData(["addresses", placement.addressId || ""]);
855
+ const address = await firebaseQuery.getDocData(["addresses", placement.addressId || ""]).catch(() => ({ ["address-line1"]: "Unknown address" }));
846
856
  const provider = await firebaseQuery.getDocData(["providers", placement.providerId || ""]).catch(() => ({ name: "Unknown" }));
847
857
  const status = provider.name !== "Unknown" ? getPlacementStatus(provider, placement, v) : "Deleted";
848
858
  return [k, { ...address, ...provider, ...placement, email: placement.providerEmail, status: status, savedPlacement: v }];
@@ -880,10 +890,11 @@ function usePlacementListingPaginator({ data, user }) {
880
890
  }, [page]);
881
891
  return ({ ...{ tableData, setPage, setFilters, page } });
882
892
  }
883
- function useCohortUserPaginator({ user, cohort, data, search, userType }) {
893
+ function useCohortUserPaginator({ user, cohort, data, search, userType, sort }) {
884
894
  const [tableData, setTableData] = (0, react_1.useState)({});
885
- const [queryAnchor, setQueryAnchor] = (0, react_1.useState)({ startKey: "", endKey: "", startQueryPos: 0, endQueryPos: 0 });
895
+ const [queryAnchor, setQueryAnchor] = (0, react_1.useState)({ startDoc: undefined, endDoc: undefined, startQueryPos: 0, endQueryPos: 0 });
886
896
  const [filters, setFilters] = (0, react_1.useState)();
897
+ const [sortResultsBy, setSortResultsBy] = (0, react_1.useState)(sort);
887
898
  const [prevEntryIds, setPrevEntryIds] = (0, react_1.useState)({});
888
899
  const [page, setPage] = (0, react_1.useState)([1, 0]);
889
900
  const [dataListenerUnsubscribe, setDataListenerUnsubscribe] = (0, react_1.useState)();
@@ -891,6 +902,14 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
891
902
  const [prevSearch, setPrevSearch] = (0, react_1.useState)();
892
903
  const algoliaClient = (0, algoliasearch_1.default)(process.env.NODE_ENV === "development" ? "A0ZB50I7VS" : "XMPXCMUUOJ", user.algoliaKey);
893
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
+ };
894
913
  (0, react_1.useEffect)(() => {
895
914
  var _a;
896
915
  if (user.userType !== "Staff") {
@@ -976,10 +995,15 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
976
995
  });
977
996
  console.log("Add order by", addOrderBy);
978
997
  if (addOrderBy) {
979
- fConstraints.push((0, firestore_1.orderBy)((0, firestore_1.documentId)()));
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
+ }
980
1004
  }
981
1005
  if (page[0] > page[1] && !cursorDirection) { // Going up
982
- currentQueryAnchor.endKey && fConstraints.push((0, firestore_1.startAfter)(currentQueryAnchor.endKey));
1006
+ currentQueryAnchor.endDoc && fConstraints.push((0, firestore_1.startAfter)(currentQueryAnchor.endDoc));
983
1007
  fConstraints.push((0, firestore_1.limit)(10));
984
1008
  if (!loadMoreFromQuery) {
985
1009
  currentQueryAnchor = { ...currentQueryAnchor, startQueryPos: currentQueryAnchor.endQueryPos };
@@ -990,11 +1014,11 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
990
1014
  currentQueryAnchor = { ...currentQueryAnchor, endQueryPos: currentQueryAnchor.startQueryPos };
991
1015
  }
992
1016
  fConstraints.push((0, firestore_1.limitToLast)(10));
993
- if (currentQueryAnchor.startKey) {
994
- currentQueryAnchor.startKey && fConstraints.push((0, firestore_1.endBefore)(currentQueryAnchor.startKey));
1017
+ if (currentQueryAnchor.startDoc) {
1018
+ currentQueryAnchor.startDoc && fConstraints.push((0, firestore_1.endBefore)(currentQueryAnchor.startDoc));
995
1019
  }
996
1020
  else {
997
- currentQueryAnchor.startKey && fConstraints.push((0, firestore_1.endAt)(currentQueryAnchor.startKey));
1021
+ currentQueryAnchor.startDoc && fConstraints.push((0, firestore_1.endAt)(currentQueryAnchor.startDoc));
998
1022
  }
999
1023
  }
1000
1024
  else {
@@ -1033,9 +1057,7 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
1033
1057
  console.log("Removing ", doc.id, ": E=", prevEntries[doc.id], ", G=", position);
1034
1058
  return;
1035
1059
  }
1036
- const item = doc.data();
1037
- item.id = doc.id;
1038
- queryResults[doc.id] = item;
1060
+ queryResults[doc.id] = doc;
1039
1061
  index = index + 1;
1040
1062
  if (prevEntries[doc.id])
1041
1063
  return;
@@ -1057,7 +1079,7 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
1057
1079
  }
1058
1080
  }
1059
1081
  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);
1082
+ return getDataFromQuery(itemList, { ...currentQueryAnchor, startDoc: Object.values(itemList)[0], endDoc: Object.values(itemList).slice(-1)[0] }, undefined, prevEntries, true);
1061
1083
  }
1062
1084
  if (queryData.size === 0 &&
1063
1085
  Object.keys(itemList).length === 0 &&
@@ -1083,8 +1105,8 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
1083
1105
  setDataListenerUnsubscribe(() => itemUpdateSnapshot);
1084
1106
  };
1085
1107
  listenForUpdates();
1086
- setQueryAnchor({ ...currentQueryAnchor, startKey: Object.keys(itemList)[0], endKey: Object.keys(itemList).slice(-1)[0] });
1087
- 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() }])));
1088
1110
  };
1089
1111
  const searchUsers = async () => {
1090
1112
  if (!search)
@@ -1121,10 +1143,10 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
1121
1143
  setPage([1, 0]);
1122
1144
  console.log("Set page");
1123
1145
  setTableData({});
1124
- setQueryAnchor({ startKey: "", endKey: "", startQueryPos: 0, endQueryPos: 0 });
1146
+ setQueryAnchor({ startQueryPos: 0, endQueryPos: 0 });
1125
1147
  setPrevEntryIds({});
1126
1148
  dataListenerUnsubscribe && dataListenerUnsubscribe();
1127
- }, [filters, search]);
1149
+ }, [filters, search, sortResultsBy]);
1128
1150
  // Fetch new data when queries or page change
1129
1151
  (0, react_1.useEffect)(() => {
1130
1152
  if (search) {
@@ -1135,7 +1157,8 @@ function useCohortUserPaginator({ user, cohort, data, search, userType }) {
1135
1157
  getDataFromQuery();
1136
1158
  dataListenerUnsubscribe && dataListenerUnsubscribe();
1137
1159
  }, [page, queries, prevSearch]);
1138
- return ({ ...{ tableData, setPage, page, setFilters } });
1160
+ const setSort = (s) => setSortResultsBy(s);
1161
+ return ({ ...{ tableData, setPage, page, setFilters, setSort, sortOptions: Object.keys(sortOptions), sortBy: sortResultsBy } });
1139
1162
  }
1140
1163
  function useAdmissionsPaginator({ data }) {
1141
1164
  const [tableData, setTableData] = (0, react_1.useState)({});
@@ -3203,15 +3226,17 @@ function useLoadApplications({ user, applicationType, listingId, queryConstraint
3203
3226
  };
3204
3227
  return { applications, type, setType, onScrollBottom, loading, changeQueryConstraints };
3205
3228
  }
3206
- function useDataViewerPaginator({ view, queryLimit, additionalEntryProcessing, formatItems, snapshot, filters: initialFilters, onSearch, data }) {
3229
+ function useDataViewerPaginator({ view: initialView, sorts, queryLimit, additionalEntryProcessing, formatItems, snapshot, filters: initialFilters, onSearch, data }) {
3207
3230
  const [tableData, setTableData] = (0, react_1.useState)(Array.isArray(data) ? Object.fromEntries(Object.entries(data).slice(0, queryLimit)) : {});
3208
3231
  const [page, setPage] = (0, react_1.useState)([1, 0]);
3232
+ const [view, setView] = (0, react_1.useState)(initialView);
3209
3233
  const [filters, setFilters] = (0, react_1.useState)(initialFilters);
3210
3234
  const [queryAnchor, setQueryAnchor] = (0, react_1.useState)({ startKey: "", endKey: "", startQueryPos: 0, endQueryPos: 0 });
3211
3235
  const [prevEntryIds, setPrevEntryIds] = (0, react_1.useState)({});
3212
3236
  const [dataListenerUnsubscribe, setDataListenerUnsubscribe] = (0, react_1.useState)();
3213
3237
  const [loading, setLoading] = (0, react_1.useState)(true);
3214
3238
  const [searchString, setSearchString] = (0, react_1.useState)();
3239
+ const [sort, setSort] = (0, react_1.useState)();
3215
3240
  const processedData = async (k, v) => additionalEntryProcessing ? await additionalEntryProcessing(k, v) : v;
3216
3241
  const setTableDataFromDefinedData = async () => {
3217
3242
  if (!data || Array.isArray(data))
@@ -3254,22 +3279,34 @@ function useDataViewerPaginator({ view, queryLimit, additionalEntryProcessing, f
3254
3279
  }
3255
3280
  };
3256
3281
  const getDataFromQuery = async (itemList = {}, currentQueryAnchor = queryAnchor, cursorDirection, prevEntries = prevEntryIds, loadMoreFromQuery = false) => {
3257
- console.log("Fetching data");
3282
+ if (!filters)
3283
+ return;
3258
3284
  setLoading(true);
3259
3285
  if (!Array.isArray(data)) {
3260
3286
  setTableDataFromDefinedData();
3261
3287
  return;
3262
3288
  }
3263
- if (onSearch && searchString) {
3289
+ if (!queryLimit)
3290
+ throw new Error("Firestore queries must have a limit defined.");
3291
+ if (onSearch && (searchString || sort)) {
3264
3292
  if (typeof onSearch === "boolean")
3265
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.");
3266
- const data = await onSearch(searchString, page[0], queryLimit);
3294
+ const data = await onSearch(searchString, sort, page[0], filters, queryLimit);
3267
3295
  const dataWithAdditionalProcessing = await Promise.all(Object.entries(data).map(async ([k, v]) => [k, await processedData(k, v)]));
3268
- setTableData(Object.fromEntries(dataWithAdditionalProcessing));
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
+ }
3269
3308
  return;
3270
3309
  }
3271
- if (!queryLimit)
3272
- throw new Error("Firestore queries must have a limit defined.");
3273
3310
  let cursorPos;
3274
3311
  if (page[0] > page[1]) {
3275
3312
  cursorPos = currentQueryAnchor.endQueryPos;
@@ -3278,7 +3315,6 @@ function useDataViewerPaginator({ view, queryLimit, additionalEntryProcessing, f
3278
3315
  cursorPos = currentQueryAnchor.startQueryPos;
3279
3316
  }
3280
3317
  const querySchema = data[cursorPos];
3281
- console.log("QUERY SCHEMA", querySchema);
3282
3318
  const createQuery = (queryData) => {
3283
3319
  const constraints = [];
3284
3320
  queryData.where && queryData.where.forEach((w) => {
@@ -3318,7 +3354,6 @@ function useDataViewerPaginator({ view, queryLimit, additionalEntryProcessing, f
3318
3354
  }
3319
3355
  return constraints;
3320
3356
  };
3321
- console.log("Building query");
3322
3357
  const constraints = createQuery(querySchema);
3323
3358
  const q = (0, firestore_1.query)((0, firestore_1.collection)(firebaseConfig_1.db, ...querySchema.path), ...(constraints));
3324
3359
  console.log("Fetching docs", constraints);
@@ -3378,23 +3413,19 @@ function useDataViewerPaginator({ view, queryLimit, additionalEntryProcessing, f
3378
3413
  else {
3379
3414
  itemList = { ...itemList, ...queryResults };
3380
3415
  }
3381
- console.log("ITEM LIST", itemList);
3382
3416
  // Updating state with the new data and query anchors
3383
3417
  setPrevEntryIds(prevEntries);
3384
3418
  if (querySnapshot.size < queryLimit && Object.keys(itemList).length < queryLimit) {
3385
3419
  // If we have ran out of entries, increase or decrease the index.
3386
3420
  if (page[0] > page[1] && cursorPos + 1 < data.length) {
3387
- console.log("Increase query index");
3388
3421
  return getDataFromQuery(itemList, { ...currentQueryAnchor, endQueryPos: currentQueryAnchor.endQueryPos + 1 }, "increase", prevEntries);
3389
3422
  }
3390
3423
  else if (page[0] < page[1] && cursorPos > 0) {
3391
- console.log("Decrease query index");
3392
3424
  return getDataFromQuery(itemList, { ...currentQueryAnchor, startQueryPos: currentQueryAnchor.startQueryPos - 1 }, "decrease", prevEntries);
3393
3425
  }
3394
3426
  }
3395
3427
  if (Object.keys(itemList).length < queryLimit && querySnapshot.size === queryLimit) {
3396
3428
  console.log("Shorter than ten");
3397
- // if(loadMoreFromQuery){return}
3398
3429
  return getDataFromQuery(itemList, { ...currentQueryAnchor, startKey: Object.keys(itemList)[0], endKey: Object.keys(itemList).slice(-1)[0] }, undefined, prevEntries, true);
3399
3430
  }
3400
3431
  if (querySnapshot.size === 0 &&
@@ -3411,7 +3442,6 @@ function useDataViewerPaginator({ view, queryLimit, additionalEntryProcessing, f
3411
3442
  else {
3412
3443
  setLoading(false);
3413
3444
  }
3414
- console.log({ ...currentQueryAnchor, startKey: Object.keys(itemList)[0], endKey: Object.keys(itemList).slice(-1)[0] });
3415
3445
  setQueryAnchor({ ...currentQueryAnchor, startKey: Object.keys(itemList)[0], endKey: Object.keys(itemList).slice(-1)[0] });
3416
3446
  setTableData((old) => {
3417
3447
  if (view === "table") {
@@ -3422,6 +3452,7 @@ function useDataViewerPaginator({ view, queryLimit, additionalEntryProcessing, f
3422
3452
  }
3423
3453
  };
3424
3454
  const reset = () => {
3455
+ console.log("Resetting after filters?");
3425
3456
  setPage([1, 0]);
3426
3457
  setTableData({});
3427
3458
  setQueryAnchor({ startKey: "", endKey: "", startQueryPos: 0, endQueryPos: 0 });
@@ -3430,17 +3461,17 @@ function useDataViewerPaginator({ view, queryLimit, additionalEntryProcessing, f
3430
3461
  setDataListenerUnsubscribe(undefined);
3431
3462
  };
3432
3463
  (0, react_1.useEffect)(() => {
3464
+ console.log("Filters updates", filters);
3433
3465
  if (!filters)
3434
3466
  return;
3435
- console.log("Data filters", filters);
3467
+ console.log("Resetting cus filters");
3436
3468
  reset();
3437
3469
  }, [filters]);
3438
3470
  (0, react_1.useEffect)(() => {
3439
3471
  reset();
3440
- }, [view, searchString, data]);
3472
+ }, [view, searchString, data, sort]);
3441
3473
  // Fetch new data when queries or page change
3442
3474
  (0, react_1.useEffect)(() => {
3443
- console.log("SETTING TABLE DATA");
3444
3475
  getDataFromQuery();
3445
3476
  dataListenerUnsubscribe && Object.values(dataListenerUnsubscribe).map((u) => u());
3446
3477
  }, [page]);
@@ -3450,7 +3481,12 @@ function useDataViewerPaginator({ view, queryLimit, additionalEntryProcessing, f
3450
3481
  const pageDown = () => {
3451
3482
  setPage((p) => ([p[0] - 1, p[0]]));
3452
3483
  };
3453
- return ({ ...{ tableData, pageUp, pageDown, setFilters, page: page[0], loading, updateSearch: setSearchString } });
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 } });
3454
3490
  }
3455
3491
  ;
3456
3492
  //# sourceMappingURL=hooks.js.map