Functional auto-process button on the teacher's Requests page that will mass confirm or reject all GCR API tasks.
IMPORTANT
You need to merge from main first to make sure the gcr-api branch is not behind.
If you were able to get GCR authentication working by linking with Google-authenticated Firebase logins, ignore this deliverable and talk to me (Matthew) as there is likely a better way to do this than what I outlined below.
Frontend
Add the auto-process button on the teacher's Requests page (ConfirmTasksTable)
Backend
This is just a suggested strategy, if you find a better way then by all means lmk!
In ConfirmTasksTable, you currently have a state variable completedTasks : CompletedTask[] storing the pending completion requests. Write an async function ProcessGCRTasks() that will:
Filter out tasks without a GCRID
Call courses.students once to obtain a reference between the student's email and their userID in Google Classroom
Use the filtered completedTasks array to run multiple API calls in tandem using Promise.allSettled(), and for each request:
Call courses.courseWork.studentSubmissions.get using the appropriate courseID, courseworkID (as GCRID), and id (as the student's Google Classroom ID, which can be derived from the email associated with the request in Questable, plus the reference obtained in step 2)
Return the original CompletedTask[] object augmented with the result of the API call, which will either be NOT_FOUND or the assignment data. (You can add a new property to the object called submission or something, which can be null or the submission data )
Note that it is important that you use Promise.allSettled and not Promise.all because if you use Promise.all, the entire array of async calls will reject if one of them rejects. Promise.allSettled still runs all your async calls even if some reject.
You should obtain an array of CompletedTask objects augmented with the submission results. You can type the augmented task object as CompletedGCRTask extends CompletedTask if you wish. Pass this array into a mutation ProcessGCRTasks that you write in mutations.js.
In mutations.js, write a function ProcessGCRTasks that accepts the augmented CompletedGCRTask[] from earlier. This will run a Firestore batched write such that for each task, if the submission exists, the task will be confirmed as in confirmTask, and if the submission does not exist, the task will be rejected as in denyTask. Note that instead of just copy pasting the logic from confirmTask and denyTask for the batched write, it would be best to refactor the logic from confirmTask, denyTask, and ProcessGCRTasks so that there is minimal repetition between the 3 functions. Jayden has already done this in another form so ask him about his strategy if necessary!
GCR API: Teacher Mass Confirm Tasks
Overview
Functional auto-process button on the teacher's Requests page that will mass confirm or reject all GCR API tasks.
IMPORTANT
main
first to make sure thegcr-api
branch is not behind.Frontend
Add the auto-process button on the teacher's Requests page (
ConfirmTasksTable
)Backend
This is just a suggested strategy, if you find a better way then by all means lmk!
ConfirmTasksTable
, you currently have a state variablecompletedTasks : CompletedTask[]
storing the pending completion requests. Write an async functionProcessGCRTasks()
that will:GCRID
courses.students
once to obtain a reference between the student's email and their userID in Google ClassroomcompletedTasks
array to run multiple API calls in tandem usingPromise.allSettled()
, and for each request:courses.courseWork.studentSubmissions.get
using the appropriatecourseID
,courseworkID
(asGCRID
), andid
(as the student's Google Classroom ID, which can be derived from the email associated with the request in Questable, plus the reference obtained in step 2)CompletedTask[]
object augmented with the result of the API call, which will either beNOT_FOUND
or the assignment data. (You can add a new property to the object calledsubmission
or something, which can benull
or the submission data )Promise.allSettled
and notPromise.all
because if you usePromise.all
, the entire array of async calls will reject if one of them rejects.Promise.allSettled
still runs all your async calls even if some reject.CompletedTask
objects augmented with the submission results. You can type the augmented task object asCompletedGCRTask extends CompletedTask
if you wish. Pass this array into a mutationProcessGCRTasks
that you write inmutations.js
.mutations.js
, write a functionProcessGCRTasks
that accepts the augmentedCompletedGCRTask[]
from earlier. This will run a Firestore batched write such that for each task, if the submission exists, the task will be confirmed as inconfirmTask
, and if the submission does not exist, the task will be rejected as indenyTask
. Note that instead of just copy pasting the logic fromconfirmTask
anddenyTask
for the batched write, it would be best to refactor the logic fromconfirmTask
,denyTask
, andProcessGCRTasks
so that there is minimal repetition between the 3 functions. Jayden has already done this in another form so ask him about his strategy if necessary!