Show Diagram for users in cockpit
This commit is contained in:
parent
61dfdfda9d
commit
a6cf4ad128
|
|
@ -2,29 +2,37 @@
|
|||
import LearningPathCircle from "@/pages/learningPath/learningPathPage/LearningPathCircle.vue";
|
||||
import { calculateCircleSectorData } from "@/pages/learningPath/learningPathPage/utils";
|
||||
import { computed } from "vue";
|
||||
import type { LearningPathType } from "@/types";
|
||||
import { flatCircles } from "@/composables";
|
||||
import { useLearningPathWithCompletion } from "@/composables";
|
||||
|
||||
export type DiagramType = "horizontal" | "horizontalSmall" | "singleSmall";
|
||||
|
||||
export interface Props {
|
||||
diagramType?: DiagramType;
|
||||
learningPath: LearningPathType;
|
||||
showCircleSlugs?: string[];
|
||||
courseSlug: string;
|
||||
courseSessionId: string;
|
||||
userId?: string;
|
||||
diagramType?: DiagramType;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
diagramType: "horizontal",
|
||||
showCircleSlugs: undefined,
|
||||
userId: undefined,
|
||||
});
|
||||
|
||||
const lpQueryResult = useLearningPathWithCompletion(
|
||||
props.courseSlug,
|
||||
props.userId,
|
||||
props.courseSessionId
|
||||
);
|
||||
|
||||
const circles = computed(() => {
|
||||
if (props.showCircleSlugs?.length) {
|
||||
return flatCircles(props.learningPath).filter(
|
||||
return (lpQueryResult.circles.value ?? []).filter(
|
||||
(c) => props.showCircleSlugs?.includes(c.slug) ?? true
|
||||
);
|
||||
}
|
||||
return flatCircles(props.learningPath);
|
||||
return lpQueryResult.circles.value ?? [];
|
||||
});
|
||||
|
||||
const wrapperClasses = computed(() => {
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
<script setup lang="ts">
|
||||
import * as log from "loglevel";
|
||||
|
||||
import LearningPathDiagram from "@/components/learningPath/LearningPathDiagram.vue";
|
||||
import { useLearningPathWithCompletion } from "@/composables";
|
||||
|
||||
log.debug("LearningPathDiagramSmall created");
|
||||
|
||||
const props = defineProps<{
|
||||
courseSlug: string;
|
||||
courseSessionId: string;
|
||||
}>();
|
||||
|
||||
const lpQueryResult = useLearningPathWithCompletion(
|
||||
props.courseSlug,
|
||||
props.courseSessionId
|
||||
);
|
||||
</script>
|
||||
<template>
|
||||
<LearningPathDiagram
|
||||
v-if="lpQueryResult.learningPath.value"
|
||||
:learning-path="lpQueryResult.learningPath.value"
|
||||
diagram-type="horizontalSmall"
|
||||
></LearningPathDiagram>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -148,6 +148,18 @@ export function useLearningPath(courseSlug: string) {
|
|||
|
||||
resultPromise.then((result) => {
|
||||
learningPath.value = result.data?.learning_path as LearningPathType;
|
||||
// attach circle information to learning contents
|
||||
if (learningPath.value) {
|
||||
flatCircles(learningPath.value).forEach((circle) => {
|
||||
circleFlatChildren(circle).forEach((lc) => {
|
||||
lc.circle = {
|
||||
id: circle.id,
|
||||
slug: circle.slug,
|
||||
title: circle.title,
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const circles = computed(() => {
|
||||
|
|
@ -163,13 +175,23 @@ export function useLearningPath(courseSlug: string) {
|
|||
});
|
||||
}
|
||||
|
||||
return { resultPromise, learningPath, circles, findCircle };
|
||||
function findLearningContent(learningContentId: string) {
|
||||
return (circles.value ?? [])
|
||||
.flatMap((c) => {
|
||||
return circleFlatLearningContents(c);
|
||||
})
|
||||
.find((lc) => {
|
||||
return lc.id === learningContentId;
|
||||
});
|
||||
}
|
||||
|
||||
return { resultPromise, learningPath, circles, findCircle, findLearningContent };
|
||||
}
|
||||
|
||||
export function useLearningPathWithCompletion(
|
||||
courseSlug?: string,
|
||||
courseSessionId?: string,
|
||||
userId?: string
|
||||
userId?: string,
|
||||
courseSessionId?: string
|
||||
) {
|
||||
if (!courseSlug) {
|
||||
courseSlug = useCurrentCourseSession().value.course.slug;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ 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 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 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 id\n title\n slug\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 description\n goals\n ...CoursePageFields\n learning_sequences {\n icon\n ...CoursePageFields\n learning_units {\n evaluate_url\n ...CoursePageFields\n performance_criteria {\n ...CoursePageFields\n }\n learning_contents {\n can_user_self_toggle_course_completion\n ...CoursePageFields\n ... on LearningContentAssignmentObjectType {\n assignment_type\n content_assignment {\n id\n }\n competence_certificate {\n ...CoursePageFields\n }\n }\n ... on LearningContentEdoniqTestObjectType {\n checkbox_text\n competence_certificate {\n ...CoursePageFields\n }\n }\n }\n }\n }\n }\n }\n }\n }\n": types.LearningPathQueryDocument,
|
||||
"\n mutation SendFeedbackMutation(\n $courseSessionId: ID!\n $learningContentId: ID!\n $data: GenericScalar!\n $submitted: Boolean\n ) {\n send_feedback(\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n data: $data\n submitted: $submitted\n ) {\n feedback_response {\n id\n data\n submitted\n }\n errors {\n field\n messages\n }\n }\n }\n": types.SendFeedbackMutationDocument,
|
||||
|
|
@ -61,7 +61,7 @@ export function graphql(source: "\n query assignmentCompletionQuery(\n $assi
|
|||
/**
|
||||
* 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 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"): (typeof documents)["\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"];
|
||||
export function graphql(source: "\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 id\n title\n slug\n }\n }\n }\n }\n }\n }\n"): (typeof documents)["\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 id\n title\n slug\n }\n }\n }\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
|
|
@ -1,6 +1,5 @@
|
|||
type Query {
|
||||
learning_path(id: ID, slug: String, course_id: ID, course_slug: String): LearningPathObjectType
|
||||
circle(id: ID, slug: String): CircleObjectType
|
||||
learning_content_media_library: LearningContentMediaLibraryObjectType
|
||||
learning_content_assignment: LearningContentAssignmentObjectType
|
||||
learning_content_attendance_course: LearningContentAttendanceCourseObjectType
|
||||
|
|
@ -28,7 +27,6 @@ type LearningPathObjectType implements CoursePageInterface {
|
|||
live: Boolean!
|
||||
translation_key: String!
|
||||
frontend_url: String!
|
||||
circle: CircleObjectType
|
||||
course: CourseObjectType
|
||||
topics: [TopicObjectType!]!
|
||||
}
|
||||
|
|
@ -41,10 +39,29 @@ interface CoursePageInterface {
|
|||
live: Boolean!
|
||||
translation_key: String!
|
||||
frontend_url: String!
|
||||
circle: CircleObjectType
|
||||
course: CourseObjectType
|
||||
}
|
||||
|
||||
type CourseObjectType {
|
||||
id: ID!
|
||||
title: String!
|
||||
category_name: String!
|
||||
slug: String!
|
||||
}
|
||||
|
||||
type TopicObjectType implements CoursePageInterface {
|
||||
is_visible: Boolean!
|
||||
id: ID!
|
||||
title: String!
|
||||
slug: String!
|
||||
content_type: String!
|
||||
live: Boolean!
|
||||
translation_key: String!
|
||||
frontend_url: String!
|
||||
course: CourseObjectType
|
||||
circles: [CircleObjectType!]!
|
||||
}
|
||||
|
||||
type CircleObjectType implements CoursePageInterface {
|
||||
description: String!
|
||||
goals: String!
|
||||
|
|
@ -55,18 +72,10 @@ type CircleObjectType implements CoursePageInterface {
|
|||
live: Boolean!
|
||||
translation_key: String!
|
||||
frontend_url: String!
|
||||
circle: CircleObjectType
|
||||
course: CourseObjectType
|
||||
learning_sequences: [LearningSequenceObjectType!]!
|
||||
}
|
||||
|
||||
type CourseObjectType {
|
||||
id: ID!
|
||||
title: String!
|
||||
category_name: String!
|
||||
slug: String!
|
||||
}
|
||||
|
||||
type LearningSequenceObjectType implements CoursePageInterface {
|
||||
icon: String!
|
||||
id: ID!
|
||||
|
|
@ -76,7 +85,6 @@ type LearningSequenceObjectType implements CoursePageInterface {
|
|||
live: Boolean!
|
||||
translation_key: String!
|
||||
frontend_url: String!
|
||||
circle: CircleObjectType
|
||||
course: CourseObjectType
|
||||
learning_units: [LearningUnitObjectType!]!
|
||||
}
|
||||
|
|
@ -90,7 +98,6 @@ type LearningUnitObjectType implements CoursePageInterface {
|
|||
live: Boolean!
|
||||
translation_key: String!
|
||||
frontend_url: String!
|
||||
circle: CircleObjectType
|
||||
course: CourseObjectType
|
||||
learning_contents: [LearningContentInterface!]!
|
||||
performance_criteria: [PerformanceCriteriaObjectType!]!
|
||||
|
|
@ -105,12 +112,18 @@ interface LearningContentInterface {
|
|||
live: Boolean!
|
||||
translation_key: String!
|
||||
frontend_url: String!
|
||||
circle: CircleObjectType!
|
||||
course: CourseObjectType
|
||||
minutes: Int
|
||||
description: String!
|
||||
content_url: String!
|
||||
can_user_self_toggle_course_completion: Boolean!
|
||||
circle: CircleLightObjectType
|
||||
}
|
||||
|
||||
type CircleLightObjectType {
|
||||
id: ID!
|
||||
title: String!
|
||||
slug: String!
|
||||
}
|
||||
|
||||
type PerformanceCriteriaObjectType implements CoursePageInterface {
|
||||
|
|
@ -122,24 +135,9 @@ type PerformanceCriteriaObjectType implements CoursePageInterface {
|
|||
live: Boolean!
|
||||
translation_key: String!
|
||||
frontend_url: String!
|
||||
circle: CircleObjectType
|
||||
course: CourseObjectType
|
||||
}
|
||||
|
||||
type TopicObjectType implements CoursePageInterface {
|
||||
is_visible: Boolean!
|
||||
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!
|
||||
|
|
@ -148,12 +146,12 @@ type LearningContentMediaLibraryObjectType implements CoursePageInterface & Lear
|
|||
live: Boolean!
|
||||
translation_key: String!
|
||||
frontend_url: String!
|
||||
circle: CircleObjectType!
|
||||
course: CourseObjectType
|
||||
minutes: Int
|
||||
description: String!
|
||||
content_url: String!
|
||||
can_user_self_toggle_course_completion: Boolean!
|
||||
circle: CircleLightObjectType
|
||||
}
|
||||
|
||||
type LearningContentAssignmentObjectType implements CoursePageInterface & LearningContentInterface {
|
||||
|
|
@ -166,12 +164,12 @@ type LearningContentAssignmentObjectType implements CoursePageInterface & Learni
|
|||
live: Boolean!
|
||||
translation_key: String!
|
||||
frontend_url: String!
|
||||
circle: CircleObjectType!
|
||||
course: CourseObjectType
|
||||
minutes: Int
|
||||
description: String!
|
||||
content_url: String!
|
||||
can_user_self_toggle_course_completion: Boolean!
|
||||
circle: CircleLightObjectType
|
||||
competence_certificate: CompetenceCertificateObjectType
|
||||
}
|
||||
|
||||
|
|
@ -202,7 +200,6 @@ type AssignmentObjectType implements CoursePageInterface {
|
|||
live: Boolean!
|
||||
translation_key: String!
|
||||
frontend_url: String!
|
||||
circle: CircleObjectType
|
||||
course: CourseObjectType
|
||||
tasks: JSONStreamField
|
||||
evaluation_tasks: JSONStreamField
|
||||
|
|
@ -238,7 +235,6 @@ type CompetenceCertificateObjectType implements CoursePageInterface {
|
|||
live: Boolean!
|
||||
translation_key: String!
|
||||
frontend_url: String!
|
||||
circle: CircleObjectType
|
||||
course: CourseObjectType
|
||||
assignments: [AssignmentObjectType!]!
|
||||
}
|
||||
|
|
@ -344,12 +340,12 @@ type LearningContentAttendanceCourseObjectType implements CoursePageInterface &
|
|||
live: Boolean!
|
||||
translation_key: String!
|
||||
frontend_url: String!
|
||||
circle: CircleObjectType!
|
||||
course: CourseObjectType
|
||||
minutes: Int
|
||||
description: String!
|
||||
content_url: String!
|
||||
can_user_self_toggle_course_completion: Boolean!
|
||||
circle: CircleLightObjectType
|
||||
}
|
||||
|
||||
type DueDateObjectType {
|
||||
|
|
@ -426,12 +422,12 @@ type LearningContentEdoniqTestObjectType implements CoursePageInterface & Learni
|
|||
live: Boolean!
|
||||
translation_key: String!
|
||||
frontend_url: String!
|
||||
circle: CircleObjectType!
|
||||
course: CourseObjectType
|
||||
minutes: Int
|
||||
description: String!
|
||||
content_url: String!
|
||||
can_user_self_toggle_course_completion: Boolean!
|
||||
circle: CircleLightObjectType
|
||||
competence_certificate: CompetenceCertificateObjectType
|
||||
}
|
||||
|
||||
|
|
@ -520,12 +516,12 @@ type LearningContentFeedbackObjectType implements CoursePageInterface & Learning
|
|||
live: Boolean!
|
||||
translation_key: String!
|
||||
frontend_url: String!
|
||||
circle: CircleObjectType!
|
||||
course: CourseObjectType
|
||||
minutes: Int
|
||||
description: String!
|
||||
content_url: String!
|
||||
can_user_self_toggle_course_completion: Boolean!
|
||||
circle: CircleLightObjectType
|
||||
}
|
||||
|
||||
type LearningContentLearningModuleObjectType implements CoursePageInterface & LearningContentInterface {
|
||||
|
|
@ -536,12 +532,12 @@ type LearningContentLearningModuleObjectType implements CoursePageInterface & Le
|
|||
live: Boolean!
|
||||
translation_key: String!
|
||||
frontend_url: String!
|
||||
circle: CircleObjectType!
|
||||
course: CourseObjectType
|
||||
minutes: Int
|
||||
description: String!
|
||||
content_url: String!
|
||||
can_user_self_toggle_course_completion: Boolean!
|
||||
circle: CircleLightObjectType
|
||||
}
|
||||
|
||||
type LearningContentPlaceholderObjectType implements CoursePageInterface & LearningContentInterface {
|
||||
|
|
@ -552,12 +548,12 @@ type LearningContentPlaceholderObjectType implements CoursePageInterface & Learn
|
|||
live: Boolean!
|
||||
translation_key: String!
|
||||
frontend_url: String!
|
||||
circle: CircleObjectType!
|
||||
course: CourseObjectType
|
||||
minutes: Int
|
||||
description: String!
|
||||
content_url: String!
|
||||
can_user_self_toggle_course_completion: Boolean!
|
||||
circle: CircleLightObjectType
|
||||
}
|
||||
|
||||
type LearningContentRichTextObjectType implements CoursePageInterface & LearningContentInterface {
|
||||
|
|
@ -568,12 +564,12 @@ type LearningContentRichTextObjectType implements CoursePageInterface & Learning
|
|||
live: Boolean!
|
||||
translation_key: String!
|
||||
frontend_url: String!
|
||||
circle: CircleObjectType!
|
||||
course: CourseObjectType
|
||||
minutes: Int
|
||||
description: String!
|
||||
content_url: String!
|
||||
can_user_self_toggle_course_completion: Boolean!
|
||||
circle: CircleLightObjectType
|
||||
}
|
||||
|
||||
type LearningContentVideoObjectType implements CoursePageInterface & LearningContentInterface {
|
||||
|
|
@ -584,12 +580,12 @@ type LearningContentVideoObjectType implements CoursePageInterface & LearningCon
|
|||
live: Boolean!
|
||||
translation_key: String!
|
||||
frontend_url: String!
|
||||
circle: CircleObjectType!
|
||||
course: CourseObjectType
|
||||
minutes: Int
|
||||
description: String!
|
||||
content_url: String!
|
||||
can_user_self_toggle_course_completion: Boolean!
|
||||
circle: CircleLightObjectType
|
||||
}
|
||||
|
||||
type LearningContentDocumentListObjectType implements CoursePageInterface & LearningContentInterface {
|
||||
|
|
@ -600,12 +596,12 @@ type LearningContentDocumentListObjectType implements CoursePageInterface & Lear
|
|||
live: Boolean!
|
||||
translation_key: String!
|
||||
frontend_url: String!
|
||||
circle: CircleObjectType!
|
||||
course: CourseObjectType
|
||||
minutes: Int
|
||||
description: String!
|
||||
content_url: String!
|
||||
can_user_self_toggle_course_completion: Boolean!
|
||||
circle: CircleLightObjectType
|
||||
}
|
||||
|
||||
type CompetenceCertificateListObjectType implements CoursePageInterface {
|
||||
|
|
@ -616,7 +612,6 @@ type CompetenceCertificateListObjectType implements CoursePageInterface {
|
|||
live: Boolean!
|
||||
translation_key: String!
|
||||
frontend_url: String!
|
||||
circle: CircleObjectType
|
||||
course: CourseObjectType
|
||||
competence_certificates: [CompetenceCertificateObjectType!]!
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ export const AttendanceUserInputType = "AttendanceUserInputType";
|
|||
export const AttendanceUserObjectType = "AttendanceUserObjectType";
|
||||
export const AttendanceUserStatus = "AttendanceUserStatus";
|
||||
export const Boolean = "Boolean";
|
||||
export const CircleLightObjectType = "CircleLightObjectType";
|
||||
export const CircleObjectType = "CircleObjectType";
|
||||
export const CompetenceCertificateListObjectType = "CompetenceCertificateListObjectType";
|
||||
export const CompetenceCertificateObjectType = "CompetenceCertificateObjectType";
|
||||
|
|
|
|||
|
|
@ -97,7 +97,9 @@ export const COMPETENCE_NAVI_CERTIFICATE_QUERY = graphql(`
|
|||
learning_content {
|
||||
...CoursePageFields
|
||||
circle {
|
||||
...CoursePageFields
|
||||
id
|
||||
title
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,16 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref, watch } from "vue";
|
||||
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
||||
import { useLearningPathStore } from "@/stores/learningPath";
|
||||
import { useTranslation } from "i18next-vue";
|
||||
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
|
||||
import type { DueDate } from "@/types";
|
||||
import DueDatesList from "@/components/dueDates/DueDatesList.vue";
|
||||
import { useLearningPath } from "@/composables";
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const UNFILTERED = Number.MAX_SAFE_INTEGER.toString();
|
||||
const courseSessionsStore = useCourseSessionsStore();
|
||||
const learningPathStore = useLearningPathStore();
|
||||
|
||||
type Item = {
|
||||
id: string;
|
||||
|
|
@ -61,16 +60,15 @@ const circles = ref<Item[]>([initialItemCircle]);
|
|||
const selectedCircle = ref<Item>(circles.value[0]);
|
||||
|
||||
async function loadCircleValues() {
|
||||
const data = await learningPathStore.loadLearningPath(
|
||||
`${selectedCourse.value.slug}-lp`,
|
||||
undefined,
|
||||
false,
|
||||
false
|
||||
);
|
||||
if (data) {
|
||||
if (selectedCourse.value) {
|
||||
const learningPathQuery = useLearningPath(selectedCourse.value.slug);
|
||||
await learningPathQuery.resultPromise;
|
||||
circles.value = [
|
||||
initialItemCircle,
|
||||
...data.circles.map((circle) => ({ id: circle.id, name: circle.title })),
|
||||
...(learningPathQuery.circles.value ?? []).map((circle) => ({
|
||||
id: circle.id,
|
||||
name: circle.title,
|
||||
})),
|
||||
];
|
||||
} else {
|
||||
circles.value = [initialItemCircle];
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
<script setup lang="ts">
|
||||
import DueDatesList from "@/components/dueDates/DueDatesList.vue";
|
||||
import LearningPathDiagramSmall from "@/components/learningPath/LearningPathDiagramSmall.vue";
|
||||
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
||||
import { useUserStore } from "@/stores/user";
|
||||
import type { CourseSession } from "@/types";
|
||||
import log from "loglevel";
|
||||
import { computed, onMounted } from "vue";
|
||||
import { getCockpitUrl, getLearningPathUrl } from "@/utils/utils";
|
||||
import LearningPathDiagram from "@/components/learningPath/LearningPathDiagram.vue";
|
||||
|
||||
log.debug("DashboardPage created");
|
||||
|
||||
|
|
@ -47,11 +47,12 @@ const getNextStepLink = (courseSession: CourseSession) => {
|
|||
<div class="bg-white p-6 md:h-full">
|
||||
<h3 class="mb-4">{{ courseSession.course.title }}</h3>
|
||||
<div>
|
||||
<LearningPathDiagramSmall
|
||||
<LearningPathDiagram
|
||||
class="mb-4"
|
||||
:course-slug="courseSession.course.slug"
|
||||
:course-session-id="courseSession.id"
|
||||
></LearningPathDiagramSmall>
|
||||
diagram-type="horizontalSmall"
|
||||
></LearningPathDiagram>
|
||||
</div>
|
||||
<div>
|
||||
<router-link
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
import { useCourseSessionDetailQuery } from "@/composables";
|
||||
import { useCockpitStore } from "@/stores/cockpit";
|
||||
import { useCompetenceStore } from "@/stores/competence";
|
||||
import { useLearningPathStore } from "@/stores/learningPath";
|
||||
import { useUserStore } from "@/stores/user";
|
||||
import * as log from "loglevel";
|
||||
import { onMounted } from "vue";
|
||||
|
||||
|
|
@ -15,8 +13,6 @@ const props = defineProps<{
|
|||
|
||||
const cockpitStore = useCockpitStore();
|
||||
const competenceStore = useCompetenceStore();
|
||||
const learningPathStore = useLearningPathStore();
|
||||
|
||||
const courseSessionDetailResult = useCourseSessionDetailQuery();
|
||||
|
||||
onMounted(async () => {
|
||||
|
|
@ -30,13 +26,7 @@ onMounted(async () => {
|
|||
props.courseSlug + "-competencenavi-competences",
|
||||
csu.user_id
|
||||
);
|
||||
|
||||
learningPathStore.loadLearningPath(props.courseSlug + "-lp", csu.user_id);
|
||||
});
|
||||
await learningPathStore.loadLearningPath(
|
||||
props.courseSlug + "-lp",
|
||||
useUserStore().id
|
||||
);
|
||||
await cockpitStore.loadCircles(
|
||||
props.courseSlug,
|
||||
courseSessionDetailResult.findCurrentUser()
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
<script setup lang="ts">
|
||||
import { useCompetenceStore } from "@/stores/competence";
|
||||
import { useLearningPathStore } from "@/stores/learningPath";
|
||||
import * as log from "loglevel";
|
||||
import { computed, onMounted } from "vue";
|
||||
|
||||
import CompetenceDetail from "@/pages/competence/ActionCompetenceDetail.vue";
|
||||
import LearningPathPathView from "@/pages/learningPath/learningPathPage/LearningPathPathView.vue";
|
||||
import { useCourseSessionDetailQuery } from "@/composables";
|
||||
import {
|
||||
useCourseSessionDetailQuery,
|
||||
useLearningPathWithCompletion,
|
||||
} from "@/composables";
|
||||
|
||||
const props = defineProps<{
|
||||
userId: string;
|
||||
|
|
@ -16,14 +18,15 @@ const props = defineProps<{
|
|||
log.debug("CockpitUserProfilePage created", props.userId);
|
||||
|
||||
const competenceStore = useCompetenceStore();
|
||||
const learningPathStore = useLearningPathStore();
|
||||
|
||||
onMounted(async () => {
|
||||
log.debug("CockpitUserProfilePage mounted");
|
||||
});
|
||||
|
||||
const lpQueryResult = useLearningPathWithCompletion(props.courseSlug, props.userId);
|
||||
|
||||
const learningPath = computed(() => {
|
||||
return learningPathStore.learningPathForUser(props.courseSlug, props.userId);
|
||||
return lpQueryResult.learningPath.value;
|
||||
});
|
||||
|
||||
const { findUser } = useCourseSessionDetailQuery();
|
||||
|
|
|
|||
|
|
@ -13,16 +13,14 @@ import { computed, onMounted, reactive } from "vue";
|
|||
import AssignmentSubmissionProgress from "@/pages/cockpit/cockpitPage/AssignmentSubmissionProgress.vue";
|
||||
import { useCourseSessionDetailQuery } from "@/composables";
|
||||
import { formatDueDate } from "../../../components/dueDates/dueDatesUtils";
|
||||
import { stringifyParse } from "@/utils/utils";
|
||||
|
||||
const props = defineProps<{
|
||||
courseSession: CourseSession;
|
||||
learningContentAssignment: LearningContentAssignment;
|
||||
}>();
|
||||
|
||||
log.debug(
|
||||
"AssignmentDetails created",
|
||||
props.learningContentAssignment.content_assignment_id
|
||||
);
|
||||
log.debug("AssignmentDetails created", stringifyParse(props));
|
||||
|
||||
const courseSessionDetailResult = useCourseSessionDetailQuery();
|
||||
|
||||
|
|
@ -39,7 +37,7 @@ const assignmentDetail = computed(() => {
|
|||
onMounted(async () => {
|
||||
const { gradedUsers, assignmentSubmittedUsers } =
|
||||
await loadAssignmentCompletionStatusData(
|
||||
props.learningContentAssignment.content_assignment_id,
|
||||
props.learningContentAssignment.content_assignment.id,
|
||||
props.courseSession.id,
|
||||
props.learningContentAssignment.id
|
||||
);
|
||||
|
|
@ -54,17 +52,17 @@ onMounted(async () => {
|
|||
{{ learningContentAssignment.title }}
|
||||
</h2>
|
||||
<div class="pt-1 underline">
|
||||
{{ $t("a.Circle") }} «{{ learningContentAssignment.parentCircle.title }}»
|
||||
{{ $t("a.Circle") }} «{{ learningContentAssignment.circle?.title }}»
|
||||
</div>
|
||||
<div v-if="assignmentDetail">
|
||||
<span v-if="assignmentDetail.submission_deadline?.start">
|
||||
{{ $t("Abgabetermin Ergebnisse:") }}
|
||||
{{ formatDueDate(assignmentDetail.submission_deadline.start) }}
|
||||
{{ formatDueDate(assignmentDetail.submission_deadline?.start) }}
|
||||
</span>
|
||||
<template v-if="assignmentDetail.evaluation_deadline?.start">
|
||||
<br />
|
||||
{{ $t("Freigabetermin Bewertungen:") }}
|
||||
{{ formatDueDate(assignmentDetail.evaluation_deadline.start) }}
|
||||
{{ formatDueDate(assignmentDetail.evaluation_deadline?.start) }}
|
||||
</template>
|
||||
</div>
|
||||
<div v-else>
|
||||
|
|
@ -131,7 +129,7 @@ onMounted(async () => {
|
|||
<template #link>
|
||||
<router-link
|
||||
v-if="state.assignmentSubmittedUsers.includes(csu)"
|
||||
:to="`/course/${props.courseSession.course.slug}/cockpit/assignment/${learningContentAssignment.content_assignment_id}/${csu.user_id}`"
|
||||
:to="`/course/${props.courseSession.course.slug}/cockpit/assignment/${learningContentAssignment.content_assignment.id}/${csu.user_id}`"
|
||||
class="link lg:w-full lg:text-right"
|
||||
data-cy="show-results"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
<script setup lang="ts">
|
||||
import { useCurrentCourseSession } from "@/composables";
|
||||
import { useCurrentCourseSession, useLearningPath } from "@/composables";
|
||||
import AssignmentDetails from "@/pages/cockpit/assignmentsPage/AssignmentDetails.vue";
|
||||
import * as log from "loglevel";
|
||||
import { computed, onMounted } from "vue";
|
||||
import { useUserStore } from "@/stores/user";
|
||||
import { useLearningPathStore } from "@/stores/learningPath";
|
||||
import { calcLearningContentAssignments } from "@/services/assignmentService";
|
||||
import type { LearningContentAssignment } from "@/types";
|
||||
|
||||
const props = defineProps<{
|
||||
courseSlug: string;
|
||||
|
|
@ -15,17 +13,15 @@ const props = defineProps<{
|
|||
log.debug("AssignmentsPage created", props.courseSlug);
|
||||
|
||||
const courseSession = useCurrentCourseSession();
|
||||
const userStore = useUserStore();
|
||||
const learningPathStore = useLearningPathStore();
|
||||
|
||||
onMounted(async () => {
|
||||
log.debug("AssignmentsPage mounted");
|
||||
});
|
||||
|
||||
const lpQueryResult = useLearningPath(props.courseSlug);
|
||||
|
||||
const learningContentAssignment = computed(() => {
|
||||
return calcLearningContentAssignments(
|
||||
learningPathStore.learningPathForUser(courseSession.value.course.slug, userStore.id)
|
||||
).filter((lc) => lc.id === props.assignmentId)[0];
|
||||
return lpQueryResult.findLearningContent(props.assignmentId);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
@ -46,7 +42,7 @@ const learningContentAssignment = computed(() => {
|
|||
<AssignmentDetails
|
||||
v-if="learningContentAssignment"
|
||||
:course-session="courseSession"
|
||||
:learning-content-assignment="learningContentAssignment"
|
||||
:learning-content-assignment="learningContentAssignment as LearningContentAssignment"
|
||||
/>
|
||||
</div>
|
||||
</main>
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ const presenceCoursesDropdownOptions = computed(() => {
|
|||
({
|
||||
id: attendanceCourse.id,
|
||||
name: `${t("Präsenzkurs")} ${
|
||||
attendanceCourse.learning_content.circle.title
|
||||
attendanceCourse.learning_content.circle?.title
|
||||
} ${dayjs(attendanceCourse.due_date?.start).format("DD.MM.YYYY")}`,
|
||||
} as DropdownSelectable)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import type {
|
|||
} from "@/types";
|
||||
import log from "loglevel";
|
||||
import { onMounted, reactive } from "vue";
|
||||
import { stringifyParse } from "@/utils/utils";
|
||||
|
||||
const props = defineProps<{
|
||||
courseSession: CourseSession;
|
||||
|
|
@ -16,10 +17,7 @@ const props = defineProps<{
|
|||
showTitle: boolean;
|
||||
}>();
|
||||
|
||||
log.debug(
|
||||
"AssignmentSubmissionProgress created",
|
||||
props.learningContentAssignment.content_assignment_id
|
||||
);
|
||||
log.debug("AssignmentSubmissionProgress created", stringifyParse(props));
|
||||
|
||||
const state = reactive({
|
||||
statusByUser: [] as {
|
||||
|
|
@ -34,7 +32,7 @@ const state = reactive({
|
|||
onMounted(async () => {
|
||||
const { assignmentSubmittedUsers, gradedUsers, total } =
|
||||
await loadAssignmentCompletionStatusData(
|
||||
props.learningContentAssignment.content_assignment_id,
|
||||
props.learningContentAssignment.content_assignment.id,
|
||||
props.courseSession.id,
|
||||
props.learningContentAssignment.id
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
<script setup lang="ts">
|
||||
import LearningPathDiagram from "@/components/learningPath/LearningPathDiagram.vue";
|
||||
import ItPersonRow from "@/components/ui/ItPersonRow.vue";
|
||||
import type { LearningPath } from "@/services/learningPath";
|
||||
|
||||
import { useCourseSessionDetailQuery, useCurrentCourseSession } from "@/composables";
|
||||
import SubmissionsOverview from "@/pages/cockpit/cockpitPage/SubmissionsOverview.vue";
|
||||
import { useCockpitStore } from "@/stores/cockpit";
|
||||
import { useCompetenceStore } from "@/stores/competence";
|
||||
import { useLearningPathStore } from "@/stores/learningPath";
|
||||
import log from "loglevel";
|
||||
import CockpitDates from "@/pages/cockpit/cockpitPage/CockpitDates.vue";
|
||||
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
|
||||
|
|
@ -20,7 +18,6 @@ log.debug("CockpitIndexPage created", props.courseSlug);
|
|||
|
||||
const cockpitStore = useCockpitStore();
|
||||
const competenceStore = useCompetenceStore();
|
||||
const learningPathStore = useLearningPathStore();
|
||||
const courseSession = useCurrentCourseSession();
|
||||
const courseSessionDetailResult = useCourseSessionDetailQuery();
|
||||
|
||||
|
|
@ -143,18 +140,9 @@ function userCountStatusForCircle(userId: string) {
|
|||
class="mt-2 flex w-full flex-col items-center justify-between lg:mt-0 lg:flex-row"
|
||||
>
|
||||
<LearningPathDiagram
|
||||
v-if="
|
||||
learningPathStore.learningPathForUser(
|
||||
props.courseSlug,
|
||||
csu.user_id
|
||||
)
|
||||
"
|
||||
:learning-path="
|
||||
learningPathStore.learningPathForUser(
|
||||
props.courseSlug,
|
||||
csu.user_id
|
||||
) as LearningPath
|
||||
"
|
||||
:course-session-id="courseSession.id"
|
||||
:course-slug="props.courseSlug"
|
||||
:user-id="csu.user_id"
|
||||
:show-circle-slugs="[cockpitStore.currentCircle.slug]"
|
||||
diagram-type="singleSmall"
|
||||
class="mr-4"
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
2
|
||||
<script setup lang="ts">
|
||||
import AssignmentSubmissionProgress from "@/pages/cockpit/cockpitPage/AssignmentSubmissionProgress.vue";
|
||||
import { useLearningPathStore } from "@/stores/learningPath";
|
||||
import { useUserStore } from "@/stores/user";
|
||||
import type {
|
||||
CourseSession,
|
||||
LearningContent,
|
||||
|
|
@ -13,11 +11,16 @@ import { computed } from "vue";
|
|||
import { useTranslation } from "i18next-vue";
|
||||
import FeedbackSubmissionProgress from "@/pages/cockpit/cockpitPage/FeedbackSubmissionProgress.vue";
|
||||
import { learningContentTypeData } from "@/utils/typeMaps";
|
||||
import { useCourseSessionDetailQuery } from "@/composables";
|
||||
import {
|
||||
useCourseSessionDetailQuery,
|
||||
useLearningPathWithCompletion,
|
||||
} from "@/composables";
|
||||
import { circleFlatLearningContents } from "@/services/circle";
|
||||
|
||||
interface Submittable {
|
||||
id: string;
|
||||
circleName: string;
|
||||
circleId: string;
|
||||
frontendUrl: string;
|
||||
title: string;
|
||||
showDetailsText: string;
|
||||
|
|
@ -32,24 +35,20 @@ const props = defineProps<{
|
|||
|
||||
log.debug("SubmissionsOverview created", props.courseSession.id);
|
||||
|
||||
const userStore = useUserStore();
|
||||
const learningPathStore = useLearningPathStore();
|
||||
const courseSessionDetailResult = useCourseSessionDetailQuery();
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const lpQueryResult = useLearningPathWithCompletion();
|
||||
|
||||
const submittables = computed(() => {
|
||||
const learningPath = learningPathStore.learningPathForUser(
|
||||
props.courseSession.course.slug,
|
||||
userStore.id
|
||||
);
|
||||
if (!learningPath) {
|
||||
if (!lpQueryResult.circles.value?.length) {
|
||||
return [];
|
||||
}
|
||||
return learningPath.circles
|
||||
return lpQueryResult.circles.value
|
||||
.filter((circle) => props.selectedCircle == circle.id)
|
||||
.flatMap((circle) => {
|
||||
const learningContents = circle.flatLearningContents.filter(
|
||||
const learningContents = circleFlatLearningContents(circle).filter(
|
||||
(lc) =>
|
||||
lc.content_type === "learnpath.LearningContentAssignment" ||
|
||||
lc.content_type === "learnpath.LearningContentFeedback"
|
||||
|
|
@ -59,10 +58,11 @@ const submittables = computed(() => {
|
|||
return {
|
||||
id: lc.id,
|
||||
circleName: circle.title,
|
||||
circleId: circle.id,
|
||||
frontendUrl: lc.frontend_url,
|
||||
title: getLearningContentType(lc),
|
||||
showDetailsText: getShowDetailsText(lc),
|
||||
detailsLink: getDetailsLink(lc),
|
||||
detailsLink: getDetailsLink(lc, circle.id),
|
||||
content: lc,
|
||||
};
|
||||
});
|
||||
|
|
@ -103,9 +103,9 @@ const getShowDetailsText = (lc: LearningContent) => {
|
|||
return t("Feedback anschauen");
|
||||
};
|
||||
|
||||
const getDetailsLink = (lc: LearningContent) => {
|
||||
const getDetailsLink = (lc: LearningContent, circleId: string) => {
|
||||
if (isFeedback(lc)) {
|
||||
return `cockpit/feedback/${lc.parentCircle.id}`;
|
||||
return `cockpit/feedback/${circleId}`;
|
||||
}
|
||||
return `cockpit/assignment/${lc.id}`;
|
||||
};
|
||||
|
|
@ -162,7 +162,7 @@ const getIconName = (lc: LearningContent) => {
|
|||
<FeedbackSubmissionProgress
|
||||
v-if="isFeedback(submittable.content)"
|
||||
:course-session="props.courseSession"
|
||||
:circle-id="submittable.content.parentCircle.id"
|
||||
:circle-id="submittable.circleId"
|
||||
class="grow pr-8"
|
||||
></FeedbackSubmissionProgress>
|
||||
<div class="flex items-center lg:w-1/4 lg:justify-end">
|
||||
|
|
|
|||
|
|
@ -32,7 +32,10 @@ const props = withDefaults(defineProps<Props>(), {
|
|||
|
||||
log.debug("CirclePage created", stringifyParse(props));
|
||||
|
||||
const lpQueryResult = useLearningPathWithCompletion(props.courseSlug);
|
||||
const lpQueryResult = useLearningPathWithCompletion(
|
||||
props.courseSlug,
|
||||
props.profileUser?.user_id
|
||||
);
|
||||
|
||||
const circle = computed(() => {
|
||||
return lpQueryResult.findCircle(props.circleSlug);
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
import { useCourseSessionDetailQuery } from "@/composables";
|
||||
import { itGet } from "@/fetchHelpers";
|
||||
import type { LearningPath } from "@/services/learningPath";
|
||||
import type {
|
||||
Assignment,
|
||||
AssignmentCompletion,
|
||||
CourseSessionUser,
|
||||
LearningContentAssignment,
|
||||
UserAssignmentCompletionStatus,
|
||||
} from "@/types";
|
||||
import { sum } from "d3";
|
||||
|
|
@ -16,17 +14,6 @@ export interface GradedUser {
|
|||
points: number;
|
||||
}
|
||||
|
||||
export function calcLearningContentAssignments(learningPath?: LearningPath) {
|
||||
// TODO: filter by circle
|
||||
if (!learningPath) return [];
|
||||
|
||||
return learningPath.circles.flatMap((circle) => {
|
||||
return circle.flatLearningContents.filter(
|
||||
(lc) => lc.content_type === "learnpath.LearningContentAssignment"
|
||||
) as LearningContentAssignment[];
|
||||
});
|
||||
}
|
||||
|
||||
export async function loadAssignmentCompletionStatusData(
|
||||
assignmentId: string,
|
||||
courseSessionId: string,
|
||||
|
|
|
|||
|
|
@ -149,6 +149,7 @@ export type LearningUnitPerformanceCriteria = Omit<
|
|||
> &
|
||||
Completable & {
|
||||
readonly content_type: "competence.PerformanceCriteria";
|
||||
circle?: CircleLight;
|
||||
};
|
||||
|
||||
export interface CourseCompletion {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ class CoursePageInterface(graphene.Interface):
|
|||
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")
|
||||
|
||||
def resolve_frontend_url(self, info):
|
||||
|
|
@ -21,11 +20,5 @@ class CoursePageInterface(graphene.Interface):
|
|||
def resolve_content_type(self, info):
|
||||
return get_django_content_type(self)
|
||||
|
||||
def resolve_circle(self, info):
|
||||
circle = self.get_ancestors().exact_type(Circle).first()
|
||||
if circle:
|
||||
return circle.specific
|
||||
return None
|
||||
|
||||
def resolve_course(self, info):
|
||||
return self.get_course()
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import graphene
|
|||
|
||||
from vbv_lernwelt.course.graphql.types import resolve_course_page
|
||||
from vbv_lernwelt.learnpath.graphql.types import (
|
||||
CircleObjectType,
|
||||
LearningContentAssignmentObjectType,
|
||||
LearningContentAttendanceCourseObjectType,
|
||||
LearningContentDocumentListObjectType,
|
||||
|
|
@ -15,7 +14,7 @@ from vbv_lernwelt.learnpath.graphql.types import (
|
|||
LearningContentVideoObjectType,
|
||||
LearningPathObjectType,
|
||||
)
|
||||
from vbv_lernwelt.learnpath.models import Circle, LearningPath
|
||||
from vbv_lernwelt.learnpath.models import LearningPath
|
||||
|
||||
|
||||
class LearningPathQuery:
|
||||
|
|
@ -26,10 +25,6 @@ class LearningPathQuery:
|
|||
course_id=graphene.ID(),
|
||||
course_slug=graphene.String(),
|
||||
)
|
||||
circle = graphene.Field(CircleObjectType, id=graphene.ID(), slug=graphene.String())
|
||||
|
||||
def resolve_circle(root, info, id=None, slug=None):
|
||||
return resolve_course_page(Circle, root, info, id=id, slug=slug)
|
||||
|
||||
def resolve_learning_path(
|
||||
root, info, id=None, slug=None, course_id=None, course_slug=None
|
||||
|
|
|
|||
|
|
@ -25,14 +25,22 @@ from vbv_lernwelt.learnpath.models import (
|
|||
logger = structlog.get_logger(__name__)
|
||||
|
||||
|
||||
class CircleLightObjectType(graphene.ObjectType):
|
||||
id = graphene.ID(required=True)
|
||||
title = graphene.String(required=True)
|
||||
slug = graphene.String(required=True)
|
||||
|
||||
|
||||
class LearningContentInterface(CoursePageInterface):
|
||||
minutes = graphene.Int()
|
||||
description = graphene.String(required=True)
|
||||
content_url = graphene.String(required=True)
|
||||
can_user_self_toggle_course_completion = graphene.Boolean(required=True)
|
||||
circle = graphene.Field(
|
||||
"vbv_lernwelt.learnpath.graphql.types.CircleObjectType", required=True
|
||||
)
|
||||
circle = graphene.Field(CircleLightObjectType)
|
||||
|
||||
@staticmethod
|
||||
def resolve_circle(root, info):
|
||||
return root.get_parent_circle()
|
||||
|
||||
@classmethod
|
||||
def resolve_type(cls, instance, info):
|
||||
|
|
|
|||
Loading…
Reference in New Issue