placementt-core 11.0.914 → 11.0.951
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.js +45 -0
- package/lib/constants.js.map +1 -1
- package/lib/hooks.d.ts +26 -19
- package/lib/hooks.js +58 -43
- package/lib/hooks.js.map +1 -1
- package/lib/typeDefinitions.d.ts +63 -1
- package/lib/util.d.ts +25 -1
- package/lib/util.js +327 -0
- package/lib/util.js.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +47 -0
- package/src/hooks.tsx +67 -48
- package/src/typeDefinitions.ts +66 -2
- package/src/util.ts +348 -2
package/src/hooks.tsx
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
import algoliasearch from "algoliasearch";
|
|
23
23
|
import {getDownloadURL, ref} from "firebase/storage";
|
|
24
24
|
import {OrganisationAddress} from "placementt-core";
|
|
25
|
+
import {objectsEqualNew} from "./util";
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
type StudentPlacementListParams = {
|
|
@@ -161,6 +162,9 @@ type NewInstitutePlacementParams = {
|
|
|
161
162
|
inProgress?: boolean,
|
|
162
163
|
view: "list"|"table",
|
|
163
164
|
filters?: FilterObject,
|
|
165
|
+
initialSort?: string,
|
|
166
|
+
initialSearch?: string
|
|
167
|
+
uid?: string,
|
|
164
168
|
}
|
|
165
169
|
|
|
166
170
|
|
|
@@ -323,7 +327,7 @@ export function useOldInstitutePlacementList({id, user, cohort, queryConstraint,
|
|
|
323
327
|
}
|
|
324
328
|
|
|
325
329
|
|
|
326
|
-
export function useNewInstitutePlacementList({id, user, filters, view, cohort, queryConstraints, ql=DEFAULTQUERYLIMIT, inProgress}:NewInstitutePlacementParams) {
|
|
330
|
+
export function useNewInstitutePlacementList({id, user, uid, filters, initialSort, initialSearch, view, cohort, queryConstraints, ql=DEFAULTQUERYLIMIT, inProgress}:NewInstitutePlacementParams) {
|
|
327
331
|
const [query, setQuery] = useState<QueryObject[]>();
|
|
328
332
|
|
|
329
333
|
const sorts:Sorts = {
|
|
@@ -377,14 +381,13 @@ export function useNewInstitutePlacementList({id, user, filters, view, cohort, q
|
|
|
377
381
|
return false;
|
|
378
382
|
}
|
|
379
383
|
}
|
|
380
|
-
console.log("Valid placement", k);
|
|
381
384
|
return {...placement, id: k};
|
|
382
385
|
}
|
|
383
386
|
|
|
384
|
-
|
|
385
|
-
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(query || [], user, s, sort, page, filters, limit, cohort, inProgress)})
|
|
387
|
+
const {tableData, pageUp, pageDown, setFilters, page, setView, loading, updateSearch, updateSort, sort} = useDataViewerPaginator({view, filters, sorts, queryLimit: ql, initialSort, initialSearch, data: query, additionalEntryProcessing: additionalProcessing, onSearch: async (s, sort, page, filters, limit) => await algoliaPlacementSearch(query || [], user, s, sort, page, filters, limit, cohort, inProgress)})
|
|
386
388
|
|
|
387
389
|
useEffect(() => {
|
|
390
|
+
console.log("SET QUERY", user, queryConstraints, cohort);
|
|
388
391
|
// Sets the query of for the DataViewerPaginator
|
|
389
392
|
if(user.product !== "institutes" || user.userType !== "Staff") {
|
|
390
393
|
setQuery(undefined);
|
|
@@ -394,6 +397,8 @@ export function useNewInstitutePlacementList({id, user, filters, view, cohort, q
|
|
|
394
397
|
const constraints:QueryObjectConstraint = [["oId", "==", user.oId], ["draft", "==", false]];
|
|
395
398
|
|
|
396
399
|
cohort && constraints.push(["cohort", "==", cohort]);
|
|
400
|
+
uid && constraints.push(["uid", "==", uid]);
|
|
401
|
+
|
|
397
402
|
queryConstraints && constraints.unshift(...queryConstraints);
|
|
398
403
|
inProgress !== undefined && constraints.push(["inProgress", "==", inProgress]);
|
|
399
404
|
|
|
@@ -1044,25 +1049,26 @@ const algoliaUsersSearch = async (data: QueryObject[], user: UserData, query?: s
|
|
|
1044
1049
|
if (!constraints?.length) return {};
|
|
1045
1050
|
|
|
1046
1051
|
let userSearchString = constraints.map(([k, e, v]) => {
|
|
1047
|
-
if (e === "==") return `${k}
|
|
1048
|
-
if (e === "!=") return `${k}
|
|
1052
|
+
if (e === "==") return `${k}:${v}`; // Equality check
|
|
1053
|
+
if (e === "!=") return `${k}:-${v}`; // Not equal check
|
|
1049
1054
|
if (e === "<") return `${k}:<${v}`; // Less than check
|
|
1050
1055
|
if (e === "<=") return `${k}:<=${v}`; // Less than or equal check
|
|
1051
1056
|
if (e === ">") return `${k}:>${v}`; // Greater than check
|
|
1052
1057
|
if (e === ">=") return `${k}:>=${v}`; // Greater than or equal check
|
|
1053
|
-
if (e === "array-contains") return `${k}
|
|
1058
|
+
if (e === "array-contains") return `${k}:${v}`; // Array contains check (string format)
|
|
1054
1059
|
if (e === "array-contains-any") return `${k}:"${(v as string[]).join('","')}"`; // Array contains any of the values (string format)
|
|
1055
|
-
if (e === "in") return
|
|
1056
|
-
if (e === "not-in") return
|
|
1060
|
+
if (e === "in") return `(${(v as string[]).map((value) => `${k}:${value}`).join(' OR ')})`; // In check
|
|
1061
|
+
if (e === "not-in") return (v as string[]).map((value) => `${k}:-${value}`).join(' AND '); // In check
|
|
1057
1062
|
return;
|
|
1058
1063
|
}).join(" AND ");
|
|
1059
1064
|
|
|
1060
|
-
console.log("QUERY", userSearchString);
|
|
1061
|
-
|
|
1062
1065
|
filters && Object.entries(filters).filter(([, filter]) => filter.value).map(([id, filter]) => {
|
|
1063
1066
|
userSearchString = userSearchString + ` AND ${id}:${filter.value}`;
|
|
1064
1067
|
});
|
|
1065
1068
|
|
|
1069
|
+
console.log("QUERY", userSearchString);
|
|
1070
|
+
|
|
1071
|
+
|
|
1066
1072
|
const options = {
|
|
1067
1073
|
filters: userSearchString,
|
|
1068
1074
|
hitsPerPage: limit,
|
|
@@ -1089,11 +1095,12 @@ type NewUserPaginatorParams = {
|
|
|
1089
1095
|
view: "list"|"table",
|
|
1090
1096
|
filters?: FilterObject,
|
|
1091
1097
|
institute: InstituteData,
|
|
1092
|
-
userType: "Staff"|"Students"
|
|
1098
|
+
userType: "Staff"|"Students",
|
|
1099
|
+
initialSort?: string
|
|
1093
1100
|
}
|
|
1094
1101
|
|
|
1095
1102
|
|
|
1096
|
-
export function useNewCohortUserPaginator({user, institute, filters, view, cohort, queryConstraints, ql=DEFAULTQUERYLIMIT, userType}:NewUserPaginatorParams) {
|
|
1103
|
+
export function useNewCohortUserPaginator({user, institute, initialSort, filters, view, cohort, queryConstraints, ql=DEFAULTQUERYLIMIT, userType}:NewUserPaginatorParams) {
|
|
1097
1104
|
const [query, setQuery] = useState<QueryObject[]>();
|
|
1098
1105
|
|
|
1099
1106
|
const firebaseQuery = new FirebaseQuery();
|
|
@@ -1202,7 +1209,7 @@ export function useNewCohortUserPaginator({user, institute, filters, view, cohor
|
|
|
1202
1209
|
}, [user, queryConstraints, cohort])
|
|
1203
1210
|
|
|
1204
1211
|
|
|
1205
|
-
const {tableData, pageUp, pageDown, setFilters, page, setView, loading, updateSearch, updateSort, sort} = useDataViewerPaginator({view, filters, sorts, queryLimit: ql, data: query, onSearch: async (s, sort, page, filters, limit) => await algoliaUsersSearch(query || [], user, s, sort, page, filters, limit, cohort)})
|
|
1212
|
+
const {tableData, pageUp, pageDown, setFilters, page, setView, loading, updateSearch, updateSort, sort} = useDataViewerPaginator({view, filters, initialSort, sorts, queryLimit: ql, data: query, onSearch: async (s, sort, page, filters, limit) => await algoliaUsersSearch(query || [], user, s, sort, page, filters, limit, cohort)})
|
|
1206
1213
|
|
|
1207
1214
|
|
|
1208
1215
|
return {tableData, page, loading, updateSearch, setFilters, setView, pageUp, pageDown, sorts, updateSort, sort}
|
|
@@ -4129,10 +4136,12 @@ export type DataViewerPaginater = {
|
|
|
4129
4136
|
onSearch?: boolean | ((search?: string, sort?: [string, {value: string, direction: "asc"|"desc"}], page?: number, filters?:FilterObject, limit?: number) => Promise<{ [key: string]: any }>);
|
|
4130
4137
|
data?: {[key:string]:{[key:string]: unknown}}|QueryObject[];
|
|
4131
4138
|
additionalEntryProcessing?: (k: string, v: any) => Promise<any> | any,
|
|
4132
|
-
sorts?: Sorts
|
|
4139
|
+
sorts?: Sorts,
|
|
4140
|
+
initialSort?: string,
|
|
4141
|
+
initialSearch?: string
|
|
4133
4142
|
}
|
|
4134
4143
|
|
|
4135
|
-
export function useDataViewerPaginator({view: initialView, sorts, queryLimit=10, additionalEntryProcessing, formatItems, snapshot, filters: initialFilters, onSearch, data}:DataViewerPaginater) {
|
|
4144
|
+
export function useDataViewerPaginator({view: initialView, sorts, queryLimit=10, additionalEntryProcessing, formatItems, snapshot, filters: initialFilters, initialSort, initialSearch, onSearch, data}:DataViewerPaginater) {
|
|
4136
4145
|
const [tableData, setTableData] = useState<{[key:string]:{[key:string]: unknown}}>(Array.isArray(data) ? Object.fromEntries(Object.entries(data).slice(0, queryLimit)) : {});
|
|
4137
4146
|
const [page, setPage] = useState([1, 0]);
|
|
4138
4147
|
const [view, setView] = useState(initialView);
|
|
@@ -4142,16 +4151,18 @@ export function useDataViewerPaginator({view: initialView, sorts, queryLimit=10,
|
|
|
4142
4151
|
const [dataListenerUnsubscribe, setDataListenerUnsubscribe] = useState<{[key: string] : Unsubscribe}>();
|
|
4143
4152
|
const [loading, setLoading] = useState<boolean|"loaded">(true);
|
|
4144
4153
|
const [searchString, setSearchString] = useState<string>();
|
|
4145
|
-
const [sort, setSort] = useState<[string, {value: string, direction: "asc"|"desc"}]>();
|
|
4154
|
+
const [sort, setSort] = useState<[string, {value: string, direction: "asc"|"desc"}]|undefined>((initialSort && sorts && sorts[initialSort]) ? [initialSort, sorts[initialSort]] : undefined);
|
|
4155
|
+
const [fData, setFData] = useState(data);
|
|
4146
4156
|
|
|
4157
|
+
console.log("SORT", sort, initialSort, sorts, sorts?.[initialSort || ""]);
|
|
4147
4158
|
|
|
4148
4159
|
|
|
4149
4160
|
const processedData = async (k: string, v: any) => additionalEntryProcessing ? await additionalEntryProcessing(k, v) : v;
|
|
4150
4161
|
|
|
4151
4162
|
const setTableDataFromDefinedData = async () => {
|
|
4152
|
-
if (!
|
|
4163
|
+
if (!fData || Array.isArray(fData)) return;
|
|
4153
4164
|
|
|
4154
|
-
const dataWithAdditionalProcessingPossibleNulls: [string, any][] = (await Promise.all(Object.entries(
|
|
4165
|
+
const dataWithAdditionalProcessingPossibleNulls: [string, any][] = (await Promise.all(Object.entries(fData).map(async ([k, v]) => [k, await processedData(k, v)])))
|
|
4155
4166
|
const dataWithAdditionalProcessing = dataWithAdditionalProcessingPossibleNulls.filter(([k, v]) => v);
|
|
4156
4167
|
|
|
4157
4168
|
const searchedData: [string, any][] = searchString ? dataWithAdditionalProcessing.filter(([, v]) => {
|
|
@@ -4173,7 +4184,7 @@ export function useDataViewerPaginator({view: initialView, sorts, queryLimit=10,
|
|
|
4173
4184
|
if (!queryLimit) throw new Error("Tables must have a limit defined.");
|
|
4174
4185
|
const newData:[string, any][] = filteredData.slice((page[0] - 1)*queryLimit, page[0]*queryLimit);
|
|
4175
4186
|
setTableData(Object.fromEntries(newData));
|
|
4176
|
-
if (Object.keys(Object.fromEntries(newData)).pop() === Object.keys(
|
|
4187
|
+
if (Object.keys(Object.fromEntries(newData)).pop() === Object.keys(fData).pop()) {
|
|
4177
4188
|
setLoading("loaded");
|
|
4178
4189
|
} else {
|
|
4179
4190
|
setLoading(false);
|
|
@@ -4191,7 +4202,7 @@ export function useDataViewerPaginator({view: initialView, sorts, queryLimit=10,
|
|
|
4191
4202
|
|
|
4192
4203
|
// if (!filters) return;
|
|
4193
4204
|
setLoading(true);
|
|
4194
|
-
if (!Array.isArray(
|
|
4205
|
+
if (!Array.isArray(fData)) {
|
|
4195
4206
|
setTableDataFromDefinedData();
|
|
4196
4207
|
return;
|
|
4197
4208
|
}
|
|
@@ -4226,7 +4237,7 @@ export function useDataViewerPaginator({view: initialView, sorts, queryLimit=10,
|
|
|
4226
4237
|
cursorPos = currentQueryAnchor.startQueryPos;
|
|
4227
4238
|
}
|
|
4228
4239
|
|
|
4229
|
-
const querySchema:QueryObject =
|
|
4240
|
+
const querySchema:QueryObject = fData[cursorPos];
|
|
4230
4241
|
|
|
4231
4242
|
const createQuery = (queryData:QueryObject) => {
|
|
4232
4243
|
const constraints:any[] = [];
|
|
@@ -4288,7 +4299,7 @@ export function useDataViewerPaginator({view: initialView, sorts, queryLimit=10,
|
|
|
4288
4299
|
|
|
4289
4300
|
// Function to handle query snapshot
|
|
4290
4301
|
async function handleQuerySnapshot(querySnapshot: QuerySnapshot) {
|
|
4291
|
-
if (!Array.isArray(
|
|
4302
|
+
if (!Array.isArray(fData)) throw new Error("Called querySnapshot but data is defined.");
|
|
4292
4303
|
if (!queryLimit) throw new Error("Firestore queries must have a limit defined.");
|
|
4293
4304
|
|
|
4294
4305
|
const queryResults: { [key: string]: { [key: string]: unknown } } = {};
|
|
@@ -4343,7 +4354,7 @@ export function useDataViewerPaginator({view: initialView, sorts, queryLimit=10,
|
|
|
4343
4354
|
|
|
4344
4355
|
if (querySnapshot.size < queryLimit && Object.keys(itemList).length < queryLimit) {
|
|
4345
4356
|
// If we have ran out of entries, increase or decrease the index.
|
|
4346
|
-
if (page[0] > page[1] && cursorPos+1 <
|
|
4357
|
+
if (page[0] > page[1] && cursorPos+1 < fData.length) {
|
|
4347
4358
|
return getDataFromQuery(itemList, {...currentQueryAnchor, endQueryPos: currentQueryAnchor.endQueryPos+1}, "increase", prevEntries);
|
|
4348
4359
|
} else if (page[0] < page[1] && cursorPos > 0) {
|
|
4349
4360
|
return getDataFromQuery(itemList, {...currentQueryAnchor, startQueryPos: currentQueryAnchor.startQueryPos-1}, "decrease", prevEntries);
|
|
@@ -4357,7 +4368,7 @@ export function useDataViewerPaginator({view: initialView, sorts, queryLimit=10,
|
|
|
4357
4368
|
|
|
4358
4369
|
if (querySnapshot.size === 0 &&
|
|
4359
4370
|
Object.keys(itemList).length === 0 &&
|
|
4360
|
-
currentQueryAnchor.endQueryPos+1 ===
|
|
4371
|
+
currentQueryAnchor.endQueryPos+1 === fData.length &&
|
|
4361
4372
|
page[0] > 1) {
|
|
4362
4373
|
if (view === "table") {
|
|
4363
4374
|
setTableData({});
|
|
@@ -4395,31 +4406,34 @@ export function useDataViewerPaginator({view: initialView, sorts, queryLimit=10,
|
|
|
4395
4406
|
};
|
|
4396
4407
|
|
|
4397
4408
|
useEffect(() => {
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
reset();
|
|
4402
|
-
}, [filters]);
|
|
4403
|
-
|
|
4404
|
-
useEffect(() => {
|
|
4405
|
-
console.log("View reset.")
|
|
4409
|
+
if (objectsEqualNew(fData, data)) return;
|
|
4410
|
+
console.log("data reset.", fData, data);
|
|
4411
|
+
setFData(data);
|
|
4406
4412
|
reset();
|
|
4407
|
-
}, [
|
|
4413
|
+
}, [data]);
|
|
4408
4414
|
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4415
|
+
const updateFilters = (fFilters?: FilterObject) => {
|
|
4416
|
+
if (!objectsEqualNew(fFilters, filters)) {
|
|
4417
|
+
console.log("FILTER RESET", fFilters, filters);
|
|
4418
|
+
setFilters(fFilters);
|
|
4419
|
+
reset();
|
|
4420
|
+
}
|
|
4421
|
+
}
|
|
4413
4422
|
|
|
4414
|
-
|
|
4415
|
-
|
|
4423
|
+
|
|
4424
|
+
const updateSearch = (search: string) => {
|
|
4425
|
+
if (searchString === search) return;
|
|
4426
|
+
console.log("SEARCH RESET", searchString, search);
|
|
4427
|
+
setSearchString(search);
|
|
4416
4428
|
reset();
|
|
4417
|
-
}
|
|
4429
|
+
}
|
|
4418
4430
|
|
|
4419
|
-
|
|
4420
|
-
|
|
4431
|
+
const updateView = (v: "list" | "table") => {
|
|
4432
|
+
if (v === view) return;
|
|
4433
|
+
console.log("View reset", view, v);
|
|
4434
|
+
setView(v);
|
|
4421
4435
|
reset();
|
|
4422
|
-
}
|
|
4436
|
+
}
|
|
4423
4437
|
|
|
4424
4438
|
|
|
4425
4439
|
// Fetch new data when queries or page change
|
|
@@ -4436,10 +4450,15 @@ export function useDataViewerPaginator({view: initialView, sorts, queryLimit=10,
|
|
|
4436
4450
|
setPage((p) => ([p[0]-1, p[0]]));
|
|
4437
4451
|
};
|
|
4438
4452
|
|
|
4439
|
-
const updateSort = (sortLabel
|
|
4440
|
-
if (!
|
|
4441
|
-
|
|
4453
|
+
const updateSort = (sortLabel?: string) => {
|
|
4454
|
+
if (!sortLabel) {
|
|
4455
|
+
setSort(undefined);
|
|
4456
|
+
} else {
|
|
4457
|
+
if (!sorts || !sorts[sortLabel]) return;
|
|
4458
|
+
setSort([sortLabel, sorts[sortLabel]]);
|
|
4459
|
+
}
|
|
4460
|
+
reset();
|
|
4442
4461
|
}
|
|
4443
4462
|
|
|
4444
|
-
return ({...{tableData, pageUp, pageDown, setFilters, page: page[0], sorts, loading, sort, updateSort: updateSort, setView, updateSearch
|
|
4463
|
+
return ({...{tableData, pageUp, pageDown, search: searchString, setFilters: updateFilters, page: page[0], sorts, loading, sort, updateSort: updateSort, setView: updateView, updateSearch}});
|
|
4445
4464
|
};
|
package/src/typeDefinitions.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {DocumentData, DocumentReference, Timestamp} from "firebase/firestore";
|
|
2
2
|
import {Descendant} from "slate";
|
|
3
3
|
import {emailTemplates} from "./constants";
|
|
4
|
+
import {FilterObject} from "./hooks";
|
|
4
5
|
|
|
5
6
|
export type Products = "institutes"|"providers"|"students"|"admin";
|
|
6
7
|
|
|
@@ -369,9 +370,24 @@ export type UserData = {
|
|
|
369
370
|
provider: number[],
|
|
370
371
|
student: number[],
|
|
371
372
|
}},
|
|
372
|
-
alumniConversationUid?: string
|
|
373
|
+
alumniConversationUid?: string,
|
|
374
|
+
savedDataViewerFilters?: {
|
|
375
|
+
[cohortId: string]: {
|
|
376
|
+
[key in "cohortPlacements"|"cohortStudents"]: {
|
|
377
|
+
[viewKey: string]: DataViewerFilterView
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
373
381
|
};
|
|
374
382
|
|
|
383
|
+
export type DataViewerFilterView = {
|
|
384
|
+
title: string,
|
|
385
|
+
search?: string,
|
|
386
|
+
sort?: string,
|
|
387
|
+
filters?: FilterObject,
|
|
388
|
+
permanent?: boolean,
|
|
389
|
+
}
|
|
390
|
+
|
|
375
391
|
export type AnalyticsItem = {
|
|
376
392
|
units?: "placements"|"weeks"|"days"|"hours",
|
|
377
393
|
name?: string
|
|
@@ -798,6 +814,11 @@ export type CohortData = {
|
|
|
798
814
|
recurringEmails?: {
|
|
799
815
|
sendType?: "all"|"lastWeek",
|
|
800
816
|
frequency?: "oneTime"|"weeklyMonday"|"fortnightlyMonday"
|
|
817
|
+
},
|
|
818
|
+
savedDataViewerFilters?: {
|
|
819
|
+
[key in "cohortPlacements"|"cohortStudents"]: {
|
|
820
|
+
[key: string]: DataViewerFilterView
|
|
821
|
+
}
|
|
801
822
|
}
|
|
802
823
|
}
|
|
803
824
|
|
|
@@ -1028,7 +1049,7 @@ export type EmailTemplateConfig = {
|
|
|
1028
1049
|
description: string,
|
|
1029
1050
|
params: string[],
|
|
1030
1051
|
button?: {text: string, link: string},
|
|
1031
|
-
type: "workflow"|"feedback"
|
|
1052
|
+
type: "workflow"|"feedback"|"event"
|
|
1032
1053
|
}
|
|
1033
1054
|
|
|
1034
1055
|
|
|
@@ -1071,10 +1092,16 @@ export type SchoolData = OrganisationAddress&{
|
|
|
1071
1092
|
export type ExternalEvent = {
|
|
1072
1093
|
name: string,
|
|
1073
1094
|
description: string,
|
|
1095
|
+
staffInformation?: string,
|
|
1096
|
+
studentInformation?: string,
|
|
1097
|
+
employerInformation?: string
|
|
1098
|
+
designatedStaff: string,
|
|
1074
1099
|
created: string,
|
|
1075
1100
|
activityId?: string,
|
|
1101
|
+
gatsbyBenchmarks?: string, // String array
|
|
1076
1102
|
oId: string,
|
|
1077
1103
|
submissionClose: string,
|
|
1104
|
+
acceptingEmployers?: boolean,
|
|
1078
1105
|
schoolId?: string,
|
|
1079
1106
|
startDate?: string,
|
|
1080
1107
|
endDate?: string,
|
|
@@ -1094,7 +1121,24 @@ export type ExternalEvent = {
|
|
|
1094
1121
|
employers: {
|
|
1095
1122
|
shareable?: boolean,
|
|
1096
1123
|
filters: {[key: string]: unknown}
|
|
1124
|
+
},
|
|
1125
|
+
employerFeedback: {
|
|
1126
|
+
files: string[],
|
|
1127
|
+
forms: string[],
|
|
1128
|
+
requiredFiles: {
|
|
1129
|
+
fileName: string,
|
|
1130
|
+
fileType: string
|
|
1131
|
+
}[],
|
|
1132
|
+
},
|
|
1133
|
+
studentFeedback: {
|
|
1134
|
+
files: string[],
|
|
1135
|
+
forms: string[],
|
|
1136
|
+
requiredFiles: {
|
|
1137
|
+
fileName: string,
|
|
1138
|
+
fileType: string
|
|
1139
|
+
}[],
|
|
1097
1140
|
}
|
|
1141
|
+
completedStages: ("basicDetails"|"employerInvites"|"studentInvites"|"employerSelection"|"feedback")[]
|
|
1098
1142
|
}&Address
|
|
1099
1143
|
|
|
1100
1144
|
|
|
@@ -1172,4 +1216,24 @@ export type Update = {
|
|
|
1172
1216
|
buttonLink?: string,
|
|
1173
1217
|
date: string,
|
|
1174
1218
|
imageData?: boolean
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
|
|
1222
|
+
|
|
1223
|
+
export type ExternalEventAttendee = {
|
|
1224
|
+
oId: string,
|
|
1225
|
+
eventId: string,
|
|
1226
|
+
providerContactId: string,
|
|
1227
|
+
status: "invited"|"providerAvailable"|"finalConfirmationSent"|"providerConfirmed"|"feedbackSent"
|
|
1228
|
+
emails: {
|
|
1229
|
+
[k in "invited"|"finalConfirmationSent"|"feedbackSent"]: {
|
|
1230
|
+
sent: number, // If below 3, keep sending reminders.
|
|
1231
|
+
reconciled: string|boolean,
|
|
1232
|
+
log: {
|
|
1233
|
+
[k: string]: string // emailNumber_dateTimeString : eventType
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
attended?: boolean,
|
|
1238
|
+
feedback: {[key: string]: unknown}
|
|
1175
1239
|
}
|