Adapt code to user more of the codegen generated typescript types

This commit is contained in:
Daniel Egger 2023-10-12 10:35:17 +02:00
parent 6510d74549
commit 2eddb93be5
27 changed files with 588 additions and 654 deletions

2
.gitignore vendored
View File

@ -284,4 +284,4 @@ git-crypt-encrypted-files-check.txt
/server/vbv_lernwelt/static/storybook
/server/vbv_lernwelt/templates/vue/index.html
/server/vbv_lernwelt/media
/client/src/gql/minifiedSchema.json
/client/src/gql/dist/minifiedSchema.json

View File

@ -11,7 +11,13 @@ const config: CodegenConfig = {
"./src/gql/": {
preset: "client",
config: {
// avoidOptionals: true,
useTypeImports: true,
scalars: {
ID: "string",
UUID: "string",
DateTime: "string",
},
},
plugins: [],
},

View File

@ -8,4 +8,4 @@ const schema = readFileSync("./src/gql/schema.graphql", "utf-8");
const minifiedSchema = minifyIntrospectionQuery(getIntrospectedSchema(schema));
// Write the minified schema to a new file
writeFileSync("./src/gql/minifiedSchema.json", JSON.stringify(minifiedSchema));
writeFileSync("./src/gql/dist/minifiedSchema.json", JSON.stringify(minifiedSchema));

View File

@ -16,7 +16,8 @@
"storybook": "storybook dev -p 6006",
"tailwind": "tailwindcss -i tailwind.css -o ../server/vbv_lernwelt/static/css/tailwind.css --watch",
"test": "vitest run",
"typecheck": "npm run codegen && vue-tsc --noEmit -p tsconfig.app.json --composite false"
"typecheck": "npm run codegen && vue-tsc --noEmit -p tsconfig.app.json --composite false",
"typecheck-only": "vue-tsc --noEmit -p tsconfig.app.json --composite false"
},
"dependencies": {
"@headlessui/tailwindcss": "^0.1.3",

View File

@ -3,7 +3,7 @@ import dayjs from "dayjs";
import LocalizedFormat from "dayjs/plugin/localizedFormat";
import i18next from "i18next";
export const formatDueDate = (start: string, end?: string) => {
export const formatDueDate = (start: string, end?: string | null) => {
dayjs.extend(LocalizedFormat);
const startDayjs = dayjs(start);
const startDateString = getDateString(startDayjs);

View File

@ -56,19 +56,19 @@ export function useCourseSessionDetailQuery(courSessionId?: string) {
function findAssignment(learningContentId: string) {
return (courseSessionDetail.value?.assignments ?? []).find((a) => {
return a.learning_content.id === learningContentId;
return a.learning_content?.id === learningContentId;
});
}
function findEdoniqTest(learningContentId: string) {
return (courseSessionDetail.value?.edoniq_tests ?? []).find((e) => {
return e.learning_content.id === learningContentId;
return e.learning_content?.id === learningContentId;
});
}
function findAttendanceCourse(learningContentId: string) {
return (courseSessionDetail.value?.attendance_courses ?? []).find((e) => {
return e.learning_content.id === learningContentId;
return e.learning_content?.id === learningContentId;
});
}

0
client/src/gql/dist/.gitkeep vendored Normal file
View File

View File

@ -18,7 +18,6 @@ const documents = {
"\n fragment CoursePageFields on CoursePageInterface {\n title\n id\n slug\n content_type\n frontend_url\n }\n": types.CoursePageFieldsFragmentDoc,
"\n query attendanceCheckQuery($courseSessionId: ID!) {\n course_session_attendance_course(id: $courseSessionId) {\n id\n attendance_user_list {\n user_id\n status\n }\n }\n }\n": types.AttendanceCheckQueryDocument,
"\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n needs_expert_evaluation\n max_points\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 competence_certificate {\n ...CoursePageFields\n }\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_points\n evaluation_max_points\n evaluation_passed\n edoniq_extended_time_flag\n completion_data\n task_completion_data\n }\n }\n": types.AssignmentCompletionQueryDocument,
"\n query courseQuery($courseId: ID!) {\n course(id: $courseId) {\n id\n slug\n title\n category_name\n learning_path {\n id\n }\n }\n }\n": types.CourseQueryDocument,
"\n query competenceCertificateQuery($courseSlug: String!, $courseSessionId: ID!) {\n competence_certificate_list(course_slug: $courseSlug) {\n ...CoursePageFields\n competence_certificates {\n ...CoursePageFields\n assignments {\n ...CoursePageFields\n assignment_type\n max_points\n completion(course_session_id: $courseSessionId) {\n id\n completion_status\n submitted_at\n evaluation_points\n evaluation_max_points\n evaluation_passed\n }\n learning_content {\n ...CoursePageFields\n circle {\n ...CoursePageFields\n }\n }\n }\n }\n }\n }\n": types.CompetenceCertificateQueryDocument,
"\n query courseSessionDetail($courseSessionId: ID!) {\n course_session(id: $courseSessionId) {\n id\n title\n course {\n id\n title\n slug\n }\n users {\n id\n user_id\n first_name\n last_name\n email\n avatar_url\n role\n circles {\n id\n title\n slug\n }\n }\n attendance_courses {\n id\n location\n trainer\n due_date {\n id\n start\n end\n }\n learning_content_id\n learning_content {\n id\n title\n circle {\n id\n title\n slug\n }\n }\n }\n assignments {\n id\n submission_deadline {\n id\n start\n }\n evaluation_deadline {\n id\n start\n }\n learning_content {\n id\n title\n content_assignment {\n id\n title\n assignment_type\n }\n }\n }\n edoniq_tests {\n id\n deadline {\n id\n start\n end\n }\n learning_content {\n id\n title\n content_assignment {\n id\n title\n assignment_type\n }\n }\n }\n }\n }\n": types.CourseSessionDetailDocument,
"\n query learningPathQuery($slug: String!) {\n learning_path(slug: $slug) {\n ...CoursePageFields\n topics {\n is_visible\n ...CoursePageFields\n circles {\n ...CoursePageFields\n learning_sequences {\n icon\n ...CoursePageFields\n learning_units {\n evaluate_url\n ...CoursePageFields\n learning_contents {\n ...CoursePageFields\n ... on LearningContentAssignmentObjectType {\n assignment_type\n content_assignment {\n id\n }\n }\n }\n }\n }\n }\n }\n }\n }\n": types.LearningPathQueryDocument,
@ -59,10 +58,6 @@ export function graphql(source: "\n query attendanceCheckQuery($courseSessionId
* 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: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n needs_expert_evaluation\n max_points\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 competence_certificate {\n ...CoursePageFields\n }\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_points\n evaluation_max_points\n evaluation_passed\n edoniq_extended_time_flag\n completion_data\n task_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 needs_expert_evaluation\n max_points\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 competence_certificate {\n ...CoursePageFields\n }\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_points\n evaluation_max_points\n evaluation_passed\n edoniq_extended_time_flag\n completion_data\n task_completion_data\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 courseQuery($courseId: ID!) {\n course(id: $courseId) {\n id\n slug\n title\n category_name\n learning_path {\n id\n }\n }\n }\n"): (typeof documents)["\n query courseQuery($courseId: ID!) {\n course(id: $courseId) {\n id\n slug\n title\n category_name\n learning_path {\n id\n }\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/

File diff suppressed because one or more lines are too long

View File

@ -21,12 +21,12 @@ type Query {
}
type LearningPathObjectType implements CoursePageInterface {
id: ID
id: ID!
path: String!
depth: Int!
numchild: Int!
translation_key: String
live: Boolean
translation_key: String!
live: Boolean!
has_unpublished_changes: Boolean!
first_published_at: DateTime
last_published_at: DateTime
@ -35,13 +35,13 @@ type LearningPathObjectType implements CoursePageInterface {
expired: Boolean!
locked: Boolean!
locked_at: DateTime
locked_by: UserType
title: String
locked_by: UserObjectType
title: String!
draft_title: String!
slug: String
content_type: String
slug: String!
content_type: String!
url_path: String!
owner: UserType
owner: UserObjectType
"""
Der Titel der Seite, dargestellt in Suchmaschinen-Ergebnissen als die verlinkte Überschrift.
@ -58,20 +58,20 @@ type LearningPathObjectType implements CoursePageInterface {
"""
search_description: String!
latest_revision_created_at: DateTime
frontend_url: String
frontend_url: String!
circle: CircleObjectType
course: CourseObjectType
topics: [TopicObjectType]
}
interface CoursePageInterface {
id: ID
title: String
slug: String
content_type: String
live: Boolean
translation_key: String
frontend_url: String
id: ID!
title: String!
slug: String!
content_type: String!
live: Boolean!
translation_key: String!
frontend_url: String!
circle: CircleObjectType
course: CourseObjectType
}
@ -79,13 +79,13 @@ interface CoursePageInterface {
type CircleObjectType implements CoursePageInterface {
description: String!
goals: String!
id: ID
title: String
slug: String
content_type: String
live: Boolean
translation_key: String
frontend_url: String
id: ID!
title: String!
slug: String!
content_type: String!
live: Boolean!
translation_key: String!
frontend_url: String!
circle: CircleObjectType
course: CourseObjectType
learning_sequences: [LearningSequenceObjectType]
@ -96,46 +96,45 @@ type CourseObjectType {
title: String!
category_name: String!
slug: String!
learning_path: LearningPathObjectType
}
type LearningSequenceObjectType implements CoursePageInterface {
icon: String!
id: ID
title: String
slug: String
content_type: String
live: Boolean
translation_key: String
frontend_url: String
id: ID!
title: String!
slug: String!
content_type: String!
live: Boolean!
translation_key: String!
frontend_url: String!
circle: CircleObjectType
course: CourseObjectType
learning_units: [LearningUnitObjectType]
}
type LearningUnitObjectType implements CoursePageInterface {
id: ID
title: String
slug: String
content_type: String
live: Boolean
translation_key: String
frontend_url: String
id: ID!
title: String!
slug: String!
content_type: String!
live: Boolean!
translation_key: String!
frontend_url: String!
circle: CircleObjectType
course: CourseObjectType
learning_contents: [LearningContentInterface]
evaluate_url: String
learning_contents: [LearningContentInterface!]!
evaluate_url: String!
}
interface LearningContentInterface {
id: ID
title: String
slug: String
content_type: String
live: Boolean
translation_key: String
frontend_url: String
circle: CircleObjectType
id: ID!
title: String!
slug: String!
content_type: String!
live: Boolean!
translation_key: String!
frontend_url: String!
circle: CircleObjectType!
course: CourseObjectType
minutes: Int
description: String
@ -149,7 +148,7 @@ value as specified by
"""
scalar DateTime
type UserType {
type UserObjectType {
"""
Erforderlich. 150 Zeichen oder weniger. Nur Buchstaben, Ziffern und @/./+/-/_.
"""
@ -182,27 +181,27 @@ enum CoreUserLanguageChoices {
type TopicObjectType implements CoursePageInterface {
is_visible: Boolean!
id: ID
title: String
slug: String
content_type: String
live: Boolean
translation_key: String
frontend_url: String
id: ID!
title: String!
slug: String!
content_type: String!
live: Boolean!
translation_key: String!
frontend_url: String!
circle: CircleObjectType
course: CourseObjectType
circles: [CircleObjectType]
}
type LearningContentMediaLibraryObjectType implements CoursePageInterface & LearningContentInterface {
id: ID
title: String
slug: String
content_type: String
live: Boolean
translation_key: String
frontend_url: String
circle: CircleObjectType
id: ID!
title: String!
slug: String!
content_type: String!
live: Boolean!
translation_key: String!
frontend_url: String!
circle: CircleObjectType!
course: CourseObjectType
minutes: Int
description: String
@ -212,14 +211,14 @@ type LearningContentMediaLibraryObjectType implements CoursePageInterface & Lear
type LearningContentAssignmentObjectType implements CoursePageInterface & LearningContentInterface {
content_assignment: AssignmentObjectType!
assignment_type: LearnpathLearningContentAssignmentAssignmentTypeChoices!
id: ID
title: String
slug: String
content_type: String
live: Boolean
translation_key: String
frontend_url: String
circle: CircleObjectType
id: ID!
title: String!
slug: String!
content_type: String!
live: Boolean!
translation_key: String!
frontend_url: String!
circle: CircleObjectType!
course: CourseObjectType
minutes: Int
description: String
@ -246,13 +245,13 @@ type AssignmentObjectType implements CoursePageInterface {
"""URL zum Beurteilungsinstrument"""
evaluation_document_url: String!
id: ID
title: String
slug: String
content_type: String
live: Boolean
translation_key: String
frontend_url: String
id: ID!
title: String!
slug: String!
content_type: String!
live: Boolean!
translation_key: String!
frontend_url: String!
circle: CircleObjectType
course: CourseObjectType
tasks: JSONStreamField
@ -282,16 +281,16 @@ enum AssignmentAssignmentAssignmentTypeChoices {
}
type CompetenceCertificateObjectType implements CoursePageInterface {
id: ID
title: String
slug: String
content_type: String
live: Boolean
translation_key: String
frontend_url: String
id: ID!
title: String!
slug: String!
content_type: String!
live: Boolean!
translation_key: String!
frontend_url: String!
circle: CircleObjectType
course: CourseObjectType
assignments: [AssignmentObjectType]
assignments: [AssignmentObjectType!]!
}
scalar JSONStreamField
@ -302,12 +301,12 @@ type AssignmentCompletionObjectType {
updated_at: DateTime!
submitted_at: DateTime
evaluation_submitted_at: DateTime
evaluation_user: UserType
evaluation_user: UserObjectType
evaluation_points: Float
evaluation_max_points: Float
evaluation_passed: Boolean
edoniq_extended_time_flag: Boolean!
assignment_user: UserType!
assignment_user: UserObjectType!
assignment: AssignmentObjectType!
course_session: CourseSessionObjectType!
completion_status: AssignmentAssignmentCompletionCompletionStatusChoices!
@ -325,11 +324,10 @@ type CourseSessionObjectType {
title: String!
start_date: Date
end_date: Date
attendance_courses: [CourseSessionAttendanceCourseObjectType]
assignments: [CourseSessionAssignmentObjectType]
edoniq_tests: [CourseSessionEdoniqTestObjectType]
documents: [CircleDocumentObjectType]
users: [CourseSessionUserObjectsType]
attendance_courses: [CourseSessionAttendanceCourseObjectType!]!
assignments: [CourseSessionAssignmentObjectType!]!
edoniq_tests: [CourseSessionEdoniqTestObjectType!]!
users: [CourseSessionUserObjectsType!]!
}
"""
@ -341,7 +339,7 @@ scalar Date
type CourseSessionAttendanceCourseObjectType {
id: ID!
learning_content: LearningContentAttendanceCourseObjectType
learning_content: LearningContentAttendanceCourseObjectType!
due_date: DueDateObjectType
location: String!
trainer: String!
@ -351,14 +349,14 @@ type CourseSessionAttendanceCourseObjectType {
}
type LearningContentAttendanceCourseObjectType implements CoursePageInterface & LearningContentInterface {
id: ID
title: String
slug: String
content_type: String
live: Boolean
translation_key: String
frontend_url: String
circle: CircleObjectType
id: ID!
title: String!
slug: String!
content_type: String!
live: Boolean!
translation_key: String!
frontend_url: String!
circle: CircleObjectType!
course: CourseObjectType
minutes: Int
description: String
@ -414,61 +412,64 @@ enum AttendanceUserStatus {
type CourseSessionAssignmentObjectType {
id: ID!
learning_content: LearningContentAssignmentObjectType
learning_content: LearningContentAssignmentObjectType!
submission_deadline: DueDateObjectType
evaluation_deadline: DueDateObjectType
course_session_id: ID
learning_content_id: ID
course_session_id: ID!
learning_content_id: ID!
}
type CourseSessionEdoniqTestObjectType {
id: ID!
learning_content: LearningContentEdoniqTestObjectType
learning_content: LearningContentEdoniqTestObjectType!
deadline: DueDateObjectType
course_session_id: ID
learning_content_id: ID
course_session_id: ID!
learning_content_id: ID!
}
type LearningContentEdoniqTestObjectType implements CoursePageInterface & LearningContentInterface {
content_assignment: AssignmentObjectType
id: ID
title: String
slug: String
content_type: String
live: Boolean
translation_key: String
frontend_url: String
circle: CircleObjectType
id: ID!
title: String!
slug: String!
content_type: String!
live: Boolean!
translation_key: String!
frontend_url: String!
circle: CircleObjectType!
course: CourseObjectType
minutes: Int
description: String
content: String
}
type CircleDocumentObjectType {
id: UUID!
name: String!
course_session: CourseSessionObjectType!
learning_sequence: LearningSequenceObjectType!
file_name: String
url: String
}
type CourseSessionUserObjectsType {
id: UUID!
role: String
user_id: UUID
first_name: String
last_name: String
email: String
avatar_url: String
circles: [CourseSessionUserExpertCircleType]
role: CourseCourseSessionUserRoleChoices!
user_id: UUID!
first_name: String!
last_name: String!
email: String!
avatar_url: String!
circles: [CourseSessionUserExpertCircleType!]!
}
"""An enumeration."""
enum CourseCourseSessionUserRoleChoices {
"""Teilnehmer"""
MEMBER
"""Experte/Trainer"""
EXPERT
"""Lernbegleitung"""
TUTOR
}
type CourseSessionUserExpertCircleType {
id: ID
title: String
slug: String
id: ID!
title: String!
slug: String!
}
"""An enumeration."""
@ -520,14 +521,14 @@ enum LearnpathLearningContentAssignmentAssignmentTypeChoices {
}
type LearningContentFeedbackObjectType implements CoursePageInterface & LearningContentInterface {
id: ID
title: String
slug: String
content_type: String
live: Boolean
translation_key: String
frontend_url: String
circle: CircleObjectType
id: ID!
title: String!
slug: String!
content_type: String!
live: Boolean!
translation_key: String!
frontend_url: String!
circle: CircleObjectType!
course: CourseObjectType
minutes: Int
description: String
@ -535,14 +536,14 @@ type LearningContentFeedbackObjectType implements CoursePageInterface & Learning
}
type LearningContentLearningModuleObjectType implements CoursePageInterface & LearningContentInterface {
id: ID
title: String
slug: String
content_type: String
live: Boolean
translation_key: String
frontend_url: String
circle: CircleObjectType
id: ID!
title: String!
slug: String!
content_type: String!
live: Boolean!
translation_key: String!
frontend_url: String!
circle: CircleObjectType!
course: CourseObjectType
minutes: Int
description: String
@ -550,14 +551,14 @@ type LearningContentLearningModuleObjectType implements CoursePageInterface & Le
}
type LearningContentPlaceholderObjectType implements CoursePageInterface & LearningContentInterface {
id: ID
title: String
slug: String
content_type: String
live: Boolean
translation_key: String
frontend_url: String
circle: CircleObjectType
id: ID!
title: String!
slug: String!
content_type: String!
live: Boolean!
translation_key: String!
frontend_url: String!
circle: CircleObjectType!
course: CourseObjectType
minutes: Int
description: String
@ -565,14 +566,14 @@ type LearningContentPlaceholderObjectType implements CoursePageInterface & Learn
}
type LearningContentRichTextObjectType implements CoursePageInterface & LearningContentInterface {
id: ID
title: String
slug: String
content_type: String
live: Boolean
translation_key: String
frontend_url: String
circle: CircleObjectType
id: ID!
title: String!
slug: String!
content_type: String!
live: Boolean!
translation_key: String!
frontend_url: String!
circle: CircleObjectType!
course: CourseObjectType
minutes: Int
description: String
@ -580,14 +581,14 @@ type LearningContentRichTextObjectType implements CoursePageInterface & Learning
}
type LearningContentVideoObjectType implements CoursePageInterface & LearningContentInterface {
id: ID
title: String
slug: String
content_type: String
live: Boolean
translation_key: String
frontend_url: String
circle: CircleObjectType
id: ID!
title: String!
slug: String!
content_type: String!
live: Boolean!
translation_key: String!
frontend_url: String!
circle: CircleObjectType!
course: CourseObjectType
minutes: Int
description: String
@ -595,14 +596,14 @@ type LearningContentVideoObjectType implements CoursePageInterface & LearningCon
}
type LearningContentDocumentListObjectType implements CoursePageInterface & LearningContentInterface {
id: ID
title: String
slug: String
content_type: String
live: Boolean
translation_key: String
frontend_url: String
circle: CircleObjectType
id: ID!
title: String!
slug: String!
content_type: String!
live: Boolean!
translation_key: String!
frontend_url: String!
circle: CircleObjectType!
course: CourseObjectType
minutes: Int
description: String
@ -610,12 +611,12 @@ type LearningContentDocumentListObjectType implements CoursePageInterface & Lear
}
type CompetenceCertificateListObjectType implements CoursePageInterface {
id: ID
id: ID!
path: String!
depth: Int!
numchild: Int!
translation_key: String
live: Boolean
translation_key: String!
live: Boolean!
has_unpublished_changes: Boolean!
first_published_at: DateTime
last_published_at: DateTime
@ -624,13 +625,13 @@ type CompetenceCertificateListObjectType implements CoursePageInterface {
expired: Boolean!
locked: Boolean!
locked_at: DateTime
locked_by: UserType
title: String
locked_by: UserObjectType
title: String!
draft_title: String!
slug: String
content_type: String
slug: String!
content_type: String!
url_path: String!
owner: UserType
owner: UserObjectType
"""
Der Titel der Seite, dargestellt in Suchmaschinen-Ergebnissen als die verlinkte Überschrift.
@ -647,10 +648,10 @@ type CompetenceCertificateListObjectType implements CoursePageInterface {
"""
search_description: String!
latest_revision_created_at: DateTime
frontend_url: String
frontend_url: String!
circle: CircleObjectType
course: CourseObjectType
competence_certificates: [CompetenceCertificateObjectType]
competence_certificates: [CompetenceCertificateObjectType!]!
}
type Mutation {

View File

@ -9,11 +9,11 @@ export const AttendanceUserInputType = "AttendanceUserInputType";
export const AttendanceUserObjectType = "AttendanceUserObjectType";
export const AttendanceUserStatus = "AttendanceUserStatus";
export const Boolean = "Boolean";
export const CircleDocumentObjectType = "CircleDocumentObjectType";
export const CircleObjectType = "CircleObjectType";
export const CompetenceCertificateListObjectType = "CompetenceCertificateListObjectType";
export const CompetenceCertificateObjectType = "CompetenceCertificateObjectType";
export const CoreUserLanguageChoices = "CoreUserLanguageChoices";
export const CourseCourseSessionUserRoleChoices = "CourseCourseSessionUserRoleChoices";
export const CourseObjectType = "CourseObjectType";
export const CoursePageInterface = "CoursePageInterface";
export const CourseSessionAssignmentObjectType = "CourseSessionAssignmentObjectType";
@ -54,4 +54,4 @@ export const SendFeedbackMutation = "SendFeedbackMutation";
export const String = "String";
export const TopicObjectType = "TopicObjectType";
export const UUID = "UUID";
export const UserType = "UserType";
export const UserObjectType = "UserObjectType";

View File

@ -2,7 +2,7 @@
// @ts-ignore
import { cacheExchange } from "@urql/exchange-graphcache";
import { Client, fetchExchange } from "@urql/vue";
import schema from "../gql/minifiedSchema.json";
import schema from "../gql/dist/minifiedSchema.json";
import {
AssignmentCompletionMutation,
AssignmentCompletionObjectType,

View File

@ -76,20 +76,6 @@ export const ASSIGNMENT_COMPLETION_QUERY = graphql(`
}
`);
export const COURSE_QUERY = graphql(`
query courseQuery($courseId: ID!) {
course(id: $courseId) {
id
slug
title
category_name
learning_path {
id
}
}
}
`);
export const COMPETENCE_NAVI_CERTIFICATE_QUERY = graphql(`
query competenceCertificateQuery($courseSlug: String!, $courseSessionId: ID!) {
competence_certificate_list(course_slug: $courseSlug) {

View File

@ -65,7 +65,7 @@ const assignmentDetail = computed(() => {
});
const dueDate = computed(() =>
dayjs(assignmentDetail.value?.evaluation_deadline.start)
dayjs(assignmentDetail.value?.evaluation_deadline?.start)
);
const inEvaluationTask = computed(

View File

@ -81,7 +81,7 @@ const courseSessionDetailResult = useCourseSessionDetailQuery();
const evaluationUser = computed(() => {
if (props.assignmentCompletion.evaluation_user) {
return courseSessionDetailResult.findUser(
props.assignmentCompletion.evaluation_user
props.assignmentCompletion.evaluation_user?.id
);
}
return undefined;

View File

@ -33,7 +33,7 @@ const presenceCoursesDropdownOptions = computed(() => {
id: attendanceCourse.id,
name: `${t("Präsenzkurs")} ${
attendanceCourse.learning_content.circle.title
} ${dayjs(attendanceCourse.due_date.start).format("DD.MM.YYYY")}`,
} ${dayjs(attendanceCourse.due_date?.start).format("DD.MM.YYYY")}`,
} as DropdownSelectable)
);
});

View File

@ -7,7 +7,7 @@ import dayjs from "dayjs";
interface Props {
assignment: Assignment;
submissionDeadlineStart?: string;
submissionDeadlineStart?: string | null;
}
const props = withDefaults(defineProps<Props>(), {

View File

@ -22,7 +22,7 @@ const props = defineProps<{
learningContentId: string;
assignmentCompletion?: AssignmentCompletion;
courseSessionId: string;
submissionDeadlineStart?: string;
submissionDeadlineStart?: string | null;
}>();
const emit = defineEmits<{

View File

@ -5,8 +5,8 @@
<p class="grid-in-value">
{{
formatDueDate(
props.attendanceCourse.due_date.start,
props.attendanceCourse.due_date.end
props.attendanceCourse.due_date?.start ?? "",
props.attendanceCourse.due_date?.end
)
}}
</p>
@ -28,11 +28,11 @@
<script setup lang="ts">
import { formatDueDate } from "@/components/dueDates/dueDatesUtils";
import type { CourseSessionAttendanceCourse } from "@/types";
import { computed } from "vue";
import type { CourseSessionAttendanceCourseObjectType } from "@/gql/graphql";
export interface Props {
attendanceCourse: CourseSessionAttendanceCourse;
attendanceCourse: CourseSessionAttendanceCourseObjectType;
}
const props = defineProps<Props>();

View File

@ -11,10 +11,7 @@ import { ASSIGNMENT_COMPLETION_QUERY } from "@/graphql/queries";
import { useCourseSessionDetailQuery, useCurrentCourseSession } from "@/composables";
import dayjs from "dayjs";
import ItSuccessAlert from "@/components/ui/ItSuccessAlert.vue";
import {
formatDueDate,
getDateString,
} from "../../../../components/dueDates/dueDatesUtils";
import { formatDueDate, getDateString } from "@/components/dueDates/dueDatesUtils";
const { t } = useTranslation();
@ -52,9 +49,12 @@ const extendedTimeTest = ref(false);
const deadlineInPast = computed(() => {
// with 16 minutes buffer
return dayjs(courseSessionEdoniqTest.value?.deadline.start)
.add(16, "minute")
.isBefore(dayjs());
if (courseSessionEdoniqTest.value?.deadline?.start) {
return dayjs(courseSessionEdoniqTest.value?.deadline.start)
.add(16, "minute")
.isBefore(dayjs());
}
return false;
});
async function startTest() {
@ -89,7 +89,7 @@ async function startTest() {
<p class="mt-2 text-lg">
{{
$t("edoniqTest.submitDateDescription", {
x: formatDueDate(courseSessionEdoniqTest.deadline.start),
x: formatDueDate(courseSessionEdoniqTest?.deadline?.start ?? ""),
})
}}
</p>
@ -157,7 +157,7 @@ async function startTest() {
</div>
<div v-else>
{{ $t("a.Abgabetermin") }}:
{{ getDateString(dayjs(courseSessionEdoniqTest?.deadline.start)) }}
{{ getDateString(dayjs(courseSessionEdoniqTest?.deadline?.start)) }}
</div>
</div>
</div>

View File

@ -1,4 +1,10 @@
import type { AssignmentCompletionStatus as AssignmentCompletionStatusGenerated } from "@/gql/graphql";
import type {
AssignmentCompletionObjectType,
AssignmentCompletionStatus as AssignmentCompletionStatusGenerated,
CourseCourseSessionUserRoleChoices,
CourseSessionObjectType,
CourseSessionUserObjectsType,
} from "@/gql/graphql";
import type { Circle } from "@/services/circle";
import type { Component } from "vue";
@ -471,46 +477,46 @@ export interface CircleDocument {
};
}
export interface CourseSessionAttendanceCourse {
id: string;
due_date: SimpleDueDate;
location: string;
trainer: string;
circle_title: string;
learning_content: {
id: string;
title: string;
circle: CircleLight;
};
}
export interface CourseSessionAssignment {
id: string;
submission_deadline: SimpleDueDate;
evaluation_deadline: SimpleDueDate;
learning_content: {
id: string;
content_assignment: {
id: string;
title: string;
assignment_type: AssignmentType;
};
};
}
export interface CourseSessionEdoniqTest {
id: number;
course_session_id: string;
deadline: SimpleDueDate;
learning_content: {
id: string;
content_assignment: {
id: string;
title: string;
assignment_type: AssignmentType;
};
};
}
// export interface CourseSessionAttendanceCourse {
// id: string;
// due_date: SimpleDueDate;
// location: string;
// trainer: string;
// circle_title: string;
// learning_content: {
// id: string;
// title: string;
// circle: CircleLight;
// };
// }
//
// export interface CourseSessionAssignment {
// id: string;
// submission_deadline: SimpleDueDate;
// evaluation_deadline: SimpleDueDate;
// learning_content: {
// id: string;
// content_assignment: {
// id: string;
// title: string;
// assignment_type: AssignmentType;
// };
// };
// }
//
// export interface CourseSessionEdoniqTest {
// id: number;
// course_session_id: string;
// deadline: SimpleDueDate;
// learning_content: {
// id: string;
// content_assignment: {
// id: string;
// title: string;
// assignment_type: AssignmentType;
// };
// };
// }
export interface CourseSession {
id: string;
@ -523,46 +529,15 @@ export interface CourseSession {
due_dates: DueDate[];
}
export type Role = "MEMBER" | "EXPERT" | "TUTOR";
export type Role = CourseCourseSessionUserRoleChoices;
export interface CourseSessionUser {
user_id: string;
first_name: string;
last_name: string;
email: string;
avatar_url: string;
role: Role;
circles: {
id: string;
title: string;
slug: string;
translation_key: string;
}[];
}
export type CourseSessionUser = CourseSessionUserObjectsType;
export interface ExpertSessionUser extends CourseSessionUser {
role: "EXPERT";
circles: {
id: string;
title: string;
slug: string;
translation_key: string;
}[];
}
export interface CourseSessionDetail {
id: string;
title: string;
course: {
id: string;
title: string;
slug: string;
};
assignments: CourseSessionAssignment[];
attendance_courses: CourseSessionAttendanceCourse[];
edoniq_tests: CourseSessionEdoniqTest[];
users: CourseSessionUser[];
}
export type CourseSessionDetail = CourseSessionObjectType;
// document upload
export interface DocumentUploadData {
@ -641,37 +616,11 @@ export interface AssignmentTaskCompletionData {
};
}
export interface AssignmentCompletion {
id: string;
created_at: string;
updated_at: string;
submitted_at: string;
evaluation_submitted_at: string | null;
assignment_user: string;
assignment: number;
course_session: number;
completion_status: AssignmentCompletionStatus;
evaluation_user: string | null;
export type AssignmentCompletion = AssignmentCompletionObjectType & {
// assignment_user: Pick<UserObjectType, "id" | "__typename">;
// evaluation_user: Pick<UserObjectType, "id" | "__typename">;
completion_data: AssignmentCompletionData;
task_completion_data: AssignmentTaskCompletionData;
edoniq_extended_time_flag: boolean;
evaluation_points: number | null;
evaluation_max_points: number | null;
evaluation_passed: boolean | null;
}
export type UpsertUserAssignmentCompletion = {
assignment_id: string;
course_session_id: string;
completion_status: AssignmentCompletionStatus;
completion_data: AssignmentCompletionData;
};
export type EvaluationCompletionData = UpsertUserAssignmentCompletion & {
assignment_user_id: string;
evaluation_points?: number;
evaluation_max_points?: number;
evaluation_passed?: boolean;
};
export interface UserAssignmentCompletionStatus {

View File

@ -1,3 +1,4 @@
import graphene
from graphene import List
from graphene_django import DjangoObjectType
@ -10,7 +11,7 @@ from vbv_lernwelt.course.graphql.interfaces import CoursePageInterface
class CompetenceCertificateObjectType(DjangoObjectType):
assignments = List(AssignmentObjectType)
assignments = List(graphene.NonNull(AssignmentObjectType), required=True)
class Meta:
model = CompetenceCertificate
@ -22,7 +23,9 @@ class CompetenceCertificateObjectType(DjangoObjectType):
class CompetenceCertificateListObjectType(DjangoObjectType):
competence_certificates = List(CompetenceCertificateObjectType)
competence_certificates = List(
graphene.NonNull(CompetenceCertificateObjectType), required=True
)
class Meta:
model = CompetenceCertificateList

View File

@ -6,7 +6,7 @@ from graphene_django import DjangoObjectType
from vbv_lernwelt.core.models import User
class UserType(DjangoObjectType):
class UserObjectType(DjangoObjectType):
class Meta:
model = User
fields = (

View File

@ -5,13 +5,13 @@ from vbv_lernwelt.learnpath.models import Circle
class CoursePageInterface(graphene.Interface):
id = graphene.ID()
title = graphene.String()
slug = graphene.String()
content_type = graphene.String()
live = graphene.Boolean()
translation_key = graphene.String()
frontend_url = graphene.String()
id = graphene.ID(required=True)
title = graphene.String(required=True)
slug = graphene.String(required=True)
content_type = graphene.String(required=True)
live = graphene.Boolean(required=True)
translation_key = graphene.String(required=True)
frontend_url = graphene.String(required=True)
circle = graphene.Field("vbv_lernwelt.learnpath.graphql.types.CircleObjectType")
course = graphene.Field("vbv_lernwelt.course.graphql.types.CourseObjectType")

View File

@ -26,7 +26,6 @@ from vbv_lernwelt.course_session.models import (
CourseSessionAttendanceCourse,
CourseSessionEdoniqTest,
)
from vbv_lernwelt.learnpath.graphql.types import LearningPathObjectType
logger = structlog.get_logger(__name__)
@ -84,30 +83,27 @@ def resolve_course_page(
class CourseObjectType(DjangoObjectType):
learning_path = graphene.Field(LearningPathObjectType)
class Meta:
model = Course
fields = ("id", "title", "category_name", "slug", "learning_path")
def resolve_learning_path(self, info):
return self.get_learning_path()
fields = ("id", "title", "category_name", "slug")
class CourseSessionUserExpertCircleType(ObjectType):
id = graphene.ID()
title = graphene.String()
slug = graphene.String()
id = graphene.ID(required=True)
title = graphene.String(required=True)
slug = graphene.String(required=True)
class CourseSessionUserObjectsType(DjangoObjectType):
user_id = graphene.UUID()
first_name = graphene.String()
last_name = graphene.String()
email = graphene.String()
avatar_url = graphene.String()
role = graphene.String()
circles = graphene.List(CourseSessionUserExpertCircleType)
user_id = graphene.UUID(required=True)
first_name = graphene.String(required=True)
last_name = graphene.String(required=True)
email = graphene.String(required=True)
avatar_url = graphene.String(required=True)
# role = graphene.String(required=True)
circles = graphene.List(
graphene.NonNull(CourseSessionUserExpertCircleType), required=True
)
class Meta:
model = CourseSessionUser
@ -166,12 +162,16 @@ class CircleDocumentObjectType(DjangoObjectType):
class CourseSessionObjectType(DjangoObjectType):
attendance_courses = graphene.List(CourseSessionAttendanceCourseObjectType)
assignments = graphene.List(CourseSessionAssignmentObjectType)
edoniq_tests = graphene.List(CourseSessionEdoniqTestObjectType)
documents = graphene.List(CircleDocumentObjectType)
users = graphene.List(CourseSessionUserObjectsType)
attendance_courses = graphene.List(
graphene.NonNull(CourseSessionAttendanceCourseObjectType), required=True
)
assignments = graphene.List(
graphene.NonNull(CourseSessionAssignmentObjectType), required=True
)
edoniq_tests = graphene.List(
graphene.NonNull(CourseSessionEdoniqTestObjectType), required=True
)
users = graphene.List(graphene.NonNull(CourseSessionUserObjectsType), required=True)
class Meta:
model = CourseSession
@ -195,10 +195,5 @@ class CourseSessionObjectType(DjangoObjectType):
def resolve_edoniq_tests(self, info):
return CourseSessionEdoniqTest.objects.filter(course_session=self)
def resolve_documents(self, info):
return CircleDocument.objects.filter(
course_session=self, file__upload_finished_at__isnull=False
)
def resolve_users(self, info):
return CourseSessionUser.objects.filter(course_session_id=self.id).distinct()

View File

@ -33,13 +33,14 @@ class CourseSessionAttendanceCourseObjectType(DjangoObjectType):
AttendanceUserObjectType, source="attendance_user_list"
)
due_date = graphene.Field(DueDateObjectType)
learning_content = graphene.Field(LearningContentAttendanceCourseObjectType)
learning_content = graphene.Field(
LearningContentAttendanceCourseObjectType, required=True
)
class Meta:
model = CourseSessionAttendanceCourse
fields = (
"id",
"course_session_id",
"learning_content",
"location",
"trainer",
@ -53,17 +54,18 @@ class CourseSessionAttendanceCourseObjectType(DjangoObjectType):
class CourseSessionAssignmentObjectType(DjangoObjectType):
course_session_id = graphene.ID(source="course_session_id")
learning_content_id = graphene.ID(source="learning_content_id")
course_session_id = graphene.ID(source="course_session_id", required=True)
learning_content_id = graphene.ID(source="learning_content_id", required=True)
submission_deadline = graphene.Field(DueDateObjectType)
evaluation_deadline = graphene.Field(DueDateObjectType)
learning_content = graphene.Field(LearningContentAssignmentObjectType)
learning_content = graphene.Field(
LearningContentAssignmentObjectType, required=True
)
class Meta:
model = CourseSessionAssignment
fields = (
"id",
"course_session_id",
"learning_content",
"submission_deadline",
"evaluation_deadline",
@ -71,16 +73,18 @@ class CourseSessionAssignmentObjectType(DjangoObjectType):
class CourseSessionEdoniqTestObjectType(DjangoObjectType):
course_session_id = graphene.ID(source="course_session_id")
learning_content_id = graphene.ID(source="learning_content_id")
course_session_id = graphene.ID(source="course_session_id", required=True)
learning_content_id = graphene.ID(source="learning_content_id", required=True)
deadline = graphene.Field(DueDateObjectType)
learning_content = graphene.Field(LearningContentEdoniqTestObjectType)
learning_content = graphene.Field(
LearningContentEdoniqTestObjectType, required=True
)
class Meta:
model = CourseSessionEdoniqTest
fields = (
"id",
"course_session_id",
"learning_content",
"deadline",
)

View File

@ -29,6 +29,9 @@ class LearningContentInterface(CoursePageInterface):
minutes = graphene.Int()
description = graphene.String()
content = graphene.String()
circle = graphene.Field(
"vbv_lernwelt.learnpath.graphql.types.CircleObjectType", required=True
)
@classmethod
def resolve_type(cls, instance, info):
@ -166,8 +169,10 @@ class LearningContentDocumentListObjectType(DjangoObjectType):
class LearningUnitObjectType(DjangoObjectType):
learning_contents = graphene.List(LearningContentInterface)
evaluate_url = graphene.String()
learning_contents = graphene.List(
graphene.NonNull(LearningContentInterface), required=True
)
evaluate_url = graphene.String(required=True)
class Meta:
model = LearningUnit