Merged in feature/VBV-438-reflection-per-circle (pull request #158)

Adapt AssignmentCompletion model to include page_id

Approved-by: Elia Bieri
This commit is contained in:
Daniel Egger 2023-07-14 11:28:05 +00:00
commit 5bd8192f05
29 changed files with 377 additions and 149 deletions

View File

@ -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 $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 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 $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 ) {\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: 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 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 $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 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 $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 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: 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"];
/**
* 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 $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 ) {\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 $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 ) {\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: 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"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/

View File

@ -74,6 +74,7 @@ export type AssignmentCompletionObjectType = {
evaluation_submitted_at?: Maybe<Scalars['DateTime']['output']>;
evaluation_user?: Maybe<UserType>;
id: Scalars['ID']['output'];
learning_content_page_id?: Maybe<Scalars['ID']['output']>;
submitted_at?: Maybe<Scalars['DateTime']['output']>;
updated_at: Scalars['DateTime']['output'];
};
@ -247,6 +248,7 @@ export type MutationUpsertAssignmentCompletionArgs = {
course_session_id: Scalars['ID']['input'];
evaluation_grade?: InputMaybe<Scalars['Float']['input']>;
evaluation_points?: InputMaybe<Scalars['Float']['input']>;
learning_content_page_id?: InputMaybe<Scalars['ID']['input']>;
};
/** An object with an ID */
@ -274,6 +276,7 @@ export type QueryAssignmentCompletionArgs = {
assignment_id: Scalars['ID']['input'];
assignment_user_id?: InputMaybe<Scalars['ID']['input']>;
course_session_id: Scalars['ID']['input'];
learning_content_page_id?: InputMaybe<Scalars['ID']['input']>;
};
@ -324,6 +327,7 @@ export type SendFeedbackMutationMutation = { __typename?: 'Mutation', send_feedb
export type UpsertAssignmentCompletionMutationVariables = Exact<{
assignmentId: Scalars['ID']['input'];
courseSessionId: Scalars['ID']['input'];
learningContentId?: InputMaybe<Scalars['ID']['input']>;
assignmentUserId?: InputMaybe<Scalars['ID']['input']>;
completionStatus: AssignmentCompletionStatus;
completionDataString: Scalars['String']['input'];
@ -337,6 +341,7 @@ export type UpsertAssignmentCompletionMutation = { __typename?: 'Mutation', upse
export type AssignmentCompletionQueryQueryVariables = Exact<{
assignmentId: Scalars['ID']['input'];
courseSessionId: Scalars['ID']['input'];
learningContentId?: InputMaybe<Scalars['ID']['input']>;
assignmentUserId?: InputMaybe<Scalars['ID']['input']>;
}>;
@ -352,6 +357,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<SendFeedbackMutationMutation, SendFeedbackMutationMutationVariables>;
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":"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":"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<UpsertAssignmentCompletionMutation, UpsertAssignmentCompletionMutationVariables>;
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":"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"}}}],"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<AssignmentCompletionQueryQuery, AssignmentCompletionQueryQueryVariables>;
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<UpsertAssignmentCompletionMutation, UpsertAssignmentCompletionMutationVariables>;
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<AssignmentCompletionQueryQuery, AssignmentCompletionQueryQueryVariables>;
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<CourseQueryQuery, CourseQueryQueryVariables>;

View File

@ -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!, assignment_user_id: ID): AssignmentCompletionObjectType
assignment_completion(assignment_id: ID!, course_session_id: ID!, learning_content_page_id: ID, assignment_user_id: ID): AssignmentCompletionObjectType
}
type CourseSessionAttendanceCourseType {
@ -177,6 +177,7 @@ type AssignmentCompletionObjectType {
completion_status: AssignmentAssignmentCompletionCompletionStatusChoices!
completion_data: GenericScalar
additional_json_data: JSONString!
learning_content_page_id: ID
}
"""An enumeration."""
@ -212,7 +213,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): AssignmentCompletionMutation
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
}
type SendFeedbackPayload {

View File

@ -4,6 +4,7 @@ export const UPSERT_ASSIGNMENT_COMPLETION_MUTATION = graphql(`
mutation UpsertAssignmentCompletion(
$assignmentId: ID!
$courseSessionId: ID!
$learningContentId: ID
$assignmentUserId: ID
$completionStatus: AssignmentCompletionStatus!
$completionDataString: String!
@ -13,6 +14,7 @@ export const UPSERT_ASSIGNMENT_COMPLETION_MUTATION = graphql(`
upsert_assignment_completion(
assignment_id: $assignmentId
course_session_id: $courseSessionId
learning_content_page_id: $learningContentId
assignment_user_id: $assignmentUserId
completion_status: $completionStatus
completion_data_string: $completionDataString

View File

@ -4,6 +4,7 @@ export const ASSIGNMENT_COMPLETION_QUERY = graphql(`
query assignmentCompletionQuery(
$assignmentId: ID!
$courseSessionId: ID!
$learningContentId: ID
$assignmentUserId: ID
) {
assignment(id: $assignmentId) {
@ -25,6 +26,7 @@ export const ASSIGNMENT_COMPLETION_QUERY = graphql(`
assignment_id: $assignmentId
course_session_id: $courseSessionId
assignment_user_id: $assignmentUserId
learning_content_page_id: $learningContentId
) {
id
completion_status

View File

@ -71,16 +71,15 @@ const assignment = computed(
<template>
<div class="absolute bottom-0 top-0 z-10 w-full bg-white">
<div
v-if="assignment && assignmentCompletion && state.assignmentUser"
class="relative"
>
<div v-if="queryResult.fetching.value"></div>
<div v-else-if="queryResult.error.value">{{ queryResult.error.value }}</div>
<div v-else>
<header
class="relative flex h-12 w-full items-center justify-between border-b border-b-gray-400 bg-white px-4 lg:h-16 lg:px-8"
>
<div class="flex items-center text-gray-900">
<it-icon-assignment class="h-6 w-6"></it-icon-assignment>
<div class="ml-2">Geleitete Fallarbeit: {{ assignment.title }}</div>
<div class="ml-2">Geleitete Fallarbeit: {{ assignment?.title }}</div>
</div>
<button
type="button"
@ -91,7 +90,10 @@ const assignment = computed(
<it-icon-close></it-icon-close>
</button>
</header>
<div
v-if="assignment && assignmentCompletion && state.assignmentUser"
class="relative"
>
<div class="h-content flex">
<div class="h-full w-1/2 overflow-y-auto bg-white">
<!-- Left part content goes here -->
@ -125,6 +127,8 @@ const assignment = computed(
</div>
</div>
</div>
<div v-else>Could not load all data</div>
</div>
</div>
</template>

View File

@ -26,13 +26,13 @@ const upsertAssignmentCompletionMutation = useMutation(
async function startEvaluation() {
log.debug("startEvaluation");
if (props.assignmentCompletion.completion_status !== "EVALUATION_SUBMITTED") {
// noinspection TypeScriptValidateTypes
upsertAssignmentCompletionMutation.executeMutation({
assignmentId: props.assignment.id.toString(),
courseSessionId: courseSession.value.id.toString(),
assignmentUserId: props.assignmentUser.user_id.toString(),
completionStatus: "EVALUATION_IN_PROGRESS",
completionDataString: JSON.stringify({}),
// next line used for urql
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
id: props.assignmentCompletion?.id,

View File

@ -41,7 +41,6 @@ const upsertAssignmentCompletionMutation = useMutation(
);
async function submitEvaluation() {
// noinspection TypeScriptValidateTypes
upsertAssignmentCompletionMutation.executeMutation({
assignmentId: props.assignment.id.toString(),
courseSessionId: courseSession.value.id.toString(),
@ -50,6 +49,7 @@ async function submitEvaluation() {
completionDataString: JSON.stringify({}),
evaluationGrade: grade.value ?? 1,
evaluationPoints: userPoints.value,
// next line used for urql
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
id: props.assignmentCompletion?.id,

View File

@ -65,7 +65,6 @@ const upsertAssignmentCompletionMutation = useMutation(
async function evaluateAssignmentCompletion(completionData: AssignmentCompletionData) {
log.debug("evaluateAssignmentCompletion", completionData);
// noinspection TypeScriptValidateTypes
upsertAssignmentCompletionMutation.executeMutation({
assignmentId: props.assignment.id.toString(),
courseSessionId: courseSession.value.id.toString(),

View File

@ -2,23 +2,29 @@
import ItPersonRow from "@/components/ui/ItPersonRow.vue";
import type { StatusCount, StatusCountKey } from "@/components/ui/ItProgress.vue";
import AssignmentSubmissionProgress from "@/pages/cockpit/assignmentsPage/AssignmentSubmissionProgress.vue";
import type { AssignmentLearningContent } from "@/services/assignmentService";
import {
findAssignmentDetail,
loadAssignmentCompletionStatusData,
} from "@/services/assignmentService";
import { useCockpitStore } from "@/stores/cockpit";
import type { AssignmentCompletionStatus, CourseSession } from "@/types";
import type {
AssignmentCompletionStatus,
CourseSession,
LearningContentAssignment,
} from "@/types";
import dayjs from "dayjs";
import log from "loglevel";
import { computed, onMounted, reactive } from "vue";
const props = defineProps<{
courseSession: CourseSession;
assignment: AssignmentLearningContent;
learningContentAssignment: LearningContentAssignment;
}>();
log.debug("AssignmentDetails created", props.assignment.assignmentId);
log.debug(
"AssignmentDetails created",
props.learningContentAssignment.content_assignment_id
);
const cockpitStore = useCockpitStore();
@ -34,7 +40,7 @@ const state = reactive({
onMounted(async () => {
state.statusByUser = await loadAssignmentCompletionStatusData(
props.assignment.assignmentId,
props.learningContentAssignment.content_assignment_id,
props.courseSession.id
);
});
@ -44,14 +50,14 @@ function submissionStatusForUser(userId: number) {
}
const assignmentDetail = computed(() =>
findAssignmentDetail(props.assignment.assignmentId)
findAssignmentDetail(props.learningContentAssignment.content_assignment_id)
);
</script>
<template>
<div v-if="state.statusByUser.length">
<div class="text-large font-bold">
{{ assignment.title }}
{{ props.learningContentAssignment.title }}
</div>
<div v-if="assignmentDetail">
<span>
@ -66,7 +72,11 @@ const assignmentDetail = computed(() =>
</div>
<div>
<a :href="props.assignment.frontend_url" class="link" target="_blank">
<a
:href="props.learningContentAssignment.frontend_url"
class="link"
target="_blank"
>
Im Circle anzeigen
</a>
</div>
@ -74,7 +84,7 @@ const assignmentDetail = computed(() =>
<div class="mt-4">
<AssignmentSubmissionProgress
:course-session="courseSession"
:assignment="assignment"
:learning-content-assignment="learningContentAssignment"
:show-title="false"
/>
</div>
@ -130,7 +140,7 @@ const assignmentDetail = computed(() =>
<template #link>
<router-link
v-if="submissionStatusForUser(csu.user_id)?.progressStatus === 'SUCCESS'"
:to="`/course/${props.courseSession.course.slug}/cockpit/assignment/${assignment.assignmentId}/${csu.user_id}`"
:to="`/course/${props.courseSession.course.slug}/cockpit/assignment/${learningContentAssignment.content_assignment_id}/${csu.user_id}`"
class="w-full text-right underline"
data-cy="show-results"
>

View File

@ -1,20 +1,26 @@
<script setup lang="ts">
import type { StatusCount, StatusCountKey } from "@/components/ui/ItProgress.vue";
import ItProgress from "@/components/ui/ItProgress.vue";
import type { AssignmentLearningContent } from "@/services/assignmentService";
import { loadAssignmentCompletionStatusData } from "@/services/assignmentService";
import type { AssignmentCompletionStatus, CourseSession } from "@/types";
import type {
AssignmentCompletionStatus,
CourseSession,
LearningContentAssignment,
} from "@/types";
import { countBy } from "lodash";
import log from "loglevel";
import { onMounted, reactive } from "vue";
const props = defineProps<{
courseSession: CourseSession;
assignment: AssignmentLearningContent;
learningContentAssignment: LearningContentAssignment;
showTitle: boolean;
}>();
log.debug("AssignmentSubmissionProgress created", props.assignment.assignmentId);
log.debug(
"AssignmentSubmissionProgress created",
props.learningContentAssignment.content_assignment_id
);
const state = reactive({
statusByUser: [] as {
@ -27,7 +33,7 @@ const state = reactive({
onMounted(async () => {
state.statusByUser = await loadAssignmentCompletionStatusData(
props.assignment.assignmentId,
props.learningContentAssignment.content_assignment_id,
props.courseSession.id
);
@ -41,7 +47,7 @@ onMounted(async () => {
<template>
<div v-if="state.statusByUser.length">
<div v-if="showTitle">
{{ props.assignment.title }}
{{ props.learningContentAssignment.title }}
</div>
<div><ItProgress :status-count="state.progressStatusCount" /></div>
<div class="text-gray-900" :class="{ 'text-gray-900': showTitle }">

View File

@ -1,7 +1,7 @@
<script setup lang="ts">
import { useCurrentCourseSession } from "@/composables";
import AssignmentDetails from "@/pages/cockpit/assignmentsPage/AssignmentDetails.vue";
import { calcAssignmentLearningContents } from "@/services/assignmentService";
import { calcLearningContentAssignments } from "@/services/assignmentService";
import { useLearningPathStore } from "@/stores/learningPath";
import { useUserStore } from "@/stores/user";
import * as log from "loglevel";
@ -21,8 +21,8 @@ onMounted(async () => {
log.debug("AssignmentsPage mounted");
});
const assignments = computed(() => {
return calcAssignmentLearningContents(
const learningContentAssignments = computed(() => {
return calcLearningContentAssignments(
learningPathStore.learningPathForUser(courseSession.value.course.slug, userStore.id)
);
});
@ -47,11 +47,11 @@ const assignments = computed(() => {
</h2>
</header>
<main>
<div v-for="assignment in assignments" :key="assignment.id">
<div v-for="lca in learningContentAssignments" :key="lca.id">
<div class="bg-white p-6">
<AssignmentDetails
:course-session="courseSession"
:assignment="assignment"
:learning-content-assignment="lca"
/>
</div>
</div>

View File

@ -1,6 +1,6 @@
<script setup lang="ts">
import AssignmentSubmissionProgress from "@/pages/cockpit/assignmentsPage/AssignmentSubmissionProgress.vue";
import { calcAssignmentLearningContents } from "@/services/assignmentService";
import { calcLearningContentAssignments } from "@/services/assignmentService";
import { useCockpitStore } from "@/stores/cockpit";
import { useLearningPathStore } from "@/stores/learningPath";
import { useUserStore } from "@/stores/user";
@ -18,9 +18,9 @@ const userStore = useUserStore();
const cockpitStore = useCockpitStore();
const learningPathStore = useLearningPathStore();
const assignments = computed(() => {
const learningContentAssignments = computed(() => {
// TODO: filter by selected circle
return calcAssignmentLearningContents(
return calcLearningContentAssignments(
learningPathStore.learningPathForUser(props.courseSession.course.slug, userStore.id)
);
});
@ -34,11 +34,11 @@ const assignments = computed(() => {
<div>Geleitete Fallarbeiten</div>
</h3>
<div v-for="assignment in assignments" :key="assignment.id" class="mb-4">
<div v-for="lca in learningContentAssignments" :key="lca.id" class="mb-4">
<AssignmentSubmissionProgress
:show-title="true"
:course-session="props.courseSession"
:assignment="assignment"
:learning-content-assignment="lca"
/>
</div>

View File

@ -18,6 +18,7 @@ import { useTranslation } from "i18next-vue";
const props = defineProps<{
assignment: Assignment;
learningContentId: number;
assignmentCompletion?: AssignmentCompletion;
courseSessionId: number;
dueDate: Dayjs;
@ -62,10 +63,10 @@ const onEditTask = (task: AssignmentTask) => {
const onSubmit = async () => {
try {
// noinspection TypeScriptValidateTypes
await upsertAssignmentCompletionMutation.executeMutation({
assignmentId: props.assignment.id.toString(),
courseSessionId: courseSession.value.id.toString(),
learningContentId: props.learningContentId.toString(),
completionDataString: JSON.stringify({}),
completionStatus: "SUBMITTED",
// eslint-disable-next-line @typescript-eslint/ban-ts-comment

View File

@ -17,6 +17,7 @@ import { computed, reactive } from "vue";
const props = defineProps<{
assignmentId: number;
learningContentId: number;
task: AssignmentTask;
assignmentCompletion?: AssignmentCompletion;
}>();
@ -31,10 +32,10 @@ const upsertAssignmentCompletionMutation = useMutation(
async function upsertAssignmentCompletion(completion_data: AssignmentCompletionData) {
try {
// noinspection TypeScriptValidateTypes
await upsertAssignmentCompletionMutation.executeMutation({
assignmentId: props.assignmentId.toString(),
courseSessionId: courseSession.value.id.toString(),
learningContentId: props.learningContentId.toString(),
completionDataString: JSON.stringify(completion_data),
completionStatus: "IN_PROGRESS",
// eslint-disable-next-line @typescript-eslint/ban-ts-comment

View File

@ -40,12 +40,12 @@ const props = defineProps<{
learningContent: LearningContentAssignment;
}>();
// noinspection TypeScriptValidateTypes TODO: because of IntelliJ
const queryResult = useQuery({
query: ASSIGNMENT_COMPLETION_QUERY,
variables: {
courseSessionId: courseSession.value.id.toString(),
assignmentId: props.learningContent.content_assignment_id.toString(),
learningContentId: props.learningContent.id.toString(),
},
pause: true,
});
@ -86,10 +86,10 @@ onMounted(async () => {
// create initial `AssignmentCompletion` first, so that it exists and we don't
// have reactivity problem accessing it.
// noinspection TypeScriptValidateTypes
await upsertAssignmentCompletionMutation.executeMutation({
assignmentId: props.learningContent.content_assignment_id.toString(),
courseSessionId: courseSession.value.id.toString(),
learningContentId: props.learningContent.id.toString(),
completionDataString: JSON.stringify({}),
completionStatus: "IN_PROGRESS",
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
@ -205,6 +205,9 @@ const endBadgeText = computed(() => {
</script>
<template>
<div v-if="queryResult.fetching.value"></div>
<div v-else-if="queryResult.error.value">{{ queryResult.error.value }}</div>
<div v-else>
<div v-if="assignment && assignmentCompletion">
<div class="flex">
<LearningContentMultiLayout
@ -237,12 +240,14 @@ const endBadgeText = computed(() => {
:task="currentTask"
:assignment-id="props.learningContent.content_assignment_id"
:assignment-completion="assignmentCompletion"
:learning-content-id="props.learningContent.id"
></AssignmentTaskView>
<AssignmentSubmissionView
v-else-if="assignmentType === 'CASEWORK' && stepIndex + 1 === numPages"
:due-date="dueDate"
:assignment="assignment"
:assignment-completion="assignmentCompletion"
:learning-content-id="props.learningContent.id"
:course-session-id="courseSession.id"
@edit-task="jumpToTask($event)"
></AssignmentSubmissionView>
@ -262,4 +267,6 @@ const endBadgeText = computed(() => {
</div>
</div>
</div>
<div v-else>Could not load all data</div>
</div>
</template>

View File

@ -140,7 +140,7 @@ const changeViewType = (viewType: ViewType) => {
class="p-6"
:class="useMobileLayout ? 'bg-gray-200' : ''"
>
<LearningPathAppointmentsMock></LearningPathAppointmentsMock>
<!--<LearningPathAppointmentsMock></LearningPathAppointmentsMock>-->
</div>
</div>
</div>

View File

@ -11,33 +11,22 @@ import type {
AssignmentCompletionStatus,
CourseSessionUser,
LearningContentAssignment,
LearningContentInterface,
UserAssignmentCompletionStatus,
} from "@/types";
import { sum } from "d3";
import pick from "lodash/pick";
export interface AssignmentLearningContent extends LearningContentInterface {
assignmentId: number;
}
export function calcAssignmentLearningContents(learningPath?: LearningPath) {
export function calcLearningContentAssignments(learningPath?: LearningPath) {
// TODO: filter by circle
if (!learningPath) return [];
return learningPath.circles.flatMap((circle) => {
const learningContents = circle.flatLearningContents.filter(
return circle.flatLearningContents.filter(
(lc) =>
lc.content_type === "learnpath.LearningContentAssignment" &&
lc.assignment_type === "CASEWORK"
) as LearningContentAssignment[];
return learningContents.map((lc) => {
return {
...lc,
assignmentId: lc.content_assignment_id,
};
});
}) as AssignmentLearningContent[];
}
export async function loadAssignmentCompletionStatusData(
@ -98,7 +87,7 @@ export function findAssignmentDetail(assignmentId: number) {
return undefined;
}
const learningContents = calcAssignmentLearningContents(
const learningContents = calcLearningContentAssignments(
learningPathStore.learningPathForUser(
courseSessionsStore.currentCourseSession.course.slug,
userStore.id
@ -106,7 +95,7 @@ export function findAssignmentDetail(assignmentId: number) {
);
const learningContent = learningContents.find(
(lc) => lc.assignmentId === assignmentId
(lc) => lc.content_assignment_id === assignmentId
);
return courseSessionsStore.findCourseSessionAssignment(learningContent?.id);

View File

@ -2673,7 +2673,7 @@ def create_uk_basis_prep_assignment(course_id=COURSE_UK):
return assignment
def create_uk_reflection(course_id=COURSE_UK, circle_title="Fahrzeug"):
def create_uk_reflection(course_id=COURSE_UK):
assignment_list_page = (
CoursePage.objects.get(course_id=course_id)
.get_children()

View File

@ -3,6 +3,7 @@ import json
import graphene
import structlog
from rest_framework.exceptions import PermissionDenied
from wagtail.models import Page
from vbv_lernwelt.assignment.graphql.types import AssignmentCompletionObjectType
from vbv_lernwelt.assignment.models import Assignment, AssignmentCompletionStatus
@ -20,6 +21,7 @@ class AssignmentCompletionMutation(graphene.Mutation):
class Arguments:
assignment_id = graphene.ID(required=True)
course_session_id = graphene.ID(required=True)
learning_content_page_id = graphene.ID()
assignment_user_id = graphene.ID()
completion_status = graphene.Argument(
@ -37,6 +39,7 @@ class AssignmentCompletionMutation(graphene.Mutation):
info,
assignment_id,
course_session_id,
learning_content_page_id=None,
assignment_user_id=None,
completion_status: AssignmentCompletionStatus = AssignmentCompletionStatus.IN_PROGRESS,
completion_data_string="{}",
@ -56,12 +59,20 @@ class AssignmentCompletionMutation(graphene.Mutation):
raise PermissionDenied()
course_session = CourseSession.objects.get(id=course_session_id)
learning_content_page = None
if learning_content_page_id:
learning_content_page = Page.objects.get(id=learning_content_page_id)
if learning_content_page is None:
learning_content_page = assignment.learningcontentassignment_set.first()
assignment_data = {
"assignment_user": assignment_user,
"assignment": assignment,
"course_session": course_session,
"completion_data": json.loads(completion_data_string),
"completion_status": completion_status,
"learning_content_page": learning_content_page,
}
if completion_status == AssignmentCompletionStatus.SUBMITTED:

View File

@ -23,11 +23,18 @@ class AssignmentQuery(object):
AssignmentCompletionObjectType,
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),
)
def resolve_assignment_completion(
root, info, assignment_id, course_session_id, assignment_user_id=None, **kwargs
root,
info,
assignment_id,
course_session_id,
learning_content_page_id=None,
assignment_user_id=None,
**kwargs,
):
if assignment_user_id is None:
assignment_user_id = info.context.user.id
@ -37,9 +44,17 @@ class AssignmentQuery(object):
) or is_course_session_expert(info.context.user, course_session_id):
course_id = CourseSession.objects.get(id=course_session_id).course_id
if has_course_access(info.context.user, course_id):
if learning_content_page_id is None:
learning_content_page = Assignment.objects.get(
id=assignment_id
).learningcontentassignment_set.first()
if learning_content_page:
learning_content_page_id = learning_content_page.id
return AssignmentCompletion.objects.filter(
assignment_user_id=assignment_user_id,
assignment_id=assignment_id,
learning_content_page_id=learning_content_page_id,
course_session_id=course_session_id,
).first()
raise PermissionDenied()

View File

@ -1,3 +1,4 @@
import graphene
from graphene.types.generic import GenericScalar
from graphene_django import DjangoObjectType
@ -25,6 +26,7 @@ class AssignmentObjectType(DjangoObjectType):
class AssignmentCompletionObjectType(DjangoObjectType):
completion_data = GenericScalar()
learning_content_page_id = graphene.ID(source="learning_content_page_id")
class Meta:
model = AssignmentCompletion
@ -37,6 +39,7 @@ class AssignmentCompletionObjectType(DjangoObjectType):
"assignment_user",
"assignment",
"course_session",
"learning_content_page_id",
"completion_status",
"completion_data",
"evaluation_user",

View File

@ -0,0 +1,48 @@
# 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",
),
),
]

View File

@ -270,12 +270,15 @@ class AssignmentCompletion(models.Model):
assignment_user = models.ForeignKey(User, on_delete=models.CASCADE)
assignment = models.ForeignKey(Assignment, on_delete=models.CASCADE)
course_session = models.ForeignKey("course.CourseSession", on_delete=models.CASCADE)
circle = models.ForeignKey(
"learnpath.Circle",
on_delete=models.CASCADE,
learning_content_page = models.ForeignKey(
Page,
on_delete=models.SET_NULL,
null=True,
blank=True,
default=None,
related_name="+",
help_text="Page reference mostly needed for 'REFLECTION' assignments",
)
completion_status = models.CharField(
@ -290,7 +293,12 @@ class AssignmentCompletion(models.Model):
class Meta:
constraints = [
UniqueConstraint(
fields=["assignment_user", "assignment", "course_session", "circle"],
fields=[
"assignment_user",
"assignment",
"course_session",
"learning_content_page",
],
name="assignment_completion_unique_user_assignment_course_session",
)
]

View File

@ -3,6 +3,7 @@ from gettext import gettext
from django.utils import timezone
from rest_framework import serializers
from wagtail.models import Page
from vbv_lernwelt.assignment.models import (
Assignment,
@ -22,6 +23,7 @@ def update_assignment_completion(
assignment_user: User,
assignment: Assignment,
course_session: CourseSession,
learning_content_page: Page | None = None,
completion_data=None,
completion_status: AssignmentCompletionStatus = AssignmentCompletionStatus.IN_PROGRESS,
evaluation_user: User | None = None,
@ -56,6 +58,9 @@ def update_assignment_completion(
assignment_user_id=assignment_user.id,
assignment_id=assignment.id,
course_session_id=course_session.id,
learning_content_page_id=learning_content_page.id
if learning_content_page
else None,
)
if not is_valid_assignment_completion_status(completion_status):

View File

@ -199,6 +199,7 @@ class AttendanceCourseUserMutationTestCase(GraphQLTestCase):
ac = AssignmentCompletion.objects.create(
assignment_user=self.student,
assignment=self.assignment,
learning_content_page=self.assignment.learningcontentassignment_set.first(),
course_session=self.course_session,
completion_status="SUBMITTED",
submitted_at=timezone.now(),
@ -366,3 +367,84 @@ class AttendanceCourseUserMutationTestCase(GraphQLTestCase):
},
},
)
def test_student_can_upsert_reflection(self):
"""
when upserting a reflection, it will store also the page_id of the learning content
"""
reflection = Assignment.objects.get(slug="test-lehrgang-assignment-reflexion")
reflection_subtasks = reflection.filter_user_subtasks()
reflection_learning_content = reflection.learningcontentassignment_set.first()
self.client.force_login(self.student)
user_text_input = find_first(
reflection_subtasks, pred=lambda x: x["type"] == "user_text_input"
)
completion_data_string = json.dumps(
{
user_text_input["id"]: {
"user_data": {"text": "Hallo via Reflection API"}
},
}
).replace('"', '\\"')
query = f"""
mutation {{
upsert_assignment_completion(
assignment_id: {reflection.id}
course_session_id: {self.course_session.id}
learning_content_page_id: {reflection_learning_content.id}
completion_status: IN_PROGRESS
completion_data_string: "{completion_data_string}"
) {{
assignment_completion {{
id
completion_status
completion_data
assignment_user {{ id }}
assignment {{ id }}
learning_content_page_id
}}
}}
}}
"""
response = self.query(query)
self.assertResponseNoErrors(response)
data = json.loads(response.content)["data"]["upsert_assignment_completion"][
"assignment_completion"
]
print(data)
self.assertEqual(data["assignment_user"]["id"], str(self.student.id))
self.assertEqual(data["assignment"]["id"], str(reflection.id))
self.assertEqual(data["completion_status"], "IN_PROGRESS")
self.assertEqual(
data["learning_content_page_id"], str(reflection_learning_content.id)
)
self.assertDictEqual(
data["completion_data"],
{
user_text_input["id"]: {
"user_data": {"text": "Hallo via Reflection API"}
},
},
)
# check DB data
db_entry = AssignmentCompletion.objects.get(
assignment_user=self.student,
course_session_id=self.course_session.id,
assignment_id=reflection.id,
learning_content_page_id=reflection_learning_content.id,
)
self.assertEqual(db_entry.completion_status, "IN_PROGRESS")
self.assertDictEqual(
db_entry.completion_data,
{
user_text_input["id"]: {
"user_data": {"text": "Hallo via Reflection API"}
},
},
)

View File

@ -12,6 +12,7 @@ from wagtail.rich_text import RichText
from vbv_lernwelt.assignment.creators.create_assignments import (
create_uk_fahrzeug_casework,
create_uk_fahrzeug_prep_assignment,
create_uk_reflection,
)
from vbv_lernwelt.assignment.models import Assignment, AssignmentCompletionStatus
from vbv_lernwelt.assignment.services import update_assignment_completion
@ -85,6 +86,7 @@ def create_test_course(include_uk=True, include_vv=True, with_sessions=False):
)
create_uk_fahrzeug_casework(course_id=COURSE_TEST_ID)
create_uk_fahrzeug_prep_assignment(course_id=COURSE_TEST_ID)
create_uk_reflection(course_id=COURSE_TEST_ID)
create_test_learning_path(include_uk=include_uk, include_vv=include_vv)
create_test_media_library()
@ -182,6 +184,7 @@ def create_test_assignment_submitted_data(assignment, course_session, user):
assignment_user=user,
assignment=assignment,
course_session=course_session,
learning_content_page=assignment.learningcontentassignment_set.first(),
completion_data={
subtask["id"]: {
"user_data": {"text": user_text},
@ -192,6 +195,7 @@ def create_test_assignment_submitted_data(assignment, course_session, user):
assignment_user=user,
assignment=assignment,
course_session=course_session,
learning_content_page=assignment.learningcontentassignment_set.first(),
completion_status=AssignmentCompletionStatus.SUBMITTED,
)
@ -328,10 +332,14 @@ damit du erfolgreich mit deinem Lernpfad (durch-)starten kannst.
)
LearningSequenceFactory(title="Transfer", parent=circle, icon="it-icon-ls-end")
LearningUnitFactory(title="Transfer", parent=circle)
LearningContentPlaceholderFactory(
LearningContentAssignmentFactory(
title="Reflexion",
assignment_type="REFLECTION",
parent=circle,
)
content_assignment=Assignment.objects.get(
slug__startswith=f"test-lehrgang-assignment-reflexion"
),
),
LearningContentAssignmentFactory(
title="Überprüfen einer Motorfahrzeug-Versicherungspolice",
parent=circle,

View File

@ -458,6 +458,7 @@ def create_course_uk_de_assignment_completion_data(assignment, course_session, u
update_assignment_completion(
assignment_user=user,
assignment=assignment,
learning_content_page=assignment.learningcontentassignment_set.first(),
course_session=course_session,
completion_data={
subtask["id"]: {
@ -468,6 +469,7 @@ def create_course_uk_de_assignment_completion_data(assignment, course_session, u
update_assignment_completion(
assignment_user=user,
assignment=assignment,
learning_content_page=assignment.learningcontentassignment_set.first(),
course_session=course_session,
completion_status=AssignmentCompletionStatus.SUBMITTED,
)

View File

@ -0,0 +1,19 @@
# 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),
),
]