diff --git a/client/src/pages/cockpit/CockpitUserCirclePage.vue b/client/src/pages/cockpit/CockpitUserCirclePage.vue index 4014e9cc..4d3b922f 100644 --- a/client/src/pages/cockpit/CockpitUserCirclePage.vue +++ b/client/src/pages/cockpit/CockpitUserCirclePage.vue @@ -19,9 +19,7 @@ onMounted(async () => { }); const user = computed(() => { - return cockpitStore.courseSessionUsers?.find( - (csu) => csu.user_id === Number(props.userId) - ); + return cockpitStore.courseSessionUsers?.find((csu) => csu.user_id === props.userId); }); diff --git a/client/src/pages/cockpit/CockpitUserProfilePage.vue b/client/src/pages/cockpit/CockpitUserProfilePage.vue index af001329..2634129e 100644 --- a/client/src/pages/cockpit/CockpitUserProfilePage.vue +++ b/client/src/pages/cockpit/CockpitUserProfilePage.vue @@ -28,9 +28,7 @@ const learningPath = computed(() => { }); const user = computed(() => { - return cockpitStore.courseSessionUsers?.find( - (csu) => csu.user_id === Number(props.userId) - ); + return cockpitStore.courseSessionUsers?.find((csu) => csu.user_id === props.userId); }); function setActiveClasses(isActive: boolean) { diff --git a/client/src/pages/cockpit/assignmentEvaluationPage/AssignmentEvaluationPage.vue b/client/src/pages/cockpit/assignmentEvaluationPage/AssignmentEvaluationPage.vue index fad881a7..d00ea917 100644 --- a/client/src/pages/cockpit/assignmentEvaluationPage/AssignmentEvaluationPage.vue +++ b/client/src/pages/cockpit/assignmentEvaluationPage/AssignmentEvaluationPage.vue @@ -49,7 +49,7 @@ onMounted(async () => { log.debug("AssignmentView mounted", props.assignmentId, props.userId); state.assignmentUser = courseSession.value.users.find( - (user) => user.user_id === Number(props.userId) + (user) => user.user_id === props.userId ); }); diff --git a/client/src/pages/cockpit/assignmentEvaluationPage/EvaluationSummary.vue b/client/src/pages/cockpit/assignmentEvaluationPage/EvaluationSummary.vue index a8a00790..2826bb50 100644 --- a/client/src/pages/cockpit/assignmentEvaluationPage/EvaluationSummary.vue +++ b/client/src/pages/cockpit/assignmentEvaluationPage/EvaluationSummary.vue @@ -88,7 +88,7 @@ const grade = computed(() => { const evaluationUser = computed(() => { if (props.assignmentCompletion.evaluation_user) { return (courseSession.value.users ?? []).find( - (user) => user.user_id === Number(props.assignmentCompletion.evaluation_user) + (user) => user.user_id === props.assignmentCompletion.evaluation_user ) as CourseSessionUser; } diff --git a/client/src/pages/cockpit/assignmentsPage/AssignmentDetails.vue b/client/src/pages/cockpit/assignmentsPage/AssignmentDetails.vue index 79fd16fc..90e0c48b 100644 --- a/client/src/pages/cockpit/assignmentsPage/AssignmentDetails.vue +++ b/client/src/pages/cockpit/assignmentsPage/AssignmentDetails.vue @@ -32,7 +32,7 @@ const state = reactive({ statusByUser: [] as { userStatus: AssignmentCompletionStatus; progressStatus: StatusCountKey; - userId: number; + userId: string; grade: number | null; }[], progressStatusCount: {} as StatusCount, @@ -45,7 +45,7 @@ onMounted(async () => { ); }); -function submissionStatusForUser(userId: number) { +function submissionStatusForUser(userId: string) { return state.statusByUser.find((s) => s.userId === userId); } diff --git a/client/src/pages/cockpit/assignmentsPage/AssignmentSubmissionProgress.vue b/client/src/pages/cockpit/assignmentsPage/AssignmentSubmissionProgress.vue index 13f20597..1cda4f89 100644 --- a/client/src/pages/cockpit/assignmentsPage/AssignmentSubmissionProgress.vue +++ b/client/src/pages/cockpit/assignmentsPage/AssignmentSubmissionProgress.vue @@ -26,7 +26,7 @@ const state = reactive({ statusByUser: [] as { userStatus: AssignmentCompletionStatus; progressStatus: StatusCountKey; - userId: number; + userId: string; }[], progressStatusCount: {} as StatusCount, }); diff --git a/client/src/pages/cockpit/cockpitPage/CockpitPage.vue b/client/src/pages/cockpit/cockpitPage/CockpitPage.vue index d1630f85..1dc938ef 100644 --- a/client/src/pages/cockpit/cockpitPage/CockpitPage.vue +++ b/client/src/pages/cockpit/cockpitPage/CockpitPage.vue @@ -26,7 +26,7 @@ const competenceStore = useCompetenceStore(); const learningPathStore = useLearningPathStore(); const courseSession = useCurrentCourseSession(); -function userCountStatusForCircle(userId: number, translationKey: string) { +function userCountStatusForCircle(userId: string, translationKey: string) { const criteria = competenceStore.flatPerformanceCriteria( userId, cockpitStore.selectedCircles diff --git a/client/src/pages/learningPath/learningContentPage/assignment/AssignmentView.vue b/client/src/pages/learningPath/learningContentPage/assignment/AssignmentView.vue index 4456097d..aab338fa 100644 --- a/client/src/pages/learningPath/learningContentPage/assignment/AssignmentView.vue +++ b/client/src/pages/learningPath/learningContentPage/assignment/AssignmentView.vue @@ -188,7 +188,7 @@ const subTitle = computed(() => { const assignmentUser = computed(() => { return courseSession.value.users.find( - (user) => user.user_id === Number(userStore.id) + (user) => user.user_id === userStore.id ) as CourseSessionUser; }); diff --git a/client/src/services/files.ts b/client/src/services/files.ts index f1fc522b..726d1bb2 100644 --- a/client/src/services/files.ts +++ b/client/src/services/files.ts @@ -98,6 +98,6 @@ export async function uploadCircleDocument( return Promise.resolve(newDocument); } -export async function deleteCircleDocument(documentId: number) { +export async function deleteCircleDocument(documentId: string) { return itDelete(`/api/core/document/${documentId}/`); } diff --git a/client/src/services/learningPath.ts b/client/src/services/learningPath.ts index 78e7feed..bd4c6bbb 100644 --- a/client/src/services/learningPath.ts +++ b/client/src/services/learningPath.ts @@ -41,7 +41,7 @@ export class LearningPath implements WagtailLearningPath { public static fromJson( json: WagtailLearningPath, completionData: CourseCompletion[], - userId: number | undefined + userId: string | undefined ): LearningPath { return new LearningPath( json.id, @@ -64,7 +64,7 @@ export class LearningPath implements WagtailLearningPath { public readonly frontend_url: string, public readonly course: Course, public children: LearningPathChild[], - public userId: number | undefined, + public userId: string | undefined, completionData?: CourseCompletion[] ) { // parse children diff --git a/client/src/stores/circle.ts b/client/src/stores/circle.ts index 69eeedd7..8a0e6c41 100644 --- a/client/src/stores/circle.ts +++ b/client/src/stores/circle.ts @@ -41,7 +41,7 @@ export const useCircleStore = defineStore({ async loadCircle( courseSlug: string, circleSlug: string, - userId: number | undefined = undefined + userId: string | undefined = undefined ): Promise { if (!userId) { const userStore = useUserStore(); diff --git a/client/src/stores/competence.ts b/client/src/stores/competence.ts index 5865a9d3..cd190c95 100644 --- a/client/src/stores/competence.ts +++ b/client/src/stores/competence.ts @@ -14,7 +14,7 @@ import orderBy from "lodash/orderBy"; import { defineStore } from "pinia"; export type CompetenceStoreState = { - competenceProfilePages: Map; + competenceProfilePages: Map; selectedCircle: { id: string; name: string }; availableCircles: { id: string; name: string }[]; @@ -24,7 +24,7 @@ export const useCompetenceStore = defineStore({ id: "competence", state: () => { return { - competenceProfilePages: new Map(), + competenceProfilePages: new Map(), selectedCircle: { id: "all", name: "Circle: Alle" }, availableCircles: [], } as CompetenceStoreState; @@ -56,7 +56,7 @@ export const useCompetenceStore = defineStore({ return competence.children; }); }, - competenceProfilePage(userId: number | undefined = undefined) { + competenceProfilePage(userId: string | undefined = undefined) { if (!userId) { const userStore = useUserStore(); userId = userStore.id; @@ -65,7 +65,7 @@ export const useCompetenceStore = defineStore({ return this.competenceProfilePages.get(userId); }, flatPerformanceCriteria( - userId: number | undefined = undefined, + userId: string | undefined = undefined, circleTranslationKeys: string[] | undefined = undefined ) { if (!userId) { @@ -102,7 +102,7 @@ export const useCompetenceStore = defineStore({ return []; }, - competences(userId: number | undefined = undefined) { + competences(userId: string | undefined = undefined) { if (!userId) { const userStore = useUserStore(); userId = userStore.id; @@ -128,7 +128,7 @@ export const useCompetenceStore = defineStore({ }, async loadCompetenceProfilePage( slug: string, - userId: number | undefined = undefined, + userId: string | undefined = undefined, reload = false ) { if (!userId) { @@ -161,7 +161,7 @@ export const useCompetenceStore = defineStore({ return this.competenceProfilePages.get(userId); }, - async parseCompletionData(userId: number) { + async parseCompletionData(userId: string) { const competenceProfilePage = this.competenceProfilePages.get(userId); if (competenceProfilePage) { const completionStore = useCompletionStore(); diff --git a/client/src/stores/completion.ts b/client/src/stores/completion.ts index 4bc82f75..515d392a 100644 --- a/client/src/stores/completion.ts +++ b/client/src/stores/completion.ts @@ -13,7 +13,7 @@ export const useCompletionStore = defineStore({ actions: { async loadCourseSessionCompletionData( courseSessionId: number, - userId: number, + userId: string, reload = false ) { const userCompletionData = (await itGetCached( @@ -30,7 +30,7 @@ export const useCompletionStore = defineStore({ }, async markPage( page: BaseCourseWagtailPage, - userId: number | undefined = undefined, + userId: string | undefined = undefined, courseSessionId: number | undefined = undefined ) { if (!courseSessionId) { diff --git a/client/src/stores/courseSessions.ts b/client/src/stores/courseSessions.ts index ada625f0..0f1664b8 100644 --- a/client/src/stores/courseSessions.ts +++ b/client/src/stores/courseSessions.ts @@ -213,7 +213,7 @@ export const useCourseSessionsStore = defineStore("courseSessions", () => { }); } - async function removeDocument(documentId: number) { + async function removeDocument(documentId: string) { await deleteCircleDocument(documentId); if (currentCourseSession.value === undefined) { diff --git a/client/src/stores/learningPath.ts b/client/src/stores/learningPath.ts index 97e3bf7e..84dba48a 100644 --- a/client/src/stores/learningPath.ts +++ b/client/src/stores/learningPath.ts @@ -43,7 +43,7 @@ export const useLearningPathStore = defineStore("learningPath", () => { async function loadCourseSessionCompletionData( courseSlug: string, - userId: number | undefined = undefined + userId: string | undefined = undefined ) { // FIXME: should not be here anymore with VBV-305 const completionStore = useCompletionStore(); @@ -66,7 +66,7 @@ export const useLearningPathStore = defineStore("learningPath", () => { async function loadLearningPath( slug: string, - userId: number | undefined = undefined, + userId: string | undefined = undefined, reload = false, fail = true ) { diff --git a/client/src/stores/user.ts b/client/src/stores/user.ts index e39549e2..7c2eee33 100644 --- a/client/src/stores/user.ts +++ b/client/src/stores/user.ts @@ -19,7 +19,7 @@ if (import.meta.env.VITE_OAUTH_API_BASE_URL) { export type AvailableLanguages = "de" | "fr" | "it"; export type UserState = { - id: number; + id: string; first_name: string; last_name: string; email: string; @@ -50,7 +50,7 @@ for (const language of languagesWithoutCountryCode) { } const initialUserState: UserState = { - id: 0, + id: "", email: "", first_name: "", last_name: "", diff --git a/client/src/types.ts b/client/src/types.ts index e354fedf..1982b820 100644 --- a/client/src/types.ts +++ b/client/src/types.ts @@ -170,7 +170,7 @@ export interface Topic extends BaseCourseWagtailPage { export type LearningPathChild = Topic | WagtailCircle; export interface CourseCompletion { - readonly id: number; + readonly id: string; created_at: string; updated_at: string; readonly user: number; @@ -181,17 +181,6 @@ export interface CourseCompletion { additional_json_data: unknown; } -export interface CircleDiagramData { - index: number; - title: string; - icon: string; - startAngle: number; - endAngle: number; - arrowStartAngle: number; - arrowEndAngle: number; - done: boolean; -} - export interface Course { id: number; title: string; @@ -394,7 +383,7 @@ export interface DropdownSelectable { } export interface CircleExpert { - user_id: number; + user_id: string; user_email: string; user_first_name: string; user_last_name: string; @@ -404,7 +393,7 @@ export interface CircleExpert { } export interface CircleDocument { - id: number; + id: string; name: string; file_name: string; url: string; @@ -457,7 +446,7 @@ export type Role = "MEMBER" | "EXPERT" | "TUTOR"; export interface CourseSessionUser { session_title: string; - user_id: number; + user_id: string; first_name: string; last_name: string; email: string; @@ -491,7 +480,7 @@ export type NotificationType = "USER_INTERACTION" | "PROGRESS" | "INFORMATION"; export interface Notification { // given by AbstractNotification model - id: number; + id: string; timestamp: string; unread: boolean; actor: string | null; @@ -532,16 +521,16 @@ export interface AssignmentCompletionData { } export interface AssignmentCompletion { - id: number; + id: string; created_at: string; updated_at: string; submitted_at: string; evaluation_submitted_at: string | null; - assignment_user: number; + assignment_user: string; assignment: number; course_session: number; completion_status: AssignmentCompletionStatus; - evaluation_user: number | null; + evaluation_user: string | null; completion_data: AssignmentCompletionData; evaluation_grade: number | null; } @@ -554,14 +543,14 @@ export type UpsertUserAssignmentCompletion = { }; export type EvaluationCompletionData = UpsertUserAssignmentCompletion & { - assignment_user_id: number; + assignment_user_id: string; evaluation_grade?: number; evaluation_points?: number; }; export interface UserAssignmentCompletionStatus { - id: number; - assignment_user_id: number; + id: string; + assignment_user_id: string; completion_status: AssignmentCompletionStatus; evaluation_grade: number | null; } diff --git a/server/config/urls.py b/server/config/urls.py index b0912a61..30d1ecbb 100644 --- a/server/config/urls.py +++ b/server/config/urls.py @@ -10,6 +10,9 @@ from django.views import defaults as default_views from django.views.decorators.csrf import csrf_exempt from graphene_django.views import GraphQLView from ratelimit.exceptions import Ratelimited +from wagtail import urls as wagtail_urls +from wagtail.admin import urls as wagtailadmin_urls +from wagtail.documents import urls as wagtaildocs_urls from vbv_lernwelt.assignment.views import request_assignment_completion_status from vbv_lernwelt.core.middleware.auth import django_view_authentication_exempt @@ -42,9 +45,6 @@ from vbv_lernwelt.feedback.views import ( get_feedback_for_circle, ) from vbv_lernwelt.notify.views import email_notification_settings -from wagtail import urls as wagtail_urls -from wagtail.admin import urls as wagtailadmin_urls -from wagtail.documents import urls as wagtaildocs_urls class SignedIntConverter(IntConverter): @@ -109,7 +109,7 @@ urlpatterns = [ path(r"api/course/completion//", request_course_completion, name="request_course_completion"), - path(r"api/course/completion///", + path(r"api/course/completion///", request_course_completion_for_user, name="request_course_completion_for_user"),