Skip to content

Commit

Permalink
Fixes to the custom view (#1256)
Browse files Browse the repository at this point in the history
* add user variables to custom view

* fix Uuid from prev pr

* Consent form ansers csv expert and fixes

* small fix

* remove console.log

* add module completion date to data sent for custom view exercise service

* attempt to fix undefined user_answer

* rename db function to more descriptive
  • Loading branch information
anadis504 authored Mar 28, 2024
1 parent b797496 commit 395be6b
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
fetchCourseModuleExercisesAndSubmissionsByType,
fetchDefaultModuleIdByCourseId,
fetchModuleIdByChapterId,
getAllCourseModuleCompletionsForUserAndCourseInstance,
} from "../../../../services/backend"
import ErrorBanner from "../../../../shared-module/components/ErrorBanner"
import MessageChannelIFrame from "../../../../shared-module/components/MessageChannelIFrame"
Expand Down Expand Up @@ -37,8 +38,17 @@ const CustomViewIframe: React.FC<React.PropsWithChildren<CustomViewIframeProps>>
const courseInstanceId = pageContext.instance?.id
const courseId = pageContext.settings?.current_course_id

const courseModuleCompletionsQuery = useQuery({
queryKey: [`${courseInstanceId}-course-module-completions-${userInfo.data?.user_id}`],
queryFn: () =>
getAllCourseModuleCompletionsForUserAndCourseInstance(
assertNotNullOrUndefined(courseInstanceId),
assertNotNullOrUndefined(userInfo.data?.user_id),
),
enabled: !!courseInstanceId && !!userInfo.data?.user_id,
})
const courseInfo = useCourseInfo(pageContext.settings?.current_course_id)
console.log(courseInfo.data?.name)

const moduleIdByChapter = useQuery({
queryKey: [`course-modules-chapter-${chapterId}`],
queryFn: () => fetchModuleIdByChapterId(assertNotNullOrUndefined(chapterId)),
Expand All @@ -65,6 +75,10 @@ const CustomViewIframe: React.FC<React.PropsWithChildren<CustomViewIframeProps>>
enabled: !!moduleId && !!courseInstanceId,
})

const completionDate = courseModuleCompletionsQuery.data?.find(
(compl) => compl.course_module_id === moduleId,
)?.completion_date

const submission_data = submissions_by_exercise.data
const subs_by_exercise = useMemo(() => {
if (!submission_data) {
Expand All @@ -77,16 +91,11 @@ const CustomViewIframe: React.FC<React.PropsWithChildren<CustomViewIframeProps>>
exercise_tasks: submission_data.exercise_tasks.task_gradings
.filter((grading) => grading.exercise_id == exer.id)
.map((grading) => {
const answer = submission_data.exercise_tasks.task_submissions
.filter((sub) => sub.exercise_task_grading_id == grading.id)
.sort((a, b) => parseISO(b.created_at).getTime() - parseISO(a.created_at).getTime())
.filter(
(task_asnwer, index, array) =>
array.findIndex((el) => el.exercise_task_id === task_asnwer.exercise_task_id) ===
index,
)[0]
const answer = submission_data.exercise_tasks.task_submissions.find(
(sub) => sub.exercise_task_grading_id === grading.id,
)
const publicSpec = submission_data.exercise_tasks.exercise_tasks.find(
(task) => task.id == grading.exercise_task_id,
(task) => task.id === grading.exercise_task_id,
)?.public_spec
return {
task_id: grading.exercise_task_id,
Expand Down Expand Up @@ -129,6 +138,7 @@ const CustomViewIframe: React.FC<React.PropsWithChildren<CustomViewIframeProps>>
// eslint-disable-next-line i18next/no-literal-string
view_type: "custom-view",
course_name: courseInfo.data?.name,
module_completion_date: completionDate ? parseISO(completionDate).toLocaleDateString() : null,
user_information: {
user_id: userInfo.data.user_id,
first_name: userInfo.data.first_name,
Expand Down
12 changes: 12 additions & 0 deletions services/course-material/src/services/backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
CourseMaterialExercise,
CourseMaterialPeerReviewDataWithToken,
CourseMaterialPeerReviewSubmission,
CourseModuleCompletion,
CoursePageWithUserData,
CustomViewExerciseSubmissions,
ExamData,
Expand Down Expand Up @@ -50,6 +51,7 @@ import {
isCourseInstance,
isCourseMaterialExercise,
isCourseMaterialPeerReviewDataWithToken,
isCourseModuleCompletion,
isCoursePageWithUserData,
isCustomViewExerciseSubmissions,
isExamData,
Expand Down Expand Up @@ -624,3 +626,13 @@ export const fetchDefaultModuleIdByCourseId = async (course_id: string) => {
})
return validateResponse(res, isUuid)
}

export const getAllCourseModuleCompletionsForUserAndCourseInstance = async (
courseInstanceId: string,
userId: string,
): Promise<CourseModuleCompletion[]> => {
const response = await courseMaterialClient.get(
`/course-instances/${courseInstanceId}/course-module-completions/${userId}`,
)
return validateResponse(response, isArray(isCourseModuleCompletion))
}

This file was deleted.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions services/headless-lms/models/src/exercise_task_submissions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ pub async fn get_user_custom_view_exercise_tasks_by_module_and_exercise_type(
course_instance_id: Uuid,
) -> ModelResult<CustomViewExerciseTasks> {
let task_submissions =
crate::exercise_task_submissions::get_user_exersice_task_submissions_by_course_module_and_exercise_type(
crate::exercise_task_submissions::get_user_latest_exercise_task_submissions_by_course_module_and_exercise_type(
&mut *conn,
user_id,
exercise_type,
Expand Down Expand Up @@ -497,7 +497,7 @@ pub async fn get_user_custom_view_exercise_tasks_by_module_and_exercise_type(
}

/// get all submissions for user and course module and exercise type
pub async fn get_user_exersice_task_submissions_by_course_module_and_exercise_type(
pub async fn get_user_latest_exercise_task_submissions_by_course_module_and_exercise_type(
conn: &mut PgConnection,
user_id: Uuid,
exercise_type: &str,
Expand All @@ -507,7 +507,8 @@ pub async fn get_user_exersice_task_submissions_by_course_module_and_exercise_ty
let res: Vec<CustomViewExerciseTaskSubmission> = sqlx::query_as!(
CustomViewExerciseTaskSubmission,
r#"
SELECT g.id,
SELECT DISTINCT ON (g.exercise_task_id)
g.id,
g.created_at,
g.exercise_slide_submission_id,
g.exercise_slide_id,
Expand All @@ -528,6 +529,7 @@ pub async fn get_user_exersice_task_submissions_by_course_module_and_exercise_ty
AND ess.deleted_at IS NULL
AND e.deleted_at IS NULL
AND c.deleted_at IS NULL
ORDER BY g.exercise_task_id, g.created_at DESC
"#,
user_id,
course_instance_id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use models::{
course_background_question_answers::NewCourseBackgroundQuestionAnswer,
course_background_questions::CourseBackgroundQuestionsAndAnswers,
course_instance_enrollments::CourseInstanceEnrollment,
course_module_completions::CourseModuleCompletion,
library::progressing::UserModuleCompletionStatus,
user_exercise_states::{UserCourseInstanceChapterExerciseProgress, UserCourseInstanceProgress},
};
Expand Down Expand Up @@ -148,6 +149,36 @@ async fn save_course_settings(
token.authorized_ok(web::Json(enrollment))
}

/**
GET /course-instances/:id/course-module-completions/:user_id - Returns a list of all course module completions for a given user for this course instance.
*/
#[instrument(skip(pool))]

async fn get_all_get_all_course_module_completions_for_user_by_course_instance_id(
params: web::Path<(Uuid, Uuid)>,
pool: web::Data<PgPool>,
user: AuthUser,
) -> ControllerResult<web::Json<Vec<CourseModuleCompletion>>> {
let (course_instance_id, user_id) = params.into_inner();
let mut conn = pool.acquire().await?;
let token = authorize(
&mut conn,
Act::ViewUserProgressOrDetails,
Some(user.id),
Res::CourseInstance(course_instance_id),
)
.await?;

let res = models::course_module_completions::get_all_by_course_instance_and_user_id(
&mut conn,
course_instance_id,
user_id,
)
.await?;

token.authorized_ok(web::Json(res))
}

/**
GET /api/v0/course-material/course-instance/:course_instance_id/background-questions-and-answers - Gets background questions and answers for an course instance.
*/
Expand Down Expand Up @@ -190,6 +221,10 @@ pub fn _add_routes(cfg: &mut ServiceConfig) {
"/{course_instance_id}/module-completions",
web::get().to(get_module_completions_for_course_instance),
)
.route(
"/{course_instance_id}/course-module-completions/{user_id}",
web::get().to(get_all_get_all_course_module_completions_for_user_by_course_instance_id),
)
.route(
"/{course_instance_id}/background-questions-and-answers",
web::get().to(get_background_questions_and_answers),
Expand Down
2 changes: 2 additions & 0 deletions shared-module/src/exercise-service-protocol-types.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@ export function isCustomViewIframeState(obj: unknown): obj is CustomViewIframeSt
typedObj["user_variables"] === null ||
(isUserVariablesMap(typedObj["user_variables"]) as boolean)) &&
typeof typedObj["course_name"] === "string" &&
(typedObj["module_completion_date"] === null ||
typeof typedObj["module_completion_date"] === "string") &&
((typedObj["data"] !== null && typeof typedObj["data"] === "object") ||
typeof typedObj["data"] === "function") &&
Array.isArray(typedObj["data"]["submissions_by_exercise"]) &&
Expand Down
1 change: 1 addition & 0 deletions shared-module/src/exercise-service-protocol-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ export type CustomViewIframeState = {
user_information: UserInfo
user_variables?: UserVariablesMap | null
course_name: string
module_completion_date: string | null
data: {
submissions_by_exercise: Array<{
exercise_id: string
Expand Down

0 comments on commit 395be6b

Please sign in to comment.