diff --git a/client/src/gql/gql.ts b/client/src/gql/gql.ts index d7be8c29..679e7998 100644 --- a/client/src/gql/gql.ts +++ b/client/src/gql/gql.ts @@ -14,8 +14,8 @@ import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document- */ const documents = { "\n mutation SendFeedbackMutation($input: SendFeedbackInput!) {\n send_feedback(input: $input) {\n feedback_response {\n id\n }\n errors {\n field\n messages\n }\n }\n }\n": types.SendFeedbackMutationDocument, - "\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: ID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationGrade: Float\n $evaluationPoints: Float\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_grade: $evaluationGrade\n evaluation_points: $evaluationPoints\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n }\n": types.UpsertAssignmentCompletionDocument, - "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: ID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n": types.AssignmentCompletionQueryDocument, + "\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationGrade: Float\n $evaluationPoints: Float\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_grade: $evaluationGrade\n evaluation_points: $evaluationPoints\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n }\n": types.UpsertAssignmentCompletionDocument, + "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n": types.AssignmentCompletionQueryDocument, "\n query courseQuery($courseId: Int!) {\n course(id: $courseId) {\n id\n slug\n title\n category_name\n learning_path {\n id\n }\n }\n }\n": types.CourseQueryDocument, }; @@ -40,11 +40,11 @@ export function graphql(source: "\n mutation SendFeedbackMutation($input: SendF /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: ID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationGrade: Float\n $evaluationPoints: Float\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_grade: $evaluationGrade\n evaluation_points: $evaluationPoints\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n }\n"): (typeof documents)["\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: ID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationGrade: Float\n $evaluationPoints: Float\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_grade: $evaluationGrade\n evaluation_points: $evaluationPoints\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n }\n"]; +export function graphql(source: "\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationGrade: Float\n $evaluationPoints: Float\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_grade: $evaluationGrade\n evaluation_points: $evaluationPoints\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n }\n"): (typeof documents)["\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationGrade: Float\n $evaluationPoints: Float\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_grade: $evaluationGrade\n evaluation_points: $evaluationPoints\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: ID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n"): (typeof documents)["\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: ID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n"]; +export function graphql(source: "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n"): (typeof documents)["\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/client/src/gql/graphql.ts b/client/src/gql/graphql.ts index 606269c6..f0e7a382 100644 --- a/client/src/gql/graphql.ts +++ b/client/src/gql/graphql.ts @@ -34,6 +34,11 @@ export type Scalars = { * schema (one of the key benefits of GraphQL). */ JSONString: { input: any; output: any; } + /** + * Leverages the internal Python implementation of UUID (uuid.UUID) to provide native UUID objects + * in fields, resolvers and input. + */ + UUID: { input: any; output: any; } }; /** An enumeration. */ @@ -73,7 +78,7 @@ export type AssignmentCompletionObjectType = { evaluation_points?: Maybe; evaluation_submitted_at?: Maybe; evaluation_user?: Maybe; - id: Scalars['ID']['output']; + id: Scalars['UUID']['output']; learning_content_page_id?: Maybe; submitted_at?: Maybe; updated_at: Scalars['DateTime']['output']; @@ -116,7 +121,7 @@ export type AttendanceCourseUserMutation = { export type AttendanceUserInputType = { status: AttendanceUserStatus; - user_id: Scalars['ID']['input']; + user_id: Scalars['UUID']['input']; }; /** An enumeration. */ @@ -130,7 +135,7 @@ export type AttendanceUserType = { first_name?: Maybe; last_name?: Maybe; status: AttendanceUserStatus; - user_id: Scalars['ID']['output']; + user_id: Scalars['UUID']['output']; }; /** An enumeration. */ @@ -242,7 +247,7 @@ export type MutationUpdateCourseSessionAttendanceCourseUsersArgs = { export type MutationUpsertAssignmentCompletionArgs = { assignment_id: Scalars['ID']['input']; - assignment_user_id?: InputMaybe; + assignment_user_id?: InputMaybe; completion_data_string?: InputMaybe; completion_status?: InputMaybe; course_session_id: Scalars['ID']['input']; @@ -274,7 +279,7 @@ export type QueryAssignmentArgs = { export type QueryAssignmentCompletionArgs = { assignment_id: Scalars['ID']['input']; - assignment_user_id?: InputMaybe; + assignment_user_id?: InputMaybe; course_session_id: Scalars['ID']['input']; learning_content_page_id?: InputMaybe; }; @@ -310,7 +315,7 @@ export type UserType = { avatar_url: Scalars['String']['output']; email: Scalars['String']['output']; first_name: Scalars['String']['output']; - id: Scalars['ID']['output']; + id: Scalars['UUID']['output']; language: CoreUserLanguageChoices; last_name: Scalars['String']['output']; /** Erforderlich. 150 Zeichen oder weniger. Nur Buchstaben, Ziffern und @/./+/-/_. */ @@ -328,7 +333,7 @@ export type UpsertAssignmentCompletionMutationVariables = Exact<{ assignmentId: Scalars['ID']['input']; courseSessionId: Scalars['ID']['input']; learningContentId?: InputMaybe; - assignmentUserId?: InputMaybe; + assignmentUserId?: InputMaybe; completionStatus: AssignmentCompletionStatus; completionDataString: Scalars['String']['input']; evaluationGrade?: InputMaybe; @@ -336,17 +341,17 @@ export type UpsertAssignmentCompletionMutationVariables = Exact<{ }>; -export type UpsertAssignmentCompletionMutation = { __typename?: 'Mutation', upsert_assignment_completion?: { __typename?: 'AssignmentCompletionMutation', assignment_completion?: { __typename?: 'AssignmentCompletionObjectType', id: string, completion_status: AssignmentAssignmentCompletionCompletionStatusChoices, submitted_at?: any | null, evaluation_submitted_at?: any | null, evaluation_grade?: number | null, evaluation_points?: number | null, completion_data?: any | null } | null } | null }; +export type UpsertAssignmentCompletionMutation = { __typename?: 'Mutation', upsert_assignment_completion?: { __typename?: 'AssignmentCompletionMutation', assignment_completion?: { __typename?: 'AssignmentCompletionObjectType', id: any, completion_status: AssignmentAssignmentCompletionCompletionStatusChoices, submitted_at?: any | null, evaluation_submitted_at?: any | null, evaluation_grade?: number | null, evaluation_points?: number | null, completion_data?: any | null } | null } | null }; export type AssignmentCompletionQueryQueryVariables = Exact<{ assignmentId: Scalars['ID']['input']; courseSessionId: Scalars['ID']['input']; learningContentId?: InputMaybe; - assignmentUserId?: InputMaybe; + assignmentUserId?: InputMaybe; }>; -export type AssignmentCompletionQueryQuery = { __typename?: 'Query', assignment?: { __typename?: 'AssignmentObjectType', assignment_type: AssignmentAssignmentAssignmentTypeChoices, content_type?: string | null, effort_required: string, evaluation_description: string, evaluation_document_url: string, evaluation_tasks?: any | null, id?: string | null, intro_text: string, performance_objectives?: any | null, slug?: string | null, tasks?: any | null, title?: string | null, translation_key?: string | null } | null, assignment_completion?: { __typename?: 'AssignmentCompletionObjectType', id: string, completion_status: AssignmentAssignmentCompletionCompletionStatusChoices, submitted_at?: any | null, evaluation_submitted_at?: any | null, evaluation_grade?: number | null, evaluation_points?: number | null, completion_data?: any | null, evaluation_user?: { __typename?: 'UserType', id: string } | null, assignment_user: { __typename?: 'UserType', id: string } } | null }; +export type AssignmentCompletionQueryQuery = { __typename?: 'Query', assignment?: { __typename?: 'AssignmentObjectType', assignment_type: AssignmentAssignmentAssignmentTypeChoices, content_type?: string | null, effort_required: string, evaluation_description: string, evaluation_document_url: string, evaluation_tasks?: any | null, id?: string | null, intro_text: string, performance_objectives?: any | null, slug?: string | null, tasks?: any | null, title?: string | null, translation_key?: string | null } | null, assignment_completion?: { __typename?: 'AssignmentCompletionObjectType', id: any, completion_status: AssignmentAssignmentCompletionCompletionStatusChoices, submitted_at?: any | null, evaluation_submitted_at?: any | null, evaluation_grade?: number | null, evaluation_points?: number | null, completion_data?: any | null, evaluation_user?: { __typename?: 'UserType', id: any } | null, assignment_user: { __typename?: 'UserType', id: any } } | null }; export type CourseQueryQueryVariables = Exact<{ courseId: Scalars['Int']['input']; @@ -357,6 +362,6 @@ export type CourseQueryQuery = { __typename?: 'Query', course?: { __typename?: ' export const SendFeedbackMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SendFeedbackMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"SendFeedbackInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"send_feedback"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"feedback_response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"errors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"field"}},{"kind":"Field","name":{"kind":"Name","value":"messages"}}]}}]}}]}}]} as unknown as DocumentNode; -export const UpsertAssignmentCompletionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpsertAssignmentCompletion"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"completionStatus"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AssignmentCompletionStatus"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"completionDataString"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"evaluationGrade"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"evaluationPoints"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"upsert_assignment_completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"assignment_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"assignment_user_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}}},{"kind":"Argument","name":{"kind":"Name","value":"completion_status"},"value":{"kind":"Variable","name":{"kind":"Name","value":"completionStatus"}}},{"kind":"Argument","name":{"kind":"Name","value":"completion_data_string"},"value":{"kind":"Variable","name":{"kind":"Name","value":"completionDataString"}}},{"kind":"Argument","name":{"kind":"Name","value":"evaluation_grade"},"value":{"kind":"Variable","name":{"kind":"Name","value":"evaluationGrade"}}},{"kind":"Argument","name":{"kind":"Name","value":"evaluation_points"},"value":{"kind":"Variable","name":{"kind":"Name","value":"evaluationPoints"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment_completion"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_grade"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"completion_data"}}]}}]}}]}}]} as unknown as DocumentNode; -export const AssignmentCompletionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"assignmentCompletionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment_type"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"effort_required"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_description"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_document_url"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_tasks"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"intro_text"}},{"kind":"Field","name":{"kind":"Name","value":"performance_objectives"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"tasks"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"translation_key"}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"assignment_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"assignment_user_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_grade"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"completion_data"}}]}}]}}]} as unknown as DocumentNode; +export const UpsertAssignmentCompletionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpsertAssignmentCompletion"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"completionStatus"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AssignmentCompletionStatus"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"completionDataString"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"evaluationGrade"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"evaluationPoints"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"upsert_assignment_completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"assignment_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"assignment_user_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}}},{"kind":"Argument","name":{"kind":"Name","value":"completion_status"},"value":{"kind":"Variable","name":{"kind":"Name","value":"completionStatus"}}},{"kind":"Argument","name":{"kind":"Name","value":"completion_data_string"},"value":{"kind":"Variable","name":{"kind":"Name","value":"completionDataString"}}},{"kind":"Argument","name":{"kind":"Name","value":"evaluation_grade"},"value":{"kind":"Variable","name":{"kind":"Name","value":"evaluationGrade"}}},{"kind":"Argument","name":{"kind":"Name","value":"evaluation_points"},"value":{"kind":"Variable","name":{"kind":"Name","value":"evaluationPoints"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment_completion"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_grade"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"completion_data"}}]}}]}}]}}]} as unknown as DocumentNode; +export const AssignmentCompletionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"assignmentCompletionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment_type"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"effort_required"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_description"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_document_url"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_tasks"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"intro_text"}},{"kind":"Field","name":{"kind":"Name","value":"performance_objectives"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"tasks"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"translation_key"}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"assignment_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"assignment_user_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_grade"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"completion_data"}}]}}]}}]} as unknown as DocumentNode; export const CourseQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"courseQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"course"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"category_name"}},{"kind":"Field","name":{"kind":"Name","value":"learning_path"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/client/src/gql/schema.graphql b/client/src/gql/schema.graphql index c83d90ee..15cea857 100644 --- a/client/src/gql/schema.graphql +++ b/client/src/gql/schema.graphql @@ -2,7 +2,7 @@ type Query { course_session_attendance_course(id: ID!, assignment_user_id: ID): CourseSessionAttendanceCourseType course(id: Int): CourseType assignment(id: ID, slug: String): AssignmentObjectType - assignment_completion(assignment_id: ID!, course_session_id: ID!, learning_content_page_id: ID, assignment_user_id: ID): AssignmentCompletionObjectType + assignment_completion(assignment_id: ID!, course_session_id: ID!, learning_content_page_id: ID, assignment_user_id: UUID): AssignmentCompletionObjectType } type CourseSessionAttendanceCourseType { @@ -25,13 +25,19 @@ value as specified by scalar DateTime type AttendanceUserType { - user_id: ID! + user_id: UUID! status: AttendanceUserStatus! first_name: String last_name: String email: String } +""" +Leverages the internal Python implementation of UUID (uuid.UUID) to provide native UUID objects +in fields, resolvers and input. +""" +scalar UUID + """An enumeration.""" enum AttendanceUserStatus { PRESENT @@ -98,14 +104,13 @@ interface CoursePageInterface { } type UserType { - id: ID! - """ Erforderlich. 150 Zeichen oder weniger. Nur Buchstaben, Ziffern und @/./+/-/_. """ username: String! first_name: String! last_name: String! + id: UUID! avatar_url: String! email: String! language: CoreUserLanguageChoices! @@ -164,7 +169,7 @@ enum AssignmentAssignmentAssignmentTypeChoices { scalar JSONStreamField type AssignmentCompletionObjectType { - id: ID! + id: UUID! created_at: DateTime! updated_at: DateTime! submitted_at: DateTime @@ -213,7 +218,7 @@ scalar JSONString type Mutation { send_feedback(input: SendFeedbackInput!): SendFeedbackPayload update_course_session_attendance_course_users(attendance_user_list: [AttendanceUserInputType]!, id: ID!): AttendanceCourseUserMutation - upsert_assignment_completion(assignment_id: ID!, assignment_user_id: ID, completion_data_string: String, completion_status: AssignmentCompletionStatus, course_session_id: ID!, evaluation_grade: Float, evaluation_points: Float, learning_content_page_id: ID): AssignmentCompletionMutation + upsert_assignment_completion(assignment_id: ID!, assignment_user_id: UUID, completion_data_string: String, completion_status: AssignmentCompletionStatus, course_session_id: ID!, evaluation_grade: Float, evaluation_points: Float, learning_content_page_id: ID): AssignmentCompletionMutation } type SendFeedbackPayload { @@ -254,7 +259,7 @@ type AttendanceCourseUserMutation { } input AttendanceUserInputType { - user_id: ID! + user_id: UUID! status: AttendanceUserStatus! } diff --git a/client/src/gql/typenames.ts b/client/src/gql/typenames.ts index 7743de82..e4fd7627 100644 --- a/client/src/gql/typenames.ts +++ b/client/src/gql/typenames.ts @@ -29,4 +29,5 @@ export const Query = "Query"; export const SendFeedbackInput = "SendFeedbackInput"; export const SendFeedbackPayload = "SendFeedbackPayload"; export const String = "String"; +export const UUID = "UUID"; export const UserType = "UserType"; diff --git a/client/src/graphql/mutations.ts b/client/src/graphql/mutations.ts index 4f0663e8..eb485ac6 100644 --- a/client/src/graphql/mutations.ts +++ b/client/src/graphql/mutations.ts @@ -5,7 +5,7 @@ export const UPSERT_ASSIGNMENT_COMPLETION_MUTATION = graphql(` $assignmentId: ID! $courseSessionId: ID! $learningContentId: ID - $assignmentUserId: ID + $assignmentUserId: UUID $completionStatus: AssignmentCompletionStatus! $completionDataString: String! $evaluationGrade: Float diff --git a/client/src/graphql/queries.ts b/client/src/graphql/queries.ts index b19bc9b0..ac39348a 100644 --- a/client/src/graphql/queries.ts +++ b/client/src/graphql/queries.ts @@ -5,7 +5,7 @@ export const ASSIGNMENT_COMPLETION_QUERY = graphql(` $assignmentId: ID! $courseSessionId: ID! $learningContentId: ID - $assignmentUserId: ID + $assignmentUserId: UUID ) { assignment(id: $assignmentId) { assignment_type 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/cypress/consts.js b/cypress/consts.js index 303130ce..c10d4f95 100644 --- a/cypress/consts.js +++ b/cypress/consts.js @@ -1,8 +1,8 @@ // ids for cypress test data -export const ADMIN_USER_ID = -1; -export const TEST_TRAINER1_USER_ID = -11; -export const TEST_STUDENT1_USER_ID = -21; -export const TEST_STUDENT2_USER_ID = -22; +export const ADMIN_USER_ID = "872efd96-3bd7-4a1e-a239-2d72cad9f604"; +export const TEST_TRAINER1_USER_ID = "b9e71f59-c44f-4290-b93a-9b3151e9a2fc"; +export const TEST_STUDENT1_USER_ID = "65c73ad0-6d53-43a9-a4a4-64143f27b03a"; +export const TEST_STUDENT2_USER_ID = "19c40d94-15cc-4198-aaad-ef707c4b0900"; export const TEST_COURSE_SESSION_BERN_ID = -1; export const TEST_COURSE_SESSION_ZURICH_ID = -2; diff --git a/cypress/support/commands.js b/cypress/support/commands.js index 8c7c5821..fde5a99c 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -80,7 +80,13 @@ Cypress.Commands.add("manageShellCommand", (command) => { return cy.manageCommand(`shell -c '${command}'`); }); -function loadObjectJson(key, value, djangoModelPath, serializerModelPath) { +function loadObjectJson( + key, + value, + djangoModelPath, + serializerModelPath, + valueAsString = false +) { const djangoModel = _.last(djangoModelPath.split(".")); const djangoModelImportPath = _.initial(djangoModelPath.split(".")).join("."); const serializerModel = _.last(serializerModelPath.split(".")); @@ -89,10 +95,18 @@ function loadObjectJson(key, value, djangoModelPath, serializerModelPath) { ).join("."); let filterPart = `${key}=${value}`; + if (valueAsString) { + filterPart = `${key}=\\"${value}\\"`; + } + if (_.isArray(key)) { filterPart = _.zip(key, value) .map(([k, v]) => { - return `${k}=${v}`; + if (valueAsString) { + return `${k}=\\"${v}\\"`; + } else { + return `${k}=${v}`; + } }) .join(","); } @@ -116,7 +130,8 @@ Cypress.Commands.add("loadAssignmentCompletion", (key, value) => { key, value, "vbv_lernwelt.assignment.models.AssignmentCompletion", - "vbv_lernwelt.assignment.serializers.AssignmentCompletionSerializer" + "vbv_lernwelt.assignment.serializers.AssignmentCompletionSerializer", + true ); }); @@ -136,15 +151,6 @@ Cypress.Commands.add("makeSelfEvaluation", (answers) => { } }); -// Cypress.Commands.add('loadApiClientRequestResponseLog', (key, value) => { -// return loadObjectJson( -// key, -// value, -// 'myservice.apps.apiclient.models.ApiClientRequestResponseLog', -// 'myservice.apps.apiclient.serializers.ApiClientRequestResponseLogSerializer' -// ); -// }); - Cypress.Commands.add("learningContentMultiLayoutNextStep", () => { return cy.get('[data-cy="next-step"]').click({ force: true }); }); diff --git a/server/config/urls.py b/server/config/urls.py index b0912a61..00ea7d18 100644 --- a/server/config/urls.py +++ b/server/config/urls.py @@ -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"), diff --git a/server/vbv_lernwelt/assignment/graphql/mutations.py b/server/vbv_lernwelt/assignment/graphql/mutations.py index 1385bc24..038d355b 100644 --- a/server/vbv_lernwelt/assignment/graphql/mutations.py +++ b/server/vbv_lernwelt/assignment/graphql/mutations.py @@ -22,7 +22,7 @@ class AssignmentCompletionMutation(graphene.Mutation): assignment_id = graphene.ID(required=True) course_session_id = graphene.ID(required=True) learning_content_page_id = graphene.ID() - assignment_user_id = graphene.ID() + assignment_user_id = graphene.UUID() completion_status = graphene.Argument( graphene.Enum.from_enum(AssignmentCompletionStatus) diff --git a/server/vbv_lernwelt/assignment/graphql/queries.py b/server/vbv_lernwelt/assignment/graphql/queries.py index 86c6ce57..035e478f 100644 --- a/server/vbv_lernwelt/assignment/graphql/queries.py +++ b/server/vbv_lernwelt/assignment/graphql/queries.py @@ -24,7 +24,7 @@ class AssignmentQuery(object): assignment_id=graphene.ID(required=True), course_session_id=graphene.ID(required=True), learning_content_page_id=graphene.ID(required=False), - assignment_user_id=graphene.ID(required=False), + assignment_user_id=graphene.UUID(required=False), ) def resolve_assignment_completion( diff --git a/server/vbv_lernwelt/assignment/migrations/0001_initial.py b/server/vbv_lernwelt/assignment/migrations/0001_initial.py index c40d150d..426909d4 100644 --- a/server/vbv_lernwelt/assignment/migrations/0001_initial.py +++ b/server/vbv_lernwelt/assignment/migrations/0001_initial.py @@ -1,4 +1,6 @@ -# Generated by Django 3.2.13 on 2023-05-12 15:29 +# Generated by Django 3.2.13 on 2023-07-14 12:28 + +import uuid import django.db.models.deletion import wagtail.blocks @@ -7,6 +9,7 @@ from django.db import migrations, models class Migration(migrations.Migration): + initial = True dependencies = [ @@ -28,6 +31,18 @@ class Migration(migrations.Migration): to="wagtailcore.page", ), ), + ( + "assignment_type", + models.CharField( + choices=[ + ("CASEWORK", "CASEWORK"), + ("PREP_ASSIGNMENT", "PREP_ASSIGNMENT"), + ("REFLECTION", "REFLECTION"), + ], + default="CASEWORK", + max_length=50, + ), + ), ( "intro_text", wagtail.fields.RichTextField( @@ -222,11 +237,11 @@ class Migration(migrations.Migration): fields=[ ( "id", - models.BigAutoField( - auto_created=True, + models.UUIDField( + default=uuid.uuid4, + editable=False, primary_key=True, serialize=False, - verbose_name="ID", ), ), ("created_at", models.DateTimeField(auto_now_add=True)), @@ -292,10 +307,10 @@ class Migration(migrations.Migration): "completion_status", models.CharField( choices=[ - (1, "IN_PROGRESS"), - (2, "SUBMITTED"), - (3, "EVALUATION_IN_PROGRESS"), - (4, "EVALUATION_SUBMITTED"), + ("IN_PROGRESS", "IN_PROGRESS"), + ("SUBMITTED", "SUBMITTED"), + ("EVALUATION_IN_PROGRESS", "EVALUATION_IN_PROGRESS"), + ("EVALUATION_SUBMITTED", "EVALUATION_SUBMITTED"), ], default="IN_PROGRESS", max_length=255, diff --git a/server/vbv_lernwelt/assignment/migrations/0002_assignmentcompletionauditlog_assignment_user.py b/server/vbv_lernwelt/assignment/migrations/0002_assignmentcompletionauditlog_assignment_user.py index 2d2828f4..261ddcf8 100644 --- a/server/vbv_lernwelt/assignment/migrations/0002_assignmentcompletionauditlog_assignment_user.py +++ b/server/vbv_lernwelt/assignment/migrations/0002_assignmentcompletionauditlog_assignment_user.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.13 on 2023-05-12 15:29 +# Generated by Django 3.2.13 on 2023-07-14 12:28 import django.db.models.deletion from django.conf import settings @@ -10,8 +10,8 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ("assignment", "0001_initial"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("assignment", "0001_initial"), ] operations = [ diff --git a/server/vbv_lernwelt/assignment/migrations/0003_initial.py b/server/vbv_lernwelt/assignment/migrations/0003_initial.py index 570836e8..553a518a 100644 --- a/server/vbv_lernwelt/assignment/migrations/0003_initial.py +++ b/server/vbv_lernwelt/assignment/migrations/0003_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.13 on 2023-05-12 15:29 +# Generated by Django 3.2.13 on 2023-07-14 12:28 import django.db.models.deletion from django.conf import settings @@ -10,9 +10,10 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ("course", "0001_initial"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ("assignment", "0002_assignmentcompletionauditlog_assignment_user"), + ("course", "0001_initial"), + ("wagtailcore", "0083_workflowcontenttype"), ] operations = [ @@ -69,10 +70,28 @@ class Migration(migrations.Migration): to=settings.AUTH_USER_MODEL, ), ), + migrations.AddField( + model_name="assignmentcompletion", + name="learning_content_page", + field=models.ForeignKey( + blank=True, + default=None, + help_text="Page reference mostly needed for 'REFLECTION' assignments", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="wagtailcore.page", + ), + ), migrations.AddConstraint( model_name="assignmentcompletion", constraint=models.UniqueConstraint( - fields=("assignment_user", "assignment", "course_session"), + fields=( + "assignment_user", + "assignment", + "course_session", + "learning_content_page", + ), name="assignment_completion_unique_user_assignment_course_session", ), ), diff --git a/server/vbv_lernwelt/assignment/migrations/0004_assignment_assignment_type.py b/server/vbv_lernwelt/assignment/migrations/0004_assignment_assignment_type.py deleted file mode 100644 index aef726ae..00000000 --- a/server/vbv_lernwelt/assignment/migrations/0004_assignment_assignment_type.py +++ /dev/null @@ -1,26 +0,0 @@ -# Generated by Django 3.2.13 on 2023-05-19 13:43 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("assignment", "0003_initial"), - ] - - operations = [ - migrations.AddField( - model_name="assignment", - name="assignment_type", - field=models.CharField( - choices=[ - ("CASEWORK", "CASEWORK"), - ("PREP_ASSIGNMENT", "PREP_ASSIGNMENT"), - ("REFLECTION", "REFLECTION"), - ], - default="CASEWORK", - max_length=50, - ), - ), - ] diff --git a/server/vbv_lernwelt/assignment/migrations/0005_alter_assignmentcompletionauditlog_completion_status.py b/server/vbv_lernwelt/assignment/migrations/0005_alter_assignmentcompletionauditlog_completion_status.py deleted file mode 100644 index 623e4aa8..00000000 --- a/server/vbv_lernwelt/assignment/migrations/0005_alter_assignmentcompletionauditlog_completion_status.py +++ /dev/null @@ -1,27 +0,0 @@ -# Generated by Django 3.2.13 on 2023-06-28 14:12 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("assignment", "0004_assignment_assignment_type"), - ] - - operations = [ - migrations.AlterField( - model_name="assignmentcompletionauditlog", - name="completion_status", - field=models.CharField( - choices=[ - ("IN_PROGRESS", "IN_PROGRESS"), - ("SUBMITTED", "SUBMITTED"), - ("EVALUATION_IN_PROGRESS", "EVALUATION_IN_PROGRESS"), - ("EVALUATION_SUBMITTED", "EVALUATION_SUBMITTED"), - ], - default="IN_PROGRESS", - max_length=255, - ), - ), - ] diff --git a/server/vbv_lernwelt/assignment/migrations/0006_auto_20230628_1616.py b/server/vbv_lernwelt/assignment/migrations/0006_auto_20230628_1616.py deleted file mode 100644 index e2a094bc..00000000 --- a/server/vbv_lernwelt/assignment/migrations/0006_auto_20230628_1616.py +++ /dev/null @@ -1,37 +0,0 @@ -# Generated by Django 3.2.13 on 2023-06-28 14:16 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("learnpath", "0007_learningunit_title_hidden"), - ("assignment", "0005_alter_assignmentcompletionauditlog_completion_status"), - ] - - operations = [ - migrations.RemoveConstraint( - model_name="assignmentcompletion", - name="assignment_completion_unique_user_assignment_course_session", - ), - migrations.AddField( - model_name="assignmentcompletion", - name="circle", - field=models.ForeignKey( - blank=True, - default=None, - null=True, - on_delete=django.db.models.deletion.CASCADE, - to="learnpath.circle", - ), - ), - migrations.AddConstraint( - model_name="assignmentcompletion", - constraint=models.UniqueConstraint( - fields=("assignment_user", "assignment", "course_session", "circle"), - name="assignment_completion_unique_user_assignment_course_session", - ), - ), - ] diff --git a/server/vbv_lernwelt/assignment/migrations/0007_auto_20230712_1649.py b/server/vbv_lernwelt/assignment/migrations/0007_auto_20230712_1649.py deleted file mode 100644 index e64815ac..00000000 --- a/server/vbv_lernwelt/assignment/migrations/0007_auto_20230712_1649.py +++ /dev/null @@ -1,48 +0,0 @@ -# Generated by Django 3.2.13 on 2023-07-12 14:49 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("wagtailcore", "0083_workflowcontenttype"), - ("assignment", "0006_auto_20230628_1616"), - ] - - operations = [ - migrations.RemoveConstraint( - model_name="assignmentcompletion", - name="assignment_completion_unique_user_assignment_course_session", - ), - migrations.RemoveField( - model_name="assignmentcompletion", - name="circle", - ), - migrations.AddField( - model_name="assignmentcompletion", - name="learning_content_page", - field=models.ForeignKey( - blank=True, - default=None, - help_text="Page reference mostly needed for 'REFLECTION' assignments", - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name="+", - to="wagtailcore.page", - ), - ), - migrations.AddConstraint( - model_name="assignmentcompletion", - constraint=models.UniqueConstraint( - fields=( - "assignment_user", - "assignment", - "course_session", - "learning_content_page", - ), - name="assignment_completion_unique_user_assignment_course_session", - ), - ), - ] diff --git a/server/vbv_lernwelt/assignment/models.py b/server/vbv_lernwelt/assignment/models.py index ae142063..407808d2 100644 --- a/server/vbv_lernwelt/assignment/models.py +++ b/server/vbv_lernwelt/assignment/models.py @@ -1,3 +1,4 @@ +import uuid from enum import Enum from django.db import models @@ -252,6 +253,8 @@ def is_valid_assignment_completion_status( class AssignmentCompletion(models.Model): + id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) diff --git a/server/vbv_lernwelt/assignment/tests/test_graphql.py b/server/vbv_lernwelt/assignment/tests/test_graphql.py index 6c8bf3ad..036d28e2 100644 --- a/server/vbv_lernwelt/assignment/tests/test_graphql.py +++ b/server/vbv_lernwelt/assignment/tests/test_graphql.py @@ -224,7 +224,7 @@ class AttendanceCourseUserMutationTestCase(GraphQLTestCase): mutation {{ upsert_assignment_completion( assignment_id: {self.assignment.id} - assignment_user_id: {self.student.id} + assignment_user_id: "{self.student.id}" course_session_id: {self.course_session.id} completion_status: EVALUATION_IN_PROGRESS completion_data_string: "{completion_data_string}" @@ -240,6 +240,7 @@ class AttendanceCourseUserMutationTestCase(GraphQLTestCase): }} """ + print(query) response = self.query(query) self.assertResponseNoErrors(response) @@ -289,7 +290,7 @@ class AttendanceCourseUserMutationTestCase(GraphQLTestCase): mutation {{ upsert_assignment_completion( assignment_id: {self.assignment.id} - assignment_user_id: {self.student.id} + assignment_user_id: "{self.student.id}" course_session_id: {self.course_session.id} completion_status: EVALUATION_SUBMITTED completion_data_string: "{completion_data_string}" diff --git a/server/vbv_lernwelt/competence/migrations/0001_initial.py b/server/vbv_lernwelt/competence/migrations/0001_initial.py index e282a6b0..a857392c 100644 --- a/server/vbv_lernwelt/competence/migrations/0001_initial.py +++ b/server/vbv_lernwelt/competence/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.13 on 2023-05-12 15:29 +# Generated by Django 3.2.13 on 2023-07-14 12:28 import django.db.models.deletion import wagtail.blocks @@ -77,6 +77,11 @@ class Migration(migrations.Migration): ), ), ("competence_id", models.TextField(default="A1.1")), + ("has_course_completion_status", models.BooleanField(default=True)), + ( + "can_user_self_toggle_course_completion", + models.BooleanField(default=True), + ), ], options={ "abstract": False, diff --git a/server/vbv_lernwelt/competence/migrations/0002_performancecriteria_learning_unit.py b/server/vbv_lernwelt/competence/migrations/0002_performancecriteria_learning_unit.py index 0278879a..890ac6c1 100644 --- a/server/vbv_lernwelt/competence/migrations/0002_performancecriteria_learning_unit.py +++ b/server/vbv_lernwelt/competence/migrations/0002_performancecriteria_learning_unit.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.13 on 2023-05-12 15:29 +# Generated by Django 3.2.13 on 2023-07-14 12:28 import django.db.models.deletion from django.db import migrations, models diff --git a/server/vbv_lernwelt/competence/migrations/0003_auto_20230626_1747.py b/server/vbv_lernwelt/competence/migrations/0003_auto_20230626_1747.py deleted file mode 100644 index d359769b..00000000 --- a/server/vbv_lernwelt/competence/migrations/0003_auto_20230626_1747.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 3.2.13 on 2023-06-26 15:47 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("competence", "0002_performancecriteria_learning_unit"), - ] - - operations = [ - migrations.AddField( - model_name="performancecriteria", - name="can_user_self_toggle_course_completion", - field=models.BooleanField(default=True), - ), - migrations.AddField( - model_name="performancecriteria", - name="has_course_completion_status", - field=models.BooleanField(default=True), - ), - ] diff --git a/server/vbv_lernwelt/contrib/sites/migrations/0001_initial.py b/server/vbv_lernwelt/contrib/sites/migrations/0001_initial.py index 59647c85..297ae556 100644 --- a/server/vbv_lernwelt/contrib/sites/migrations/0001_initial.py +++ b/server/vbv_lernwelt/contrib/sites/migrations/0001_initial.py @@ -1,9 +1,13 @@ +# Generated by Django 3.2.13 on 2023-07-14 12:28 + import django.contrib.sites.models -from django.contrib.sites.models import _simple_domain_name_validator from django.db import migrations, models class Migration(migrations.Migration): + + initial = True + dependencies = [] operations = [ @@ -13,29 +17,33 @@ class Migration(migrations.Migration): ( "id", models.AutoField( - verbose_name="ID", - serialize=False, auto_created=True, primary_key=True, + serialize=False, + verbose_name="ID", ), ), ( "domain", models.CharField( max_length=100, + unique=True, + validators=[ + django.contrib.sites.models._simple_domain_name_validator + ], verbose_name="domain name", - validators=[_simple_domain_name_validator], ), ), ("name", models.CharField(max_length=50, verbose_name="display name")), ], options={ - "ordering": ("domain",), - "db_table": "django_site", "verbose_name": "site", "verbose_name_plural": "sites", + "db_table": "django_site", + "ordering": ["domain"], }, - bases=(models.Model,), - managers=[("objects", django.contrib.sites.models.SiteManager())], - ) + managers=[ + ("objects", django.contrib.sites.models.SiteManager()), + ], + ), ] diff --git a/server/vbv_lernwelt/contrib/sites/migrations/0002_alter_domain_unique.py b/server/vbv_lernwelt/contrib/sites/migrations/0002_alter_domain_unique.py deleted file mode 100644 index 4359049f..00000000 --- a/server/vbv_lernwelt/contrib/sites/migrations/0002_alter_domain_unique.py +++ /dev/null @@ -1,19 +0,0 @@ -import django.contrib.sites.models -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [("sites", "0001_initial")] - - operations = [ - migrations.AlterField( - model_name="site", - name="domain", - field=models.CharField( - max_length=100, - unique=True, - validators=[django.contrib.sites.models._simple_domain_name_validator], - verbose_name="domain name", - ), - ) - ] diff --git a/server/vbv_lernwelt/contrib/sites/migrations/0003_set_site_domain_and_name.py b/server/vbv_lernwelt/contrib/sites/migrations/0003_set_site_domain_and_name.py deleted file mode 100644 index b1c98fa7..00000000 --- a/server/vbv_lernwelt/contrib/sites/migrations/0003_set_site_domain_and_name.py +++ /dev/null @@ -1,62 +0,0 @@ -""" -To understand why this file is here, please read: - -http://cookiecutter-django.readthedocs.io/en/latest/faq.html#why-is-there-a-django-contrib-sites-directory-in-cookiecutter-django -""" -from django.conf import settings -from django.db import migrations - - -def _update_or_create_site_with_sequence(site_model, connection, domain, name): - """Update or create the site with default ID and keep the DB sequence in sync.""" - site, created = site_model.objects.update_or_create( - id=settings.SITE_ID, - defaults={ - "domain": domain, - "name": name, - }, - ) - if created: - # We provided the ID explicitly when creating the Site entry, therefore the DB - # sequence to auto-generate them wasn't used and is now out of sync. If we - # don't do anything, we'll get a unique constraint violation the next time a - # site is created. - # To avoid this, we need to manually update DB sequence and make sure it's - # greater than the maximum value. - max_id = site_model.objects.order_by("-id").first().id - with connection.cursor() as cursor: - cursor.execute("SELECT last_value from django_site_id_seq") - (current_id,) = cursor.fetchone() - if current_id <= max_id: - cursor.execute( - "alter sequence django_site_id_seq restart with %s", - [max_id + 1], - ) - - -def update_site_forward(apps, schema_editor): - """Set site domain and name.""" - Site = apps.get_model("sites", "Site") - _update_or_create_site_with_sequence( - Site, - schema_editor.connection, - "vbv-lernwelt.iterativ.ch", - "VBV Lernwelt", - ) - - -def update_site_backward(apps, schema_editor): - """Revert site domain and name to default.""" - Site = apps.get_model("sites", "Site") - _update_or_create_site_with_sequence( - Site, - schema_editor.connection, - "example.com", - "example.com", - ) - - -class Migration(migrations.Migration): - dependencies = [("sites", "0002_alter_domain_unique")] - - operations = [migrations.RunPython(update_site_forward, update_site_backward)] diff --git a/server/vbv_lernwelt/contrib/sites/migrations/0004_alter_options_ordering_domain.py b/server/vbv_lernwelt/contrib/sites/migrations/0004_alter_options_ordering_domain.py deleted file mode 100644 index 095ca009..00000000 --- a/server/vbv_lernwelt/contrib/sites/migrations/0004_alter_options_ordering_domain.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 3.1.7 on 2021-02-04 14:49 - -from django.db import migrations - - -class Migration(migrations.Migration): - dependencies = [ - ("sites", "0003_set_site_domain_and_name"), - ] - - operations = [ - migrations.AlterModelOptions( - name="site", - options={ - "ordering": ["domain"], - "verbose_name": "site", - "verbose_name_plural": "sites", - }, - ), - ] diff --git a/server/vbv_lernwelt/core/constants.py b/server/vbv_lernwelt/core/constants.py index 5ec2388d..d525ee0d 100644 --- a/server/vbv_lernwelt/core/constants.py +++ b/server/vbv_lernwelt/core/constants.py @@ -11,10 +11,10 @@ DEFAULT_RICH_TEXT_FEATURES_WITH_HEADER = [ ] # ids for cypress test data -ADMIN_USER_ID = -1 -TEST_TRAINER1_USER_ID = -11 -TEST_STUDENT1_USER_ID = -21 -TEST_STUDENT2_USER_ID = -22 +ADMIN_USER_ID = "872efd96-3bd7-4a1e-a239-2d72cad9f604" +TEST_TRAINER1_USER_ID = "b9e71f59-c44f-4290-b93a-9b3151e9a2fc" +TEST_STUDENT1_USER_ID = "65c73ad0-6d53-43a9-a4a4-64143f27b03a" +TEST_STUDENT2_USER_ID = "19c40d94-15cc-4198-aaad-ef707c4b0900" TEST_COURSE_SESSION_BERN_ID = -1 TEST_COURSE_SESSION_ZURICH_ID = -2 diff --git a/server/vbv_lernwelt/core/migrations/0001_initial.py b/server/vbv_lernwelt/core/migrations/0001_initial.py index 833238c4..e196649b 100644 --- a/server/vbv_lernwelt/core/migrations/0001_initial.py +++ b/server/vbv_lernwelt/core/migrations/0001_initial.py @@ -1,5 +1,8 @@ -# Generated by Django 3.2.13 on 2023-05-12 15:29 +# Generated by Django 3.2.13 on 2023-07-14 12:28 +import uuid + +import django.contrib.auth.models import django.contrib.auth.validators import django.utils.timezone from django.db import migrations, models @@ -53,15 +56,6 @@ class Migration(migrations.Migration): migrations.CreateModel( name="User", fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), ("password", models.CharField(max_length=128, verbose_name="password")), ( "last_login", @@ -126,9 +120,22 @@ class Migration(migrations.Migration): default=django.utils.timezone.now, verbose_name="date joined" ), ), + ( + "id", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), ( "avatar_url", - models.CharField(blank=True, default="", max_length=254), + models.CharField( + blank=True, + default="/static/avatars/myvbv-default-avatar.png", + max_length=254, + ), ), ( "email", @@ -187,5 +194,8 @@ class Migration(migrations.Migration): "verbose_name_plural": "users", "abstract": False, }, + managers=[ + ("objects", django.contrib.auth.models.UserManager()), + ], ), ] diff --git a/server/vbv_lernwelt/core/migrations/0002_alter_user_managers.py b/server/vbv_lernwelt/core/migrations/0002_alter_user_managers.py deleted file mode 100644 index 3f6b16fe..00000000 --- a/server/vbv_lernwelt/core/migrations/0002_alter_user_managers.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 3.2.13 on 2023-05-31 14:34 - -import django.contrib.auth.models -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("core", "0001_initial"), - ] - - operations = [ - migrations.AlterModelManagers( - name="user", - managers=[ - ("objects", django.contrib.auth.models.UserManager()), - ], - ), - ] diff --git a/server/vbv_lernwelt/core/migrations/0003_alter_user_avatar_url.py b/server/vbv_lernwelt/core/migrations/0003_alter_user_avatar_url.py deleted file mode 100644 index d1e22e74..00000000 --- a/server/vbv_lernwelt/core/migrations/0003_alter_user_avatar_url.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 3.2.13 on 2023-06-02 12:32 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("core", "0002_alter_user_managers"), - ] - - operations = [ - migrations.AlterField( - model_name="user", - name="avatar_url", - field=models.CharField( - blank=True, - default="/static/avatars/myvbv-default-avatar.png", - max_length=254, - ), - ), - ] diff --git a/server/vbv_lernwelt/core/models.py b/server/vbv_lernwelt/core/models.py index c1a09d96..8f8bcb75 100644 --- a/server/vbv_lernwelt/core/models.py +++ b/server/vbv_lernwelt/core/models.py @@ -1,3 +1,5 @@ +import uuid + from django.contrib.auth.models import AbstractUser from django.db import models from django.db.models import JSONField @@ -15,8 +17,8 @@ class User(AbstractUser): ("it", "Italiano"), ) - # FIXME: look into it... - # objects = UserManager() + id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + avatar_url = models.CharField( max_length=254, blank=True, default="/static/avatars/myvbv-default-avatar.png" ) diff --git a/server/vbv_lernwelt/course/migrations/0001_initial.py b/server/vbv_lernwelt/course/migrations/0001_initial.py index 87fba784..730fc62f 100644 --- a/server/vbv_lernwelt/course/migrations/0001_initial.py +++ b/server/vbv_lernwelt/course/migrations/0001_initial.py @@ -1,9 +1,12 @@ -# Generated by Django 3.2.13 on 2023-05-12 15:29 +# Generated by Django 3.2.13 on 2023-07-14 12:28 + +import uuid import django.db.models.deletion -import django_jsonform.models.fields from django.db import migrations, models +import vbv_lernwelt.course.models + class Migration(migrations.Migration): @@ -19,11 +22,11 @@ class Migration(migrations.Migration): fields=[ ( "id", - models.BigAutoField( - auto_created=True, + models.UUIDField( + default=uuid.uuid4, + editable=False, primary_key=True, serialize=False, - verbose_name="ID", ), ), ("created_at", models.DateTimeField(auto_now_add=True)), @@ -93,27 +96,40 @@ class Migration(migrations.Migration): fields=[ ( "id", - models.BigAutoField( - auto_created=True, + models.UUIDField( + default=uuid.uuid4, + editable=False, primary_key=True, serialize=False, - verbose_name="ID", ), ), ("created_at", models.DateTimeField(auto_now_add=True)), ("updated_at", models.DateTimeField(auto_now=True)), - ("page_key", models.UUIDField()), ("page_type", models.CharField(blank=True, default="", max_length=255)), - ("page_slug", models.CharField(blank=True, default="", max_length=255)), ( "completion_status", models.CharField( choices=[ - ("unknown", "unknown"), - ("success", "success"), - ("fail", "fail"), + ( + vbv_lernwelt.course.models.CourseCompletionStatus[ + "SUCCESS" + ], + "SUCCESS", + ), + ( + vbv_lernwelt.course.models.CourseCompletionStatus[ + "FAIL" + ], + "FAIL", + ), + ( + vbv_lernwelt.course.models.CourseCompletionStatus[ + "UNKNOWN" + ], + "UNKNOWN", + ), ], - default="unknown", + default="UNKNOWN", max_length=255, ), ), @@ -154,14 +170,13 @@ class Migration(migrations.Migration): ), ("created_at", models.DateTimeField(auto_now_add=True)), ("updated_at", models.DateTimeField(auto_now=True)), - ("title", models.TextField()), + ("title", models.TextField(unique=True)), + ("import_id", models.TextField(blank=True, default="")), + ("generation", models.TextField(blank=True, default="")), + ("region", models.TextField(blank=True, default="")), + ("group", models.TextField(blank=True, default="")), ("start_date", models.DateField(blank=True, null=True)), ("end_date", models.DateField(blank=True, null=True)), - ( - "attendance_days", - django_jsonform.models.fields.JSONField(blank=True, default=list), - ), - ("assignment_details_list", models.JSONField(blank=True, default=list)), ("additional_json_data", models.JSONField(blank=True, default=dict)), ], ), @@ -170,11 +185,11 @@ class Migration(migrations.Migration): fields=[ ( "id", - models.BigAutoField( - auto_created=True, + models.UUIDField( + default=uuid.uuid4, + editable=False, primary_key=True, serialize=False, - verbose_name="ID", ), ), ("created_at", models.DateTimeField(auto_now_add=True)), diff --git a/server/vbv_lernwelt/course/migrations/0002_initial.py b/server/vbv_lernwelt/course/migrations/0002_initial.py index a9d4b4fe..25a52a56 100644 --- a/server/vbv_lernwelt/course/migrations/0002_initial.py +++ b/server/vbv_lernwelt/course/migrations/0002_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.13 on 2023-05-12 15:29 +# Generated by Django 3.2.13 on 2023-07-14 12:28 import django.db.models.deletion from django.conf import settings @@ -10,9 +10,10 @@ class Migration(migrations.Migration): initial = True dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("wagtailcore", "0083_workflowcontenttype"), ("files", "0001_initial"), ("course", "0001_initial"), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), ("learnpath", "0001_initial"), ] @@ -52,6 +53,13 @@ class Migration(migrations.Migration): on_delete=django.db.models.deletion.CASCADE, to="course.coursesession" ), ), + migrations.AddField( + model_name="coursecompletion", + name="page", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="wagtailcore.page" + ), + ), migrations.AddField( model_name="coursecompletion", name="user", @@ -98,7 +106,7 @@ class Migration(migrations.Migration): migrations.AddConstraint( model_name="coursecompletion", constraint=models.UniqueConstraint( - fields=("user", "page_key", "course_session"), + fields=("user", "page", "course_session"), name="course_completion_unique_user_page_key", ), ), diff --git a/server/vbv_lernwelt/course/migrations/0003_rename_attendance_days_coursesession_attendance_courses.py b/server/vbv_lernwelt/course/migrations/0003_rename_attendance_days_coursesession_attendance_courses.py deleted file mode 100644 index 3b013fb3..00000000 --- a/server/vbv_lernwelt/course/migrations/0003_rename_attendance_days_coursesession_attendance_courses.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.2.13 on 2023-05-23 12:49 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("course", "0002_initial"), - ] - - operations = [ - migrations.RenameField( - model_name="coursesession", - old_name="attendance_days", - new_name="attendance_courses", - ), - ] diff --git a/server/vbv_lernwelt/course/migrations/0004_import_fields.py b/server/vbv_lernwelt/course/migrations/0004_import_fields.py deleted file mode 100644 index cc7f16c7..00000000 --- a/server/vbv_lernwelt/course/migrations/0004_import_fields.py +++ /dev/null @@ -1,38 +0,0 @@ -# Generated by Django 3.2.13 on 2023-05-31 15:59 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("course", "0003_rename_attendance_days_coursesession_attendance_courses"), - ] - - operations = [ - migrations.AddField( - model_name="coursesession", - name="generation", - field=models.TextField(blank=True, default=""), - ), - migrations.AddField( - model_name="coursesession", - name="group", - field=models.TextField(blank=True, default=""), - ), - migrations.AddField( - model_name="coursesession", - name="import_id", - field=models.TextField(blank=True, default=""), - ), - migrations.AddField( - model_name="coursesession", - name="region", - field=models.TextField(blank=True, default=""), - ), - migrations.AlterField( - model_name="coursesession", - name="title", - field=models.TextField(unique=True), - ), - ] diff --git a/server/vbv_lernwelt/course/migrations/0005_remove_coursesession_attendance_courses.py b/server/vbv_lernwelt/course/migrations/0005_remove_coursesession_attendance_courses.py deleted file mode 100644 index f57fc644..00000000 --- a/server/vbv_lernwelt/course/migrations/0005_remove_coursesession_attendance_courses.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 3.2.13 on 2023-06-14 14:02 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("course", "0004_import_fields"), - ] - - operations = [ - migrations.RemoveField( - model_name="coursesession", - name="attendance_courses", - ), - ] diff --git a/server/vbv_lernwelt/course/migrations/0006_auto_20230626_1724.py b/server/vbv_lernwelt/course/migrations/0006_auto_20230626_1724.py deleted file mode 100644 index c2135216..00000000 --- a/server/vbv_lernwelt/course/migrations/0006_auto_20230626_1724.py +++ /dev/null @@ -1,65 +0,0 @@ -# Generated by Django 3.2.13 on 2023-06-26 15:24 - -import django.db.models.deletion -from django.db import migrations, models - -import vbv_lernwelt.course.models - - -class Migration(migrations.Migration): - - dependencies = [ - ("wagtailcore", "0083_workflowcontenttype"), - ("course", "0005_remove_coursesession_attendance_courses"), - ] - - operations = [ - migrations.RemoveConstraint( - model_name="coursecompletion", - name="course_completion_unique_user_page_key", - ), - migrations.RemoveField( - model_name="coursecompletion", - name="page_key", - ), - migrations.RemoveField( - model_name="coursecompletion", - name="page_slug", - ), - migrations.AddField( - model_name="coursecompletion", - name="page", - field=models.ForeignKey( - default=1, - on_delete=django.db.models.deletion.CASCADE, - to="wagtailcore.page", - ), - preserve_default=False, - ), - migrations.AlterField( - model_name="coursecompletion", - name="completion_status", - field=models.CharField( - choices=[ - ( - vbv_lernwelt.course.models.CourseCompletionStatus["SUCCESS"], - "SUCCESS", - ), - (vbv_lernwelt.course.models.CourseCompletionStatus["FAIL"], "FAIL"), - ( - vbv_lernwelt.course.models.CourseCompletionStatus["UNKNOWN"], - "UNKNOWN", - ), - ], - default="UNKNOWN", - max_length=255, - ), - ), - migrations.AddConstraint( - model_name="coursecompletion", - constraint=models.UniqueConstraint( - fields=("user", "page", "course_session"), - name="course_completion_unique_user_page_key", - ), - ), - ] diff --git a/server/vbv_lernwelt/course/migrations/0006_remove_coursesession_assignment_details_list.py b/server/vbv_lernwelt/course/migrations/0006_remove_coursesession_assignment_details_list.py deleted file mode 100644 index b8c3106e..00000000 --- a/server/vbv_lernwelt/course/migrations/0006_remove_coursesession_assignment_details_list.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 3.2.13 on 2023-06-21 14:19 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("course", "0005_remove_coursesession_attendance_courses"), - ] - - operations = [ - migrations.RemoveField( - model_name="coursesession", - name="assignment_details_list", - ), - ] diff --git a/server/vbv_lernwelt/course/migrations/0007_merge_20230711_1108.py b/server/vbv_lernwelt/course/migrations/0007_merge_20230711_1108.py deleted file mode 100644 index 1b1c6991..00000000 --- a/server/vbv_lernwelt/course/migrations/0007_merge_20230711_1108.py +++ /dev/null @@ -1,13 +0,0 @@ -# Generated by Django 3.2.13 on 2023-07-11 09:08 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("course", "0006_auto_20230626_1724"), - ("course", "0006_remove_coursesession_assignment_details_list"), - ] - - operations = [] diff --git a/server/vbv_lernwelt/course/models.py b/server/vbv_lernwelt/course/models.py index c13dbc45..78701ad8 100644 --- a/server/vbv_lernwelt/course/models.py +++ b/server/vbv_lernwelt/course/models.py @@ -1,4 +1,5 @@ import enum +import uuid from django.db import models from django.db.models import UniqueConstraint @@ -161,6 +162,8 @@ class CourseCompletionStatus(enum.Enum): class CourseCompletion(models.Model): + id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) @@ -220,9 +223,11 @@ class CourseSession(models.Model): class CourseSessionUser(models.Model): """ - Ein Benutzer der an einer CourseSession teilnimmt + Ein Benutzer der an einer Durchführung teilnimmt """ + id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) @@ -268,6 +273,8 @@ class CourseSessionUser(models.Model): class CircleDocument(models.Model): + id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + created_at = models.DateTimeField(auto_now_add=True) file = models.OneToOneField(UploadFile, on_delete=models.CASCADE) name = models.CharField(max_length=100) diff --git a/server/vbv_lernwelt/course/serializers.py b/server/vbv_lernwelt/course/serializers.py index 676aeeda..69d326b2 100644 --- a/server/vbv_lernwelt/course/serializers.py +++ b/server/vbv_lernwelt/course/serializers.py @@ -146,4 +146,4 @@ class DocumentUploadStartInputSerializer(serializers.Serializer): class DocumentUploadFinishInputSerializer(serializers.Serializer): - file_id = serializers.IntegerField() + file_id = serializers.UUIDField() diff --git a/server/vbv_lernwelt/course_session/graphql/mutations.py b/server/vbv_lernwelt/course_session/graphql/mutations.py index 64e6c15f..e8bedaac 100644 --- a/server/vbv_lernwelt/course_session/graphql/mutations.py +++ b/server/vbv_lernwelt/course_session/graphql/mutations.py @@ -14,7 +14,7 @@ logger = structlog.get_logger(__name__) class AttendanceUserInputType(graphene.InputObjectType): - user_id = graphene.ID(required=True) + user_id = graphene.UUID(required=True) status = graphene.Field( graphene.Enum.from_enum(AttendanceUserStatus), required=True ) diff --git a/server/vbv_lernwelt/course_session/graphql/types.py b/server/vbv_lernwelt/course_session/graphql/types.py index 36dd82f1..bc1a0f4c 100644 --- a/server/vbv_lernwelt/course_session/graphql/types.py +++ b/server/vbv_lernwelt/course_session/graphql/types.py @@ -6,7 +6,7 @@ from vbv_lernwelt.course_session.services.attendance import AttendanceUserStatus class AttendanceUserType(graphene.ObjectType): - user_id = graphene.ID(required=True) + user_id = graphene.UUID(required=True) status = graphene.Field( graphene.Enum.from_enum(AttendanceUserStatus), required=True ) diff --git a/server/vbv_lernwelt/course_session/migrations/0001_initial.py b/server/vbv_lernwelt/course_session/migrations/0001_initial.py index 6d0ab3fd..a669d2d2 100644 --- a/server/vbv_lernwelt/course_session/migrations/0001_initial.py +++ b/server/vbv_lernwelt/course_session/migrations/0001_initial.py @@ -1,6 +1,7 @@ -# Generated by Django 3.2.13 on 2023-06-14 15:01 +# Generated by Django 3.2.13 on 2023-07-14 12:28 import django.db.models.deletion +import django_jsonform.models.fields from django.db import migrations, models @@ -9,12 +10,24 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ("learnpath", "0007_learningunit_title_hidden"), - ("course", "0005_remove_coursesession_attendance_courses"), - ("duedate", "0002_auto_20230614_1500"), + ("course", "0001_initial"), ] operations = [ + migrations.CreateModel( + name="CourseSessionAssignment", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ], + ), migrations.CreateModel( name="CourseSessionAttendanceCourse", fields=[ @@ -29,6 +42,10 @@ class Migration(migrations.Migration): ), ("location", models.CharField(blank=True, default="", max_length=255)), ("trainer", models.CharField(blank=True, default="", max_length=255)), + ( + "attendance_user_list", + django_jsonform.models.fields.JSONField(default=list), + ), ( "course_session", models.ForeignKey( @@ -36,21 +53,6 @@ class Migration(migrations.Migration): to="course.coursesession", ), ), - ( - "due_date", - models.OneToOneField( - on_delete=django.db.models.deletion.CASCADE, - related_name="attendance_course_due_date", - to="duedate.duedate", - ), - ), - ( - "learning_content", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="learnpath.learningcontentattendancecourse", - ), - ), ], ), ] diff --git a/server/vbv_lernwelt/course_session/migrations/0002_coursesessionassignment.py b/server/vbv_lernwelt/course_session/migrations/0002_coursesessionassignment.py deleted file mode 100644 index 43826084..00000000 --- a/server/vbv_lernwelt/course_session/migrations/0002_coursesessionassignment.py +++ /dev/null @@ -1,61 +0,0 @@ -# Generated by Django 3.2.13 on 2023-06-21 14:19 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("course", "0006_remove_coursesession_assignment_details_list"), - ("learnpath", "0007_learningunit_title_hidden"), - ("duedate", "0003_alter_duedate_course_session"), - ("course_session", "0001_initial"), - ] - - operations = [ - migrations.CreateModel( - name="CourseSessionAssignment", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "course_session", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="course.coursesession", - ), - ), - ( - "evaluation_deadline", - models.OneToOneField( - on_delete=django.db.models.deletion.CASCADE, - related_name="assignment_evaluation_deadline", - to="duedate.duedate", - ), - ), - ( - "learning_content", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="learnpath.learningcontentassignment", - ), - ), - ( - "submission_deadline", - models.OneToOneField( - on_delete=django.db.models.deletion.CASCADE, - related_name="assignment_submission_deadline", - to="duedate.duedate", - ), - ), - ], - ), - ] diff --git a/server/vbv_lernwelt/course_session/migrations/0002_coursesessionattendancecourse_attendance_user_list.py b/server/vbv_lernwelt/course_session/migrations/0002_coursesessionattendancecourse_attendance_user_list.py deleted file mode 100644 index 0fe26463..00000000 --- a/server/vbv_lernwelt/course_session/migrations/0002_coursesessionattendancecourse_attendance_user_list.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.2.13 on 2023-06-23 15:17 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("course_session", "0001_initial"), - ] - - operations = [ - migrations.AddField( - model_name="coursesessionattendancecourse", - name="attendance_user_list", - field=models.JSONField(default=list), - ), - ] diff --git a/server/vbv_lernwelt/course_session/migrations/0002_coursesessionattendancecourse_due_date.py b/server/vbv_lernwelt/course_session/migrations/0002_coursesessionattendancecourse_due_date.py new file mode 100644 index 00000000..dfc7cb7d --- /dev/null +++ b/server/vbv_lernwelt/course_session/migrations/0002_coursesessionattendancecourse_due_date.py @@ -0,0 +1,26 @@ +# Generated by Django 3.2.13 on 2023-07-14 12:28 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ("duedate", "0001_initial"), + ("course_session", "0001_initial"), + ] + + operations = [ + migrations.AddField( + model_name="coursesessionattendancecourse", + name="due_date", + field=models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, + related_name="attendance_course_due_date", + to="duedate.duedate", + ), + ), + ] diff --git a/server/vbv_lernwelt/course_session/migrations/0003_auto_20230628_1321.py b/server/vbv_lernwelt/course_session/migrations/0003_auto_20230628_1321.py deleted file mode 100644 index 8ea1d556..00000000 --- a/server/vbv_lernwelt/course_session/migrations/0003_auto_20230628_1321.py +++ /dev/null @@ -1,35 +0,0 @@ -# Generated by Django 3.2.13 on 2023-06-28 11:21 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("duedate", "0006_auto_20230627_1553"), - ("course_session", "0002_coursesessionassignment"), - ] - - operations = [ - migrations.AlterField( - model_name="coursesessionassignment", - name="evaluation_deadline", - field=models.OneToOneField( - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="assignment_evaluation_deadline", - to="duedate.duedate", - ), - ), - migrations.AlterField( - model_name="coursesessionassignment", - name="submission_deadline", - field=models.OneToOneField( - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="assignment_submission_deadline", - to="duedate.duedate", - ), - ), - ] diff --git a/server/vbv_lernwelt/course_session/migrations/0003_initial.py b/server/vbv_lernwelt/course_session/migrations/0003_initial.py new file mode 100644 index 00000000..73c4e1ef --- /dev/null +++ b/server/vbv_lernwelt/course_session/migrations/0003_initial.py @@ -0,0 +1,62 @@ +# Generated by Django 3.2.13 on 2023-07-14 12:28 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ("course_session", "0002_coursesessionattendancecourse_due_date"), + ("course", "0001_initial"), + ("duedate", "0001_initial"), + ("learnpath", "0001_initial"), + ] + + operations = [ + migrations.AddField( + model_name="coursesessionattendancecourse", + name="learning_content", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="learnpath.learningcontentattendancecourse", + ), + ), + migrations.AddField( + model_name="coursesessionassignment", + name="course_session", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="course.coursesession" + ), + ), + migrations.AddField( + model_name="coursesessionassignment", + name="evaluation_deadline", + field=models.OneToOneField( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="assignment_evaluation_deadline", + to="duedate.duedate", + ), + ), + migrations.AddField( + model_name="coursesessionassignment", + name="learning_content", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="learnpath.learningcontentassignment", + ), + ), + migrations.AddField( + model_name="coursesessionassignment", + name="submission_deadline", + field=models.OneToOneField( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="assignment_submission_deadline", + to="duedate.duedate", + ), + ), + ] diff --git a/server/vbv_lernwelt/course_session/migrations/0004_merge_20230711_1108.py b/server/vbv_lernwelt/course_session/migrations/0004_merge_20230711_1108.py deleted file mode 100644 index f607ebe8..00000000 --- a/server/vbv_lernwelt/course_session/migrations/0004_merge_20230711_1108.py +++ /dev/null @@ -1,13 +0,0 @@ -# Generated by Django 3.2.13 on 2023-07-11 09:08 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("course_session", "0002_coursesessionattendancecourse_attendance_user_list"), - ("course_session", "0003_auto_20230628_1321"), - ] - - operations = [] diff --git a/server/vbv_lernwelt/course_session/migrations/0005_alter_coursesessionattendancecourse_attendance_user_list.py b/server/vbv_lernwelt/course_session/migrations/0005_alter_coursesessionattendancecourse_attendance_user_list.py deleted file mode 100644 index 1631e1cf..00000000 --- a/server/vbv_lernwelt/course_session/migrations/0005_alter_coursesessionattendancecourse_attendance_user_list.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 3.2.13 on 2023-07-12 14:49 - -import django_jsonform.models.fields -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("course_session", "0004_merge_20230711_1108"), - ] - - operations = [ - migrations.AlterField( - model_name="coursesessionattendancecourse", - name="attendance_user_list", - field=django_jsonform.models.fields.JSONField(default=list), - ), - ] diff --git a/server/vbv_lernwelt/course_session/services/attendance.py b/server/vbv_lernwelt/course_session/services/attendance.py index 22802943..8af7f7e1 100644 --- a/server/vbv_lernwelt/course_session/services/attendance.py +++ b/server/vbv_lernwelt/course_session/services/attendance.py @@ -30,7 +30,7 @@ def update_attendance_list( if u is not None: result_user_list.append( { - "user_id": u.id, + "user_id": str(u.id), "status": attendance_user.get( "status", AttendanceUserStatus.PRESENT ).value, diff --git a/server/vbv_lernwelt/course_session/tests/test_attendance.py b/server/vbv_lernwelt/course_session/tests/test_attendance.py index 841da952..347d1795 100644 --- a/server/vbv_lernwelt/course_session/tests/test_attendance.py +++ b/server/vbv_lernwelt/course_session/tests/test_attendance.py @@ -1,5 +1,6 @@ from django.test import TestCase +from vbv_lernwelt.core.constants import TEST_STUDENT1_USER_ID from vbv_lernwelt.core.create_default_users import create_default_users from vbv_lernwelt.core.models import User from vbv_lernwelt.course.creators.test_course import create_test_course @@ -35,7 +36,7 @@ class AttendanceServicesTestCase(TestCase): id=self.attendance_course.id ) self.assertEqual( - attendance_course.attendance_user_list[0]["user_id"], student.id + attendance_course.attendance_user_list[0]["user_id"], str(student.id) ) self.assertEqual( attendance_course.attendance_user_list, @@ -43,7 +44,7 @@ class AttendanceServicesTestCase(TestCase): { "email": "test-student1@example.com", "status": "PRESENT", - "user_id": -21, + "user_id": TEST_STUDENT1_USER_ID, "last_name": "Student1", "first_name": "Test", } @@ -68,7 +69,7 @@ class AttendanceServicesTestCase(TestCase): { "email": "test-student1@example.com", "status": "PRESENT", - "user_id": "-21", + "user_id": TEST_STUDENT1_USER_ID, "last_name": "Student1", "first_name": "Test", } diff --git a/server/vbv_lernwelt/course_session/tests/test_graphql.py b/server/vbv_lernwelt/course_session/tests/test_graphql.py index fcb4aab0..3790ffe5 100644 --- a/server/vbv_lernwelt/course_session/tests/test_graphql.py +++ b/server/vbv_lernwelt/course_session/tests/test_graphql.py @@ -49,8 +49,8 @@ class AttendanceCourseUserMutationTestCase(GraphQLTestCase): update_course_session_attendance_course_users( id:{self.attendance_course.id}, attendance_user_list:[ - {{user_id: {student.id}, status: PRESENT}}, - {{user_id: "123123123", status: PRESENT}}, + {{user_id: "{student.id}", status: PRESENT}}, + {{user_id: "3372836c-1c95-4721-881d-5342a60a3bfe", status: PRESENT}}, ] ) {{ course_session_attendance_course {{ diff --git a/server/vbv_lernwelt/duedate/migrations/0001_initial.py b/server/vbv_lernwelt/duedate/migrations/0001_initial.py index d433175d..0d84b5f4 100644 --- a/server/vbv_lernwelt/duedate/migrations/0001_initial.py +++ b/server/vbv_lernwelt/duedate/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.13 on 2023-06-14 09:29 +# Generated by Django 3.2.13 on 2023-07-14 12:28 import django.db.models.deletion from django.db import migrations, models @@ -9,7 +9,8 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ("course", "0004_import_fields"), + ("course", "0001_initial"), + ("wagtailcore", "0083_workflowcontenttype"), ] operations = [ @@ -26,23 +27,34 @@ class Migration(migrations.Migration): ), ), ("start", models.DateTimeField(db_index=True, null=True)), - ("end", models.DateTimeField(db_index=True, null=True)), - ("title", models.CharField(default="Termin", max_length=1024)), - ("url", models.URLField(blank=True, max_length=1024, null=True)), + ("end", models.DateTimeField(blank=True, db_index=True, null=True)), + ("title", models.CharField(default="", max_length=1024)), ( - "learning_content_id", - models.CharField(blank=True, max_length=255, null=True), + "learning_content_description", + models.CharField(blank=True, default="", max_length=1024), ), + ( + "description", + models.CharField(blank=True, default="", max_length=1024), + ), + ("url", models.CharField(blank=True, default="", max_length=1024)), ( "course_session", models.ForeignKey( blank=True, - null=True, on_delete=django.db.models.deletion.CASCADE, - related_name="events", to="course.coursesession", ), ), + ( + "page", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="wagtailcore.page", + ), + ), ], ), ] diff --git a/server/vbv_lernwelt/duedate/migrations/0002_auto_20230614_1500.py b/server/vbv_lernwelt/duedate/migrations/0002_auto_20230614_1500.py deleted file mode 100644 index c567593e..00000000 --- a/server/vbv_lernwelt/duedate/migrations/0002_auto_20230614_1500.py +++ /dev/null @@ -1,29 +0,0 @@ -# Generated by Django 3.2.13 on 2023-06-14 13:00 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("wagtailcore", "0083_workflowcontenttype"), - ("duedate", "0001_initial"), - ] - - operations = [ - migrations.RemoveField( - model_name="duedate", - name="learning_content_id", - ), - migrations.AddField( - model_name="duedate", - name="page", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - to="wagtailcore.page", - ), - ), - ] diff --git a/server/vbv_lernwelt/duedate/migrations/0003_alter_duedate_course_session.py b/server/vbv_lernwelt/duedate/migrations/0003_alter_duedate_course_session.py deleted file mode 100644 index 070d58c7..00000000 --- a/server/vbv_lernwelt/duedate/migrations/0003_alter_duedate_course_session.py +++ /dev/null @@ -1,26 +0,0 @@ -# Generated by Django 3.2.13 on 2023-06-21 14:19 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("course", "0006_remove_coursesession_assignment_details_list"), - ("duedate", "0002_auto_20230614_1500"), - ] - - operations = [ - migrations.AlterField( - model_name="duedate", - name="course_session", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="duedates", - to="course.coursesession", - ), - ), - ] diff --git a/server/vbv_lernwelt/duedate/migrations/0004_auto_20230621_1703.py b/server/vbv_lernwelt/duedate/migrations/0004_auto_20230621_1703.py deleted file mode 100644 index 91b6d2f2..00000000 --- a/server/vbv_lernwelt/duedate/migrations/0004_auto_20230621_1703.py +++ /dev/null @@ -1,29 +0,0 @@ -# Generated by Django 3.2.13 on 2023-06-21 15:03 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("contenttypes", "0002_remove_content_type_name"), - ("duedate", "0003_alter_duedate_course_session"), - ] - - operations = [ - migrations.AddField( - model_name="duedate", - name="content_type", - field=models.ForeignKey( - null=True, - on_delete=django.db.models.deletion.CASCADE, - to="contenttypes.contenttype", - ), - ), - migrations.AddField( - model_name="duedate", - name="object_id", - field=models.PositiveIntegerField(null=True), - ), - ] diff --git a/server/vbv_lernwelt/duedate/migrations/0005_auto_20230622_1138.py b/server/vbv_lernwelt/duedate/migrations/0005_auto_20230622_1138.py deleted file mode 100644 index 9ec6e37e..00000000 --- a/server/vbv_lernwelt/duedate/migrations/0005_auto_20230622_1138.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 3.2.13 on 2023-06-22 09:38 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("duedate", "0004_auto_20230621_1703"), - ] - - operations = [ - migrations.RemoveField( - model_name="duedate", - name="content_type", - ), - migrations.RemoveField( - model_name="duedate", - name="object_id", - ), - ] diff --git a/server/vbv_lernwelt/duedate/migrations/0006_auto_20230627_1553.py b/server/vbv_lernwelt/duedate/migrations/0006_auto_20230627_1553.py deleted file mode 100644 index e412294d..00000000 --- a/server/vbv_lernwelt/duedate/migrations/0006_auto_20230627_1553.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 3.2.13 on 2023-06-27 13:53 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("duedate", "0005_auto_20230622_1138"), - ] - - operations = [ - migrations.AddField( - model_name="duedate", - name="description", - field=models.CharField(default="Abgabetermin", max_length=1024), - ), - migrations.AddField( - model_name="duedate", - name="learning_content_description", - field=models.CharField(default="GeleiteteFallarbeit", max_length=1024), - ), - ] diff --git a/server/vbv_lernwelt/duedate/migrations/0007_auto_20230703_1741.py b/server/vbv_lernwelt/duedate/migrations/0007_auto_20230703_1741.py deleted file mode 100644 index 05c6dace..00000000 --- a/server/vbv_lernwelt/duedate/migrations/0007_auto_20230703_1741.py +++ /dev/null @@ -1,42 +0,0 @@ -# Generated by Django 3.2.13 on 2023-07-03 15:41 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("course", "0006_remove_coursesession_assignment_details_list"), - ("duedate", "0006_auto_20230627_1553"), - ] - - operations = [ - migrations.AlterField( - model_name="duedate", - name="course_session", - field=models.ForeignKey( - blank=True, - default=1, - on_delete=django.db.models.deletion.CASCADE, - related_name="duedates", - to="course.coursesession", - ), - preserve_default=False, - ), - migrations.AlterField( - model_name="duedate", - name="description", - field=models.CharField(default="", max_length=1024), - ), - migrations.AlterField( - model_name="duedate", - name="learning_content_description", - field=models.CharField(default="", max_length=1024), - ), - migrations.AlterField( - model_name="duedate", - name="url", - field=models.URLField(blank=True, default="", max_length=1024), - ), - ] diff --git a/server/vbv_lernwelt/duedate/migrations/0008_auto_20230711_1116.py b/server/vbv_lernwelt/duedate/migrations/0008_auto_20230711_1116.py deleted file mode 100644 index 006f14b7..00000000 --- a/server/vbv_lernwelt/duedate/migrations/0008_auto_20230711_1116.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 3.2.13 on 2023-07-11 09:16 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("duedate", "0007_auto_20230703_1741"), - ] - - operations = [ - migrations.AlterField( - model_name="duedate", - name="start", - field=models.DateTimeField(blank=True, db_index=True, null=True), - ), - migrations.AlterField( - model_name="duedate", - name="url", - field=models.CharField(blank=True, default="", max_length=1024), - ), - ] diff --git a/server/vbv_lernwelt/duedate/migrations/0009_alter_duedate_course_session.py b/server/vbv_lernwelt/duedate/migrations/0009_alter_duedate_course_session.py deleted file mode 100644 index 4b149840..00000000 --- a/server/vbv_lernwelt/duedate/migrations/0009_alter_duedate_course_session.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 3.2.13 on 2023-07-12 07:05 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("course", "0006_remove_coursesession_assignment_details_list"), - ("duedate", "0008_auto_20230711_1116"), - ] - - operations = [ - migrations.AlterField( - model_name="duedate", - name="course_session", - field=models.ForeignKey( - blank=True, - on_delete=django.db.models.deletion.CASCADE, - to="course.coursesession", - ), - ), - ] diff --git a/server/vbv_lernwelt/duedate/migrations/0010_auto_20230712_0920.py b/server/vbv_lernwelt/duedate/migrations/0010_auto_20230712_0920.py deleted file mode 100644 index a54f8713..00000000 --- a/server/vbv_lernwelt/duedate/migrations/0010_auto_20230712_0920.py +++ /dev/null @@ -1,38 +0,0 @@ -# Generated by Django 3.2.13 on 2023-07-12 07:20 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("duedate", "0009_alter_duedate_course_session"), - ] - - operations = [ - migrations.AlterField( - model_name="duedate", - name="description", - field=models.CharField(blank=True, default="", max_length=1024), - ), - migrations.AlterField( - model_name="duedate", - name="end", - field=models.DateTimeField(blank=True, db_index=True, null=True), - ), - migrations.AlterField( - model_name="duedate", - name="learning_content_description", - field=models.CharField(blank=True, default="", max_length=1024), - ), - migrations.AlterField( - model_name="duedate", - name="start", - field=models.DateTimeField(db_index=True, null=True), - ), - migrations.AlterField( - model_name="duedate", - name="title", - field=models.CharField(default="", max_length=1024), - ), - ] diff --git a/server/vbv_lernwelt/feedback/creators/create_demo_feedback.py b/server/vbv_lernwelt/feedback/creators/create_demo_feedback.py index 586b2989..f71a6b55 100644 --- a/server/vbv_lernwelt/feedback/creators/create_demo_feedback.py +++ b/server/vbv_lernwelt/feedback/creators/create_demo_feedback.py @@ -1,8 +1,8 @@ from vbv_lernwelt.course.models import CourseSession -from vbv_lernwelt.feedback.factories import FeedbackFactory +from vbv_lernwelt.feedback.factories import FeedbackResponseFactory from vbv_lernwelt.learnpath.models import Circle def create_feedback(circle: Circle, course_session: CourseSession, amount: int): for _i in range(amount): - FeedbackFactory(circle=circle, course_session=course_session).save() + FeedbackResponseFactory(circle=circle, course_session=course_session).save() diff --git a/server/vbv_lernwelt/feedback/factories.py b/server/vbv_lernwelt/feedback/factories.py index d55d830f..d44622c7 100644 --- a/server/vbv_lernwelt/feedback/factories.py +++ b/server/vbv_lernwelt/feedback/factories.py @@ -5,7 +5,7 @@ from factory.fuzzy import FuzzyChoice, FuzzyInteger from vbv_lernwelt.feedback.models import FeedbackResponse -class FeedbackFactory(DjangoModelFactory): +class FeedbackResponseFactory(DjangoModelFactory): data = Dict( { "satisfaction": FuzzyInteger(2, 4), diff --git a/server/vbv_lernwelt/feedback/migrations/0001_initial.py b/server/vbv_lernwelt/feedback/migrations/0001_initial.py index 469cb309..c871fc75 100644 --- a/server/vbv_lernwelt/feedback/migrations/0001_initial.py +++ b/server/vbv_lernwelt/feedback/migrations/0001_initial.py @@ -1,4 +1,6 @@ -# Generated by Django 3.2.13 on 2023-05-12 15:29 +# Generated by Django 3.2.13 on 2023-07-14 12:28 + +import uuid from django.db import migrations, models @@ -15,11 +17,11 @@ class Migration(migrations.Migration): fields=[ ( "id", - models.BigAutoField( - auto_created=True, + models.UUIDField( + default=uuid.uuid4, + editable=False, primary_key=True, serialize=False, - verbose_name="ID", ), ), ("data", models.JSONField(default=dict)), diff --git a/server/vbv_lernwelt/feedback/migrations/0002_initial.py b/server/vbv_lernwelt/feedback/migrations/0002_initial.py index b10b9aed..d0543c85 100644 --- a/server/vbv_lernwelt/feedback/migrations/0002_initial.py +++ b/server/vbv_lernwelt/feedback/migrations/0002_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.13 on 2023-05-12 15:29 +# Generated by Django 3.2.13 on 2023-07-14 12:28 import django.db.models.deletion from django.db import migrations, models @@ -9,9 +9,9 @@ class Migration(migrations.Migration): initial = True dependencies = [ + ("feedback", "0001_initial"), ("course", "0001_initial"), ("learnpath", "0001_initial"), - ("feedback", "0001_initial"), ] operations = [ diff --git a/server/vbv_lernwelt/feedback/models.py b/server/vbv_lernwelt/feedback/models.py index 6901601e..f7f56444 100644 --- a/server/vbv_lernwelt/feedback/models.py +++ b/server/vbv_lernwelt/feedback/models.py @@ -1,3 +1,5 @@ +import uuid + from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models from django.utils.translation import gettext_lazy as _ @@ -19,6 +21,8 @@ class FeedbackIntegerField(models.IntegerField): class FeedbackResponse(models.Model): + id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + class DiscoveredChoices(models.TextChoices): INTERNET = "I", _("Internet") LEAFLET = "L", _("Leaflet") @@ -41,7 +45,8 @@ class FeedbackResponse(models.Model): HUNDRED = 100, "100%" def save(self, *args, **kwargs): - if not self.id: + if self._state.adding: + # with `id=UUIDField` it is always set... course_session_users = CourseSessionUser.objects.filter( role="EXPERT", course_session=self.course_session, expert=self.circle ) diff --git a/server/vbv_lernwelt/feedback/tests/test_feedback_api.py b/server/vbv_lernwelt/feedback/tests/test_feedback_api.py index 6ad2136c..c302ca5c 100644 --- a/server/vbv_lernwelt/feedback/tests/test_feedback_api.py +++ b/server/vbv_lernwelt/feedback/tests/test_feedback_api.py @@ -5,7 +5,8 @@ from vbv_lernwelt.core.models import User from vbv_lernwelt.course.consts import COURSE_TEST_ID from vbv_lernwelt.course.creators.test_course import create_test_course from vbv_lernwelt.course.models import CourseSession, CourseSessionUser -from vbv_lernwelt.feedback.factories import FeedbackFactory +from vbv_lernwelt.feedback.factories import FeedbackResponseFactory +from vbv_lernwelt.feedback.models import FeedbackResponse from vbv_lernwelt.learnpath.models import Circle from vbv_lernwelt.notify.models import Notification @@ -61,7 +62,9 @@ class FeedbackSummaryApiTestCase(FeedbackApiBaseTestCase): basis_circle = Circle.objects.get(slug="test-lehrgang-lp-circle-reisen") csu.expert.add(basis_circle) - FeedbackFactory(circle=basis_circle, course_session=csu.course_session).save() + FeedbackResponse.objects.create( + circle=basis_circle, course_session=csu.course_session + ) notifications = Notification.objects.all() self.assertEqual(len(notifications), 1) @@ -84,7 +87,7 @@ class FeedbackSummaryApiTestCase(FeedbackApiBaseTestCase): basis_circle = Circle.objects.get(slug="test-lehrgang-lp-circle-reisen") csu.expert.add(basis_circle) - feedback = FeedbackFactory( + feedback = FeedbackResponseFactory( circle=basis_circle, course_session=csu.course_session ) feedback.save() @@ -113,12 +116,12 @@ class FeedbackSummaryApiTestCase(FeedbackApiBaseTestCase): csu.expert.add(reisen_circle) for i in range(number_reisen_feedback): - FeedbackFactory( + FeedbackResponseFactory( circle=reisen_circle, course_session=csu.course_session ).save() for i in range(number_fahrzeug_feedback): - FeedbackFactory( + FeedbackResponseFactory( circle=fahrzeug_circle, course_session=csu.course_session ).save() @@ -146,12 +149,12 @@ class FeedbackSummaryApiTestCase(FeedbackApiBaseTestCase): reisen_circle = Circle.objects.get(slug="test-lehrgang-lp-circle-reisen") for i in range(number_basis_feedback): - FeedbackFactory( + FeedbackResponseFactory( circle=reisen_circle, course_session=csu.course_session ).save() for i in range(number_analyse_feedback): - FeedbackFactory( + FeedbackResponseFactory( circle=fahrzeug_circle, course_session=csu.course_session ).save() @@ -172,7 +175,7 @@ class FeedbackSummaryApiTestCase(FeedbackApiBaseTestCase): user=self.user, ) fahrzeug_circle = Circle.objects.get(slug="test-lehrgang-lp-circle-fahrzeug") - FeedbackFactory( + FeedbackResponseFactory( circle=fahrzeug_circle, course_session=csu.course_session ).save() @@ -206,7 +209,7 @@ class FeedbackDetailApiTestCase(FeedbackApiBaseTestCase): circle = Circle.objects.get(slug="test-lehrgang-lp-circle-fahrzeug") for i in range(3): - FeedbackFactory( + FeedbackResponseFactory( circle=circle, course_session=csu.course_session, data={ @@ -252,7 +255,7 @@ class FeedbackDetailApiTestCase(FeedbackApiBaseTestCase): ) circle = Circle.objects.get(slug="test-lehrgang-lp-circle-reisen") - FeedbackFactory(circle=circle, course_session=csu.course_session).save() + FeedbackResponseFactory(circle=circle, course_session=csu.course_session).save() response = self.client.get( f"/api/core/feedback/{csu.course_session.course.id}/{circle.id}/" @@ -268,7 +271,7 @@ class FeedbackDetailApiTestCase(FeedbackApiBaseTestCase): user=self.user, ) circle = Circle.objects.get(slug="test-lehrgang-lp-circle-fahrzeug") - FeedbackFactory(circle=circle, course_session=csu.course_session).save() + FeedbackResponseFactory(circle=circle, course_session=csu.course_session).save() response = self.client.get( f"/api/core/feedback/{csu.course_session.course.id}/{circle.id}/" diff --git a/server/vbv_lernwelt/files/migrations/0001_initial.py b/server/vbv_lernwelt/files/migrations/0001_initial.py index d40af972..36cbad5e 100644 --- a/server/vbv_lernwelt/files/migrations/0001_initial.py +++ b/server/vbv_lernwelt/files/migrations/0001_initial.py @@ -1,4 +1,6 @@ -# Generated by Django 3.2.13 on 2023-05-11 20:06 +# Generated by Django 3.2.13 on 2023-07-14 12:28 + +import uuid import django.db.models.deletion from django.conf import settings @@ -21,11 +23,11 @@ class Migration(migrations.Migration): fields=[ ( "id", - models.BigAutoField( - auto_created=True, + models.UUIDField( + default=uuid.uuid4, + editable=False, primary_key=True, serialize=False, - verbose_name="ID", ), ), ( diff --git a/server/vbv_lernwelt/files/models.py b/server/vbv_lernwelt/files/models.py index 69a3dd12..32cec66c 100644 --- a/server/vbv_lernwelt/files/models.py +++ b/server/vbv_lernwelt/files/models.py @@ -1,3 +1,5 @@ +import uuid + from django.conf import settings from django.db import models @@ -12,6 +14,8 @@ from vbv_lernwelt.files.utils import file_generate_upload_path class UploadFile(models.Model): + id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + file = models.FileField(upload_to=file_generate_upload_path, blank=True, null=True) original_file_name = models.TextField() diff --git a/server/vbv_lernwelt/learnpath/migrations/0001_initial.py b/server/vbv_lernwelt/learnpath/migrations/0001_initial.py index bd16996c..596b11ad 100644 --- a/server/vbv_lernwelt/learnpath/migrations/0001_initial.py +++ b/server/vbv_lernwelt/learnpath/migrations/0001_initial.py @@ -1,6 +1,7 @@ -# Generated by Django 3.2.13 on 2023-05-12 15:29 +# Generated by Django 3.2.13 on 2023-07-14 12:28 import django.db.models.deletion +import wagtail.blocks import wagtail.fields from django.db import migrations, models @@ -10,8 +11,8 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ("course", "0001_initial"), ("assignment", "0003_initial"), + ("course", "0001_initial"), ("wagtailcore", "0083_workflowcontenttype"), ] @@ -39,7 +40,7 @@ class Migration(migrations.Migration): bases=("wagtailcore.page",), ), migrations.CreateModel( - name="LearningContentAttendanceDay", + name="LearningContentAttendanceCourse", fields=[ ( "page_ptr", @@ -55,6 +56,84 @@ class Migration(migrations.Migration): ("minutes", models.PositiveIntegerField(default=15)), ("description", wagtail.fields.RichTextField(blank=True)), ("content_url", models.TextField(blank=True)), + ("has_course_completion_status", models.BooleanField(default=True)), + ( + "can_user_self_toggle_course_completion", + models.BooleanField(default=False), + ), + ], + options={ + "abstract": False, + }, + bases=("wagtailcore.page",), + ), + migrations.CreateModel( + name="LearningContentDocumentList", + fields=[ + ( + "page_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + serialize=False, + to="wagtailcore.page", + ), + ), + ("minutes", models.PositiveIntegerField(default=15)), + ("description", wagtail.fields.RichTextField(blank=True)), + ("content_url", models.TextField(blank=True)), + ("has_course_completion_status", models.BooleanField(default=True)), + ( + "can_user_self_toggle_course_completion", + models.BooleanField(default=True), + ), + ( + "documents", + wagtail.fields.StreamField( + [ + ( + "document", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.TextBlock()), + ( + "description", + wagtail.blocks.TextBlock( + default="", required=False + ), + ), + ( + "icon_url", + wagtail.blocks.TextBlock( + default="", required=False + ), + ), + ( + "link_display_text", + wagtail.blocks.CharBlock( + default="Link öffnen", max_length=255 + ), + ), + ( + "url", + wagtail.blocks.TextBlock( + default="", required=False + ), + ), + ( + "open_window", + wagtail.blocks.BooleanBlock(default=False), + ), + ] + ), + ) + ], + blank=True, + use_json_field=True, + ), + ), ], options={ "abstract": False, @@ -78,6 +157,11 @@ class Migration(migrations.Migration): ("minutes", models.PositiveIntegerField(default=15)), ("description", wagtail.fields.RichTextField(blank=True)), ("content_url", models.TextField(blank=True)), + ("has_course_completion_status", models.BooleanField(default=True)), + ( + "can_user_self_toggle_course_completion", + models.BooleanField(default=True), + ), ], options={ "abstract": False, @@ -101,6 +185,11 @@ class Migration(migrations.Migration): ("minutes", models.PositiveIntegerField(default=15)), ("description", wagtail.fields.RichTextField(blank=True)), ("content_url", models.TextField(blank=True)), + ("has_course_completion_status", models.BooleanField(default=True)), + ( + "can_user_self_toggle_course_completion", + models.BooleanField(default=True), + ), ], options={ "abstract": False, @@ -124,6 +213,11 @@ class Migration(migrations.Migration): ("minutes", models.PositiveIntegerField(default=15)), ("description", wagtail.fields.RichTextField(blank=True)), ("content_url", models.TextField(blank=True)), + ("has_course_completion_status", models.BooleanField(default=True)), + ( + "can_user_self_toggle_course_completion", + models.BooleanField(default=True), + ), ], options={ "abstract": False, @@ -147,6 +241,11 @@ class Migration(migrations.Migration): ("minutes", models.PositiveIntegerField(default=15)), ("description", wagtail.fields.RichTextField(blank=True)), ("content_url", models.TextField(blank=True)), + ("has_course_completion_status", models.BooleanField(default=True)), + ( + "can_user_self_toggle_course_completion", + models.BooleanField(default=True), + ), ], options={ "abstract": False, @@ -170,6 +269,12 @@ class Migration(migrations.Migration): ("minutes", models.PositiveIntegerField(default=15)), ("description", wagtail.fields.RichTextField(blank=True)), ("content_url", models.TextField(blank=True)), + ("has_course_completion_status", models.BooleanField(default=True)), + ("text", wagtail.fields.RichTextField(blank=True)), + ( + "can_user_self_toggle_course_completion", + models.BooleanField(default=True), + ), ], options={ "abstract": False, @@ -193,6 +298,12 @@ class Migration(migrations.Migration): ("minutes", models.PositiveIntegerField(default=15)), ("description", wagtail.fields.RichTextField(blank=True)), ("content_url", models.TextField(blank=True)), + ("has_course_completion_status", models.BooleanField(default=True)), + ( + "can_user_self_toggle_course_completion", + models.BooleanField(default=False), + ), + ("checkbox_text", models.TextField(blank=True)), ], options={ "abstract": False, @@ -216,6 +327,11 @@ class Migration(migrations.Migration): ("minutes", models.PositiveIntegerField(default=15)), ("description", wagtail.fields.RichTextField(blank=True)), ("content_url", models.TextField(blank=True)), + ("has_course_completion_status", models.BooleanField(default=True)), + ( + "can_user_self_toggle_course_completion", + models.BooleanField(default=True), + ), ], options={ "abstract": False, @@ -298,6 +414,7 @@ class Migration(migrations.Migration): to="wagtailcore.page", ), ), + ("title_hidden", models.BooleanField(default=False)), ( "course_category", models.ForeignKey( @@ -330,11 +447,27 @@ class Migration(migrations.Migration): ("minutes", models.PositiveIntegerField(default=15)), ("description", wagtail.fields.RichTextField(blank=True)), ("content_url", models.TextField(blank=True)), + ("has_course_completion_status", models.BooleanField(default=True)), + ( + "can_user_self_toggle_course_completion", + models.BooleanField(default=False), + ), + ( + "assignment_type", + models.CharField( + choices=[ + ("CASEWORK", "CASEWORK"), + ("PREP_ASSIGNMENT", "PREP_ASSIGNMENT"), + ("REFLECTION", "REFLECTION"), + ], + default="CASEWORK", + max_length=50, + ), + ), ( "content_assignment", models.ForeignKey( on_delete=django.db.models.deletion.PROTECT, - related_name="+", to="assignment.assignment", ), ), diff --git a/server/vbv_lernwelt/learnpath/migrations/0002_learningcontentrichtext_text.py b/server/vbv_lernwelt/learnpath/migrations/0002_learningcontentrichtext_text.py deleted file mode 100644 index b4f26255..00000000 --- a/server/vbv_lernwelt/learnpath/migrations/0002_learningcontentrichtext_text.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 3.2.13 on 2023-05-17 09:00 - -import wagtail.fields -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("learnpath", "0001_initial"), - ] - - operations = [ - migrations.AddField( - model_name="learningcontentrichtext", - name="text", - field=wagtail.fields.RichTextField(blank=True), - ), - ] diff --git a/server/vbv_lernwelt/learnpath/migrations/0003_rename_learningcontentattendanceday_learningcontentattendancecourse.py b/server/vbv_lernwelt/learnpath/migrations/0003_rename_learningcontentattendanceday_learningcontentattendancecourse.py deleted file mode 100644 index 7c0b9f61..00000000 --- a/server/vbv_lernwelt/learnpath/migrations/0003_rename_learningcontentattendanceday_learningcontentattendancecourse.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 3.2.13 on 2023-05-23 12:49 - -from django.conf import settings -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("wagtailcore", "0083_workflowcontenttype"), - ("wagtailforms", "0005_alter_formsubmission_form_data"), - ("wagtailredirects", "0008_add_verbose_name_plural"), - ("contenttypes", "0002_remove_content_type_name"), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ("learnpath", "0002_learningcontentrichtext_text"), - ] - - operations = [ - migrations.RenameModel( - old_name="LearningContentAttendanceDay", - new_name="LearningContentAttendanceCourse", - ), - ] diff --git a/server/vbv_lernwelt/learnpath/migrations/0004_learningcontentassignment_assignment_type.py b/server/vbv_lernwelt/learnpath/migrations/0004_learningcontentassignment_assignment_type.py deleted file mode 100644 index 5525b9a3..00000000 --- a/server/vbv_lernwelt/learnpath/migrations/0004_learningcontentassignment_assignment_type.py +++ /dev/null @@ -1,28 +0,0 @@ -# Generated by Django 3.2.13 on 2023-05-19 15:21 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ( - "learnpath", - "0003_rename_learningcontentattendanceday_learningcontentattendancecourse", - ), - ] - - operations = [ - migrations.AddField( - model_name="learningcontentassignment", - name="assignment_type", - field=models.CharField( - choices=[ - ("CASEWORK", "CASEWORK"), - ("PREP_ASSIGNMENT", "PREP_ASSIGNMENT"), - ("REFLECTION", "REFLECTION"), - ], - default="CASEWORK", - max_length=50, - ), - ), - ] diff --git a/server/vbv_lernwelt/learnpath/migrations/0005_learningcontentdocumentlist.py b/server/vbv_lernwelt/learnpath/migrations/0005_learningcontentdocumentlist.py deleted file mode 100644 index 406cfc8c..00000000 --- a/server/vbv_lernwelt/learnpath/migrations/0005_learningcontentdocumentlist.py +++ /dev/null @@ -1,85 +0,0 @@ -# Generated by Django 3.2.13 on 2023-05-26 10:34 - -import django.db.models.deletion -import wagtail.blocks -import wagtail.fields -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("wagtailcore", "0083_workflowcontenttype"), - ("learnpath", "0004_learningcontentassignment_assignment_type"), - ] - - operations = [ - migrations.CreateModel( - name="LearningContentDocumentList", - fields=[ - ( - "page_ptr", - models.OneToOneField( - auto_created=True, - on_delete=django.db.models.deletion.CASCADE, - parent_link=True, - primary_key=True, - serialize=False, - to="wagtailcore.page", - ), - ), - ("minutes", models.PositiveIntegerField(default=15)), - ("description", wagtail.fields.RichTextField(blank=True)), - ("content_url", models.TextField(blank=True)), - ( - "documents", - wagtail.fields.StreamField( - [ - ( - "document", - wagtail.blocks.StructBlock( - [ - ("title", wagtail.blocks.TextBlock()), - ( - "description", - wagtail.blocks.TextBlock( - default="", required=False - ), - ), - ( - "icon_url", - wagtail.blocks.TextBlock( - default="", required=False - ), - ), - ( - "link_display_text", - wagtail.blocks.CharBlock( - default="Link öffnen", max_length=255 - ), - ), - ( - "url", - wagtail.blocks.TextBlock( - default="", required=False - ), - ), - ( - "open_window", - wagtail.blocks.BooleanBlock(default=False), - ), - ] - ), - ) - ], - blank=True, - use_json_field=True, - ), - ), - ], - options={ - "abstract": False, - }, - bases=("wagtailcore.page",), - ), - ] diff --git a/server/vbv_lernwelt/learnpath/migrations/0006_learningcontenttest_checkbox_text.py b/server/vbv_lernwelt/learnpath/migrations/0006_learningcontenttest_checkbox_text.py deleted file mode 100644 index 545416ae..00000000 --- a/server/vbv_lernwelt/learnpath/migrations/0006_learningcontenttest_checkbox_text.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.2.13 on 2023-05-26 14:31 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("learnpath", "0005_learningcontentdocumentlist"), - ] - - operations = [ - migrations.AddField( - model_name="learningcontenttest", - name="checkbox_text", - field=models.TextField(blank=True), - ), - ] diff --git a/server/vbv_lernwelt/learnpath/migrations/0007_learningunit_title_hidden.py b/server/vbv_lernwelt/learnpath/migrations/0007_learningunit_title_hidden.py deleted file mode 100644 index e68e39d5..00000000 --- a/server/vbv_lernwelt/learnpath/migrations/0007_learningunit_title_hidden.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.2.13 on 2023-05-30 09:18 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("learnpath", "0006_learningcontenttest_checkbox_text"), - ] - - operations = [ - migrations.AddField( - model_name="learningunit", - name="title_hidden", - field=models.BooleanField(default=False), - ), - ] diff --git a/server/vbv_lernwelt/learnpath/migrations/0008_alter_learningcontentassignment_content_assignment.py b/server/vbv_lernwelt/learnpath/migrations/0008_alter_learningcontentassignment_content_assignment.py deleted file mode 100644 index cd1300ed..00000000 --- a/server/vbv_lernwelt/learnpath/migrations/0008_alter_learningcontentassignment_content_assignment.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 3.2.13 on 2023-06-28 11:21 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("assignment", "0004_assignment_assignment_type"), - ("learnpath", "0007_learningunit_title_hidden"), - ] - - operations = [ - migrations.AlterField( - model_name="learningcontentassignment", - name="content_assignment", - field=models.ForeignKey( - on_delete=django.db.models.deletion.PROTECT, to="assignment.assignment" - ), - ), - ] diff --git a/server/vbv_lernwelt/learnpath/migrations/0008_auto_20230626_1747.py b/server/vbv_lernwelt/learnpath/migrations/0008_auto_20230626_1747.py deleted file mode 100644 index ee442287..00000000 --- a/server/vbv_lernwelt/learnpath/migrations/0008_auto_20230626_1747.py +++ /dev/null @@ -1,112 +0,0 @@ -# Generated by Django 3.2.13 on 2023-06-26 15:47 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("learnpath", "0007_learningunit_title_hidden"), - ] - - operations = [ - migrations.AddField( - model_name="learningcontentassignment", - name="can_user_self_toggle_course_completion", - field=models.BooleanField(default=False), - ), - migrations.AddField( - model_name="learningcontentassignment", - name="has_course_completion_status", - field=models.BooleanField(default=True), - ), - migrations.AddField( - model_name="learningcontentattendancecourse", - name="can_user_self_toggle_course_completion", - field=models.BooleanField(default=False), - ), - migrations.AddField( - model_name="learningcontentattendancecourse", - name="has_course_completion_status", - field=models.BooleanField(default=True), - ), - migrations.AddField( - model_name="learningcontentdocumentlist", - name="can_user_self_toggle_course_completion", - field=models.BooleanField(default=True), - ), - migrations.AddField( - model_name="learningcontentdocumentlist", - name="has_course_completion_status", - field=models.BooleanField(default=True), - ), - migrations.AddField( - model_name="learningcontentfeedback", - name="can_user_self_toggle_course_completion", - field=models.BooleanField(default=True), - ), - migrations.AddField( - model_name="learningcontentfeedback", - name="has_course_completion_status", - field=models.BooleanField(default=True), - ), - migrations.AddField( - model_name="learningcontentlearningmodule", - name="can_user_self_toggle_course_completion", - field=models.BooleanField(default=True), - ), - migrations.AddField( - model_name="learningcontentlearningmodule", - name="has_course_completion_status", - field=models.BooleanField(default=True), - ), - migrations.AddField( - model_name="learningcontentmedialibrary", - name="can_user_self_toggle_course_completion", - field=models.BooleanField(default=True), - ), - migrations.AddField( - model_name="learningcontentmedialibrary", - name="has_course_completion_status", - field=models.BooleanField(default=True), - ), - migrations.AddField( - model_name="learningcontentplaceholder", - name="can_user_self_toggle_course_completion", - field=models.BooleanField(default=True), - ), - migrations.AddField( - model_name="learningcontentplaceholder", - name="has_course_completion_status", - field=models.BooleanField(default=True), - ), - migrations.AddField( - model_name="learningcontentrichtext", - name="can_user_self_toggle_course_completion", - field=models.BooleanField(default=True), - ), - migrations.AddField( - model_name="learningcontentrichtext", - name="has_course_completion_status", - field=models.BooleanField(default=True), - ), - migrations.AddField( - model_name="learningcontenttest", - name="can_user_self_toggle_course_completion", - field=models.BooleanField(default=False), - ), - migrations.AddField( - model_name="learningcontenttest", - name="has_course_completion_status", - field=models.BooleanField(default=True), - ), - migrations.AddField( - model_name="learningcontentvideo", - name="can_user_self_toggle_course_completion", - field=models.BooleanField(default=True), - ), - migrations.AddField( - model_name="learningcontentvideo", - name="has_course_completion_status", - field=models.BooleanField(default=True), - ), - ] diff --git a/server/vbv_lernwelt/learnpath/migrations/0009_alter_learningcontentassignment_content_assignment.py b/server/vbv_lernwelt/learnpath/migrations/0009_alter_learningcontentassignment_content_assignment.py deleted file mode 100644 index 076c78c6..00000000 --- a/server/vbv_lernwelt/learnpath/migrations/0009_alter_learningcontentassignment_content_assignment.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 3.2.13 on 2023-06-26 16:30 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("assignment", "0004_assignment_assignment_type"), - ("learnpath", "0008_auto_20230626_1747"), - ] - - operations = [ - migrations.AlterField( - model_name="learningcontentassignment", - name="content_assignment", - field=models.ForeignKey( - on_delete=django.db.models.deletion.PROTECT, to="assignment.assignment" - ), - ), - ] diff --git a/server/vbv_lernwelt/learnpath/migrations/0010_merge_20230711_1108.py b/server/vbv_lernwelt/learnpath/migrations/0010_merge_20230711_1108.py deleted file mode 100644 index 0b85ed9c..00000000 --- a/server/vbv_lernwelt/learnpath/migrations/0010_merge_20230711_1108.py +++ /dev/null @@ -1,13 +0,0 @@ -# Generated by Django 3.2.13 on 2023-07-11 09:08 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("learnpath", "0008_alter_learningcontentassignment_content_assignment"), - ("learnpath", "0009_alter_learningcontentassignment_content_assignment"), - ] - - operations = [] diff --git a/server/vbv_lernwelt/media_library/migrations/0001_initial.py b/server/vbv_lernwelt/media_library/migrations/0001_initial.py index 5277c312..9b84fef1 100644 --- a/server/vbv_lernwelt/media_library/migrations/0001_initial.py +++ b/server/vbv_lernwelt/media_library/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.13 on 2023-05-12 15:29 +# Generated by Django 3.2.13 on 2023-07-14 12:28 import django.db.models.deletion import taggit.managers @@ -15,9 +15,9 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ("taggit", "0004_alter_taggeditem_content_type_alter_taggeditem_tag"), ("course", "0002_initial"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("taggit", "0004_alter_taggeditem_content_type_alter_taggeditem_tag"), ("wagtailcore", "0083_workflowcontenttype"), ] diff --git a/server/vbv_lernwelt/notify/migrations/0001_initial.py b/server/vbv_lernwelt/notify/migrations/0001_initial.py index e802df1c..cbca2aeb 100644 --- a/server/vbv_lernwelt/notify/migrations/0001_initial.py +++ b/server/vbv_lernwelt/notify/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.13 on 2023-05-11 20:06 +# Generated by Django 3.2.13 on 2023-07-14 13:08 import django.db.models.deletion import django.utils.timezone @@ -40,30 +40,74 @@ class Migration(migrations.Migration): ], default="info", max_length=20, + verbose_name="level", ), ), - ("unread", models.BooleanField(db_index=True, default=True)), - ("actor_object_id", models.CharField(max_length=255)), - ("verb", models.CharField(max_length=255)), - ("description", models.TextField(blank=True, null=True)), + ( + "unread", + models.BooleanField( + db_index=True, default=True, verbose_name="unread" + ), + ), + ( + "actor_object_id", + models.CharField(max_length=255, verbose_name="actor object id"), + ), + ("verb", models.CharField(max_length=255, verbose_name="verb")), + ( + "description", + models.TextField(blank=True, null=True, verbose_name="description"), + ), ( "target_object_id", - models.CharField(blank=True, max_length=255, null=True), + models.CharField( + blank=True, + max_length=255, + null=True, + verbose_name="target object id", + ), ), ( "action_object_object_id", - models.CharField(blank=True, max_length=255, null=True), + models.CharField( + blank=True, + max_length=255, + null=True, + verbose_name="action object object id", + ), ), ( "timestamp", models.DateTimeField( - db_index=True, default=django.utils.timezone.now + db_index=True, + default=django.utils.timezone.now, + verbose_name="timestamp", + ), + ), + ( + "public", + models.BooleanField( + db_index=True, default=True, verbose_name="public" + ), + ), + ( + "deleted", + models.BooleanField( + db_index=True, default=False, verbose_name="deleted" + ), + ), + ( + "emailed", + models.BooleanField( + db_index=True, default=False, verbose_name="emailed" + ), + ), + ( + "data", + jsonfield.fields.JSONField( + blank=True, null=True, verbose_name="data" ), ), - ("public", models.BooleanField(db_index=True, default=True)), - ("deleted", models.BooleanField(db_index=True, default=False)), - ("emailed", models.BooleanField(db_index=True, default=False)), - ("data", jsonfield.fields.JSONField(blank=True, null=True)), ( "notification_type", models.CharField( @@ -87,6 +131,7 @@ class Migration(migrations.Migration): on_delete=django.db.models.deletion.CASCADE, related_name="notify_action_object", to="contenttypes.contenttype", + verbose_name="action object content type", ), ), ( @@ -95,6 +140,7 @@ class Migration(migrations.Migration): on_delete=django.db.models.deletion.CASCADE, related_name="notify_actor", to="contenttypes.contenttype", + verbose_name="actor content type", ), ), ( @@ -103,6 +149,7 @@ class Migration(migrations.Migration): on_delete=django.db.models.deletion.CASCADE, related_name="notifications", to=settings.AUTH_USER_MODEL, + verbose_name="recipient", ), ), ( @@ -113,10 +160,13 @@ class Migration(migrations.Migration): on_delete=django.db.models.deletion.CASCADE, related_name="notify_target", to="contenttypes.contenttype", + verbose_name="target content type", ), ), ], options={ + "verbose_name": "Notification", + "verbose_name_plural": "Notifications", "ordering": ["-timestamp"], "abstract": False, "index_together": {("recipient", "unread")}, diff --git a/server/vbv_lernwelt/notify/migrations/0002_auto_20230712_0905.py b/server/vbv_lernwelt/notify/migrations/0002_auto_20230712_0905.py deleted file mode 100644 index cbc4d336..00000000 --- a/server/vbv_lernwelt/notify/migrations/0002_auto_20230712_0905.py +++ /dev/null @@ -1,162 +0,0 @@ -# Generated by Django 3.2.13 on 2023-07-12 07:05 - -import django.db.models.deletion -import django.utils.timezone -import jsonfield.fields -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("contenttypes", "0002_remove_content_type_name"), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ("notify", "0001_initial"), - ] - - operations = [ - migrations.AlterModelOptions( - name="notification", - options={ - "ordering": ["-timestamp"], - "verbose_name": "Notification", - "verbose_name_plural": "Notifications", - }, - ), - migrations.AlterField( - model_name="notification", - name="action_object_content_type", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="notify_action_object", - to="contenttypes.contenttype", - verbose_name="action object content type", - ), - ), - migrations.AlterField( - model_name="notification", - name="action_object_object_id", - field=models.CharField( - blank=True, - max_length=255, - null=True, - verbose_name="action object object id", - ), - ), - migrations.AlterField( - model_name="notification", - name="actor_content_type", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="notify_actor", - to="contenttypes.contenttype", - verbose_name="actor content type", - ), - ), - migrations.AlterField( - model_name="notification", - name="actor_object_id", - field=models.CharField(max_length=255, verbose_name="actor object id"), - ), - migrations.AlterField( - model_name="notification", - name="data", - field=jsonfield.fields.JSONField( - blank=True, null=True, verbose_name="data" - ), - ), - migrations.AlterField( - model_name="notification", - name="deleted", - field=models.BooleanField( - db_index=True, default=False, verbose_name="deleted" - ), - ), - migrations.AlterField( - model_name="notification", - name="description", - field=models.TextField(blank=True, null=True, verbose_name="description"), - ), - migrations.AlterField( - model_name="notification", - name="emailed", - field=models.BooleanField( - db_index=True, default=False, verbose_name="emailed" - ), - ), - migrations.AlterField( - model_name="notification", - name="level", - field=models.CharField( - choices=[ - ("success", "success"), - ("info", "info"), - ("warning", "warning"), - ("error", "error"), - ], - default="info", - max_length=20, - verbose_name="level", - ), - ), - migrations.AlterField( - model_name="notification", - name="public", - field=models.BooleanField( - db_index=True, default=True, verbose_name="public" - ), - ), - migrations.AlterField( - model_name="notification", - name="recipient", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="notifications", - to=settings.AUTH_USER_MODEL, - verbose_name="recipient", - ), - ), - migrations.AlterField( - model_name="notification", - name="target_content_type", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="notify_target", - to="contenttypes.contenttype", - verbose_name="target content type", - ), - ), - migrations.AlterField( - model_name="notification", - name="target_object_id", - field=models.CharField( - blank=True, max_length=255, null=True, verbose_name="target object id" - ), - ), - migrations.AlterField( - model_name="notification", - name="timestamp", - field=models.DateTimeField( - db_index=True, - default=django.utils.timezone.now, - verbose_name="timestamp", - ), - ), - migrations.AlterField( - model_name="notification", - name="unread", - field=models.BooleanField( - db_index=True, default=True, verbose_name="unread" - ), - ), - migrations.AlterField( - model_name="notification", - name="verb", - field=models.CharField(max_length=255, verbose_name="verb"), - ), - ] diff --git a/server/vbv_lernwelt/notify/models.py b/server/vbv_lernwelt/notify/models.py index 0592214f..dd00ed99 100644 --- a/server/vbv_lernwelt/notify/models.py +++ b/server/vbv_lernwelt/notify/models.py @@ -10,6 +10,9 @@ class NotificationType(models.TextChoices): class Notification(AbstractNotification): + # UUIDs are not supported by the notifications app... + # id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + notification_type = models.CharField( max_length=32, choices=NotificationType.choices, diff --git a/server/vbv_lernwelt/notify/tests/test_notify_api.py b/server/vbv_lernwelt/notify/tests/test_notify_api.py index 7f10d785..fa9a2863 100644 --- a/server/vbv_lernwelt/notify/tests/test_notify_api.py +++ b/server/vbv_lernwelt/notify/tests/test_notify_api.py @@ -52,7 +52,7 @@ class TestNotificationApi(APITestCase): self.assertTrue( all( [ - self.alice.id == notification["recipient"] + str(self.alice.id) == notification["recipient"] for notification in data["all_list"] ] )