github.com/quickfeed/quickfeed@v0.0.0-20240507093252-ed8ca812a09c/public/src/overmind/namespaces/review/state.ts (about) 1 import { derived } from "overmind" 2 import { Context } from "../.." 3 import { GradingCriterion_Grade, Review, User } from "../../../../proto/qf/types_pb" 4 5 export type ReviewState = { 6 /* The index of the selected review */ 7 selectedReview: number 8 9 /* Contains all reviews for the different courses, indexed by the course id and submission id */ 10 reviews: Map<bigint, Review[]> 11 12 /* The current review */ 13 // derived from reviews and selectedReview 14 currentReview: Review | null 15 16 /* The reviewer for the current review */ 17 // derived from currentReview 18 reviewer: User | null 19 20 /* Indicates if the current review can be updated */ 21 canUpdate: boolean 22 23 /* The amount of criteria for the current review */ 24 criteriaTotal: number 25 26 /* The amount of criteria that have been graded for the current review */ 27 graded: number 28 29 /* The ID of the assignment selected. Used to determine which assignment to release */ 30 assignmentID: bigint 31 32 /* The minimum score submissions must have to be released or approved */ 33 /* Sent as argument to updateSubmissions */ 34 minimumScore: number 35 } 36 37 export const state: ReviewState = { 38 selectedReview: -1, 39 40 reviews: new Map(), 41 42 currentReview: derived(({ reviews, selectedReview }: ReviewState, { selectedSubmission, activeCourse }: Context["state"]) => { 43 if (!(activeCourse > 0 && selectedSubmission !== null)) { 44 return null 45 } 46 const check = reviews.get(selectedSubmission.ID) 47 return check ? check[selectedReview] : null 48 }), 49 50 reviewer: derived(({ currentReview }: ReviewState, { courseTeachers }: Context["state"]) => { 51 if (!currentReview) { 52 return null 53 } 54 return courseTeachers[currentReview.ReviewerID.toString()] 55 }), 56 57 canUpdate: derived(({ currentReview }: ReviewState, { activeCourse, selectedSubmission }: Context["state"]) => { 58 return currentReview !== null && activeCourse > 0 && currentReview?.ID > 0 && selectedSubmission !== null 59 }), 60 61 criteriaTotal: derived((_state: ReviewState, rootState: Context["state"]) => { 62 let total = 0 63 if (rootState.selectedSubmission && rootState.activeCourse) { 64 const assignment = rootState.assignments[rootState.activeCourse.toString()]?.find(a => a.ID === rootState.selectedSubmission?.AssignmentID) 65 if (assignment) { 66 assignment.gradingBenchmarks.forEach(bm => { 67 bm.criteria.forEach(() => { 68 total++ 69 }) 70 }) 71 } 72 } 73 return total 74 }), 75 76 graded: derived(({ currentReview }: ReviewState) => { 77 let total = 0 78 currentReview?.gradingBenchmarks?.forEach(bm => { 79 bm.criteria.forEach((c) => { 80 if (c.grade > GradingCriterion_Grade.NONE) { 81 total++ 82 } 83 }) 84 }) 85 return total 86 }), 87 88 assignmentID: BigInt(-1), 89 minimumScore: 0, 90 }