Refactor code to use `useCourseSessionDetailQuery`
This commit is contained in:
parent
06d284b1ce
commit
f75590dd0b
|
|
@ -48,12 +48,30 @@ export function useCourseSessionDetailQuery(courSessionId?: string | number) {
|
||||||
return queryResult.data.value?.course_session as CourseSessionDetail | undefined;
|
return queryResult.data.value?.course_session as CourseSessionDetail | undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
function findAssignmentDetail(assignmentId: string) {
|
function findAssignmentByAssignmentId(assignmentId: string) {
|
||||||
return (courseSessionDetail.value?.assignments ?? []).find((a) => {
|
return (courseSessionDetail.value?.assignments ?? []).find((a) => {
|
||||||
return a.learning_content?.content_assignment?.id === assignmentId;
|
return a.learning_content?.content_assignment?.id === assignmentId;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function findAssignment(learningContentId: string) {
|
||||||
|
return (courseSessionDetail.value?.assignments ?? []).find((a) => {
|
||||||
|
return a.learning_content.id === learningContentId;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function findEdoniqTest(learningContentId: string) {
|
||||||
|
return (courseSessionDetail.value?.edoniq_tests ?? []).find((e) => {
|
||||||
|
return e.learning_content.id === learningContentId;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function findAttendanceCourse(learningContentId: string) {
|
||||||
|
return (courseSessionDetail.value?.attendance_courses ?? []).find((e) => {
|
||||||
|
return e.learning_content.id === learningContentId;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function findUser(userId: string) {
|
function findUser(userId: string) {
|
||||||
return (courseSessionDetail.value?.users ?? []).find((u) => {
|
return (courseSessionDetail.value?.users ?? []).find((u) => {
|
||||||
return u.user_id === userId;
|
return u.user_id === userId;
|
||||||
|
|
@ -72,6 +90,12 @@ export function useCourseSessionDetailQuery(courSessionId?: string | number) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function filterCircleExperts(circleSlug: string) {
|
||||||
|
return (courseSessionDetail.value?.users ?? []).filter((u) => {
|
||||||
|
return u.role === "EXPERT" && u.circles.map((c) => c.slug).includes(circleSlug);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const dataLoaded = ref(false);
|
const dataLoaded = ref(false);
|
||||||
|
|
||||||
function waitForData() {
|
function waitForData() {
|
||||||
|
|
@ -89,9 +113,13 @@ export function useCourseSessionDetailQuery(courSessionId?: string | number) {
|
||||||
...queryResult,
|
...queryResult,
|
||||||
courseSessionDetail,
|
courseSessionDetail,
|
||||||
waitForData,
|
waitForData,
|
||||||
findAssignmentDetail,
|
findAssignmentByAssignmentId,
|
||||||
|
findAssignment,
|
||||||
|
findEdoniqTest,
|
||||||
|
findAttendanceCourse,
|
||||||
findUser,
|
findUser,
|
||||||
findCurrentUser,
|
findCurrentUser,
|
||||||
filterMembers,
|
filterMembers,
|
||||||
|
filterCircleExperts,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ const 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 }\n }\n": types.AssignmentCompletionQueryDocument,
|
"\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 }\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 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 title\n id\n slug\n content_type\n frontend_url\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 title\n id\n slug\n content_type\n frontend_url\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 }\n }\n }\n }\n": types.CourseSessionDetailDocument,
|
"\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 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,
|
"\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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -69,7 +69,7 @@ export function graphql(source: "\n query competenceCertificateQuery($courseSlu
|
||||||
/**
|
/**
|
||||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
* 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 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 }\n }\n }\n }\n"): (typeof documents)["\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 }\n }\n }\n }\n"];
|
export function graphql(source: "\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"): (typeof documents)["\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"];
|
||||||
/**
|
/**
|
||||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
* 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
|
|
@ -197,6 +197,11 @@ export const COURSE_SESSION_DETAIL_QUERY = graphql(`
|
||||||
learning_content {
|
learning_content {
|
||||||
id
|
id
|
||||||
title
|
title
|
||||||
|
content_assignment {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
assignment_type
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,9 @@ function editTask(task: AssignmentEvaluationTask) {
|
||||||
const courseSessionDetailResult = useCourseSessionDetailQuery();
|
const courseSessionDetailResult = useCourseSessionDetailQuery();
|
||||||
|
|
||||||
const assignmentDetail = computed(() => {
|
const assignmentDetail = computed(() => {
|
||||||
return courseSessionDetailResult.findAssignmentDetail(props.assignment.id.toString());
|
return courseSessionDetailResult.findAssignmentByAssignmentId(
|
||||||
|
props.assignment.id.toString()
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const dueDate = computed(() =>
|
const dueDate = computed(() =>
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,8 @@ const state = reactive({
|
||||||
});
|
});
|
||||||
|
|
||||||
const assignmentDetail = computed(() => {
|
const assignmentDetail = computed(() => {
|
||||||
return courseSessionDetailResult.findAssignmentDetail(
|
return courseSessionDetailResult.findAssignment(
|
||||||
props.learningContentAssignment.content_assignment_id.toString()
|
props.learningContentAssignment.id.toString()
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useCircleStore } from "@/stores/circle";
|
import { useCircleStore } from "@/stores/circle";
|
||||||
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
|
||||||
import type { CourseSessionUser } from "@/types";
|
import type { CourseSessionUser } from "@/types";
|
||||||
import { humanizeDuration } from "@/utils/humanizeDuration";
|
import { humanizeDuration } from "@/utils/humanizeDuration";
|
||||||
import sumBy from "lodash/sumBy";
|
import sumBy from "lodash/sumBy";
|
||||||
|
|
@ -11,6 +10,7 @@ import CircleDiagram from "./CircleDiagram.vue";
|
||||||
import CircleOverview from "./CircleOverview.vue";
|
import CircleOverview from "./CircleOverview.vue";
|
||||||
import DocumentSection from "./DocumentSection.vue";
|
import DocumentSection from "./DocumentSection.vue";
|
||||||
import LearningSequence from "./LearningSequence.vue";
|
import LearningSequence from "./LearningSequence.vue";
|
||||||
|
import { useCourseSessionDetailQuery } from "@/composables";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
courseSlug: string;
|
courseSlug: string;
|
||||||
|
|
@ -20,7 +20,8 @@ export interface Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const courseSessionsStore = useCourseSessionsStore();
|
const courseSessionDetailResult = useCourseSessionDetailQuery();
|
||||||
|
const circleStore = useCircleStore();
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
readonly: false,
|
readonly: false,
|
||||||
|
|
@ -29,7 +30,12 @@ const props = withDefaults(defineProps<Props>(), {
|
||||||
|
|
||||||
log.debug("CirclePage created", props.readonly, props.profileUser);
|
log.debug("CirclePage created", props.readonly, props.profileUser);
|
||||||
|
|
||||||
const circleStore = useCircleStore();
|
const circleExperts = computed(() => {
|
||||||
|
if (circleStore.circle) {
|
||||||
|
return courseSessionDetailResult.filterCircleExperts(circleStore.circle.slug);
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
});
|
||||||
|
|
||||||
const duration = computed(() => {
|
const duration = computed(() => {
|
||||||
if (circleStore.circle) {
|
if (circleStore.circle) {
|
||||||
|
|
@ -190,10 +196,7 @@ onMounted(async () => {
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div v-for="expert in circleExperts" :key="expert.user_id">
|
||||||
v-for="expert in courseSessionsStore.circleExperts"
|
|
||||||
:key="expert.user_id"
|
|
||||||
>
|
|
||||||
<div class="mb-2 mt-2 flex flex-row items-center">
|
<div class="mb-2 mt-2 flex flex-row items-center">
|
||||||
<img
|
<img
|
||||||
class="mr-2 h-[45px] rounded-full"
|
class="mr-2 h-[45px] rounded-full"
|
||||||
|
|
@ -205,8 +208,8 @@ onMounted(async () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a
|
<a
|
||||||
v-if="courseSessionsStore.circleExperts.length > 0"
|
v-if="circleExperts.length > 0"
|
||||||
:href="'mailto:' + courseSessionsStore.circleExperts[0].email"
|
:href="'mailto:' + circleExperts[0].email"
|
||||||
class="btn-secondary mt-4 text-xl"
|
class="btn-secondary mt-4 text-xl"
|
||||||
>
|
>
|
||||||
{{ $t("circlePage.contactExpertButton") }}
|
{{ $t("circlePage.contactExpertButton") }}
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,19 @@
|
||||||
import DateEmbedding from "@/components/dueDates/DateEmbedding.vue";
|
import DateEmbedding from "@/components/dueDates/DateEmbedding.vue";
|
||||||
import type { Assignment } from "@/types";
|
import type { Assignment } from "@/types";
|
||||||
import { useRouteQuery } from "@vueuse/router";
|
import { useRouteQuery } from "@vueuse/router";
|
||||||
import type { Dayjs } from "dayjs";
|
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
assignment: Assignment;
|
assignment: Assignment;
|
||||||
dueDate?: Dayjs;
|
submissionDeadlineStart?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
dueDate: undefined,
|
submissionDeadlineStart: "",
|
||||||
});
|
});
|
||||||
|
|
||||||
log.debug("AssignmentIntroductionView created", props.assignment, props.dueDate);
|
log.debug("AssignmentIntroductionView created", props.assignment);
|
||||||
|
|
||||||
const step = useRouteQuery("step");
|
const step = useRouteQuery("step");
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -40,9 +40,10 @@ const step = useRouteQuery("step");
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3 class="mb-4 mt-8">{{ $t("assignment.dueDateSubmission") }}</h3>
|
<h3 class="mb-4 mt-8">{{ $t("assignment.dueDateSubmission") }}</h3>
|
||||||
<p v-if="props.dueDate?.toString() === 'Invalid Date'" class="text-large">
|
|
||||||
|
<p v-if="submissionDeadlineStart" class="text-large">
|
||||||
{{ $t("assignment.dueDateIntroduction") }}
|
{{ $t("assignment.dueDateIntroduction") }}
|
||||||
<DateEmbedding :single-date="dueDate"></DateEmbedding>
|
<DateEmbedding :single-date="dayjs(submissionDeadlineStart)"></DateEmbedding>
|
||||||
</p>
|
</p>
|
||||||
<p v-else class="text-large">
|
<p v-else class="text-large">
|
||||||
{{ $t("assignment.dueDateNotSet") }}
|
{{ $t("assignment.dueDateNotSet") }}
|
||||||
|
|
|
||||||
|
|
@ -3,34 +3,36 @@ import DateEmbedding from "@/components/dueDates/DateEmbedding.vue";
|
||||||
import ItButton from "@/components/ui/ItButton.vue";
|
import ItButton from "@/components/ui/ItButton.vue";
|
||||||
import ItCheckbox from "@/components/ui/ItCheckbox.vue";
|
import ItCheckbox from "@/components/ui/ItCheckbox.vue";
|
||||||
import ItSuccessAlert from "@/components/ui/ItSuccessAlert.vue";
|
import ItSuccessAlert from "@/components/ui/ItSuccessAlert.vue";
|
||||||
import { useCurrentCourseSession } from "@/composables";
|
import { useCourseSessionDetailQuery, useCurrentCourseSession } from "@/composables";
|
||||||
import { bustItGetCache } from "@/fetchHelpers";
|
import { bustItGetCache } from "@/fetchHelpers";
|
||||||
import { UPSERT_ASSIGNMENT_COMPLETION_MUTATION } from "@/graphql/mutations";
|
import { UPSERT_ASSIGNMENT_COMPLETION_MUTATION } from "@/graphql/mutations";
|
||||||
import AssignmentSubmissionResponses from "@/pages/learningPath/learningContentPage/assignment/AssignmentSubmissionResponses.vue";
|
import AssignmentSubmissionResponses from "@/pages/learningPath/learningContentPage/assignment/AssignmentSubmissionResponses.vue";
|
||||||
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
|
||||||
import { useUserStore } from "@/stores/user";
|
import { useUserStore } from "@/stores/user";
|
||||||
import type { Assignment, AssignmentCompletion, AssignmentTask } from "@/types";
|
import type { Assignment, AssignmentCompletion, AssignmentTask } from "@/types";
|
||||||
import { useMutation } from "@urql/vue";
|
import { useMutation } from "@urql/vue";
|
||||||
import type { Dayjs } from "dayjs";
|
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import { computed, reactive } from "vue";
|
import { computed, reactive } from "vue";
|
||||||
import { useTranslation } from "i18next-vue";
|
import { useTranslation } from "i18next-vue";
|
||||||
import eventBus from "@/utils/eventBus";
|
import eventBus from "@/utils/eventBus";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import { useCircleStore } from "@/stores/circle";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
assignment: Assignment;
|
assignment: Assignment;
|
||||||
learningContentId: number;
|
learningContentId: number;
|
||||||
assignmentCompletion?: AssignmentCompletion;
|
assignmentCompletion?: AssignmentCompletion;
|
||||||
courseSessionId: number;
|
courseSessionId: number;
|
||||||
dueDate: Dayjs;
|
submissionDeadlineStart?: string;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: "editTask", task: AssignmentTask): void;
|
(e: "editTask", task: AssignmentTask): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const courseSessionsStore = useCourseSessionsStore();
|
|
||||||
const courseSession = useCurrentCourseSession();
|
const courseSession = useCurrentCourseSession();
|
||||||
|
const courseSessionDetailResult = useCourseSessionDetailQuery();
|
||||||
|
const circleStore = useCircleStore();
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
|
|
@ -38,8 +40,15 @@ const state = reactive({
|
||||||
confirmPerson: false,
|
confirmPerson: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const circleExperts = computed(() => {
|
||||||
|
if (circleStore.circle) {
|
||||||
|
return courseSessionDetailResult.filterCircleExperts(circleStore.circle.slug);
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
});
|
||||||
|
|
||||||
const circleExpert = computed(() => {
|
const circleExpert = computed(() => {
|
||||||
return courseSessionsStore.circleExperts[0];
|
return circleExperts.value[0];
|
||||||
});
|
});
|
||||||
|
|
||||||
const circleExpertName = computed(() => {
|
const circleExpertName = computed(() => {
|
||||||
|
|
@ -138,9 +147,11 @@ const onSubmit = async () => {
|
||||||
{{ $t("assignment.showAssessmentDocument") }}
|
{{ $t("assignment.showAssessmentDocument") }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<p v-if="isCasework" class="pt-6">
|
<p v-if="isCasework && props.submissionDeadlineStart" class="pt-6">
|
||||||
{{ $t("assignment.dueDateSubmission") }}
|
{{ $t("assignment.dueDateSubmission") }}
|
||||||
<DateEmbedding :single-date="dueDate"></DateEmbedding>
|
<DateEmbedding
|
||||||
|
:single-date="dayjs(props.submissionDeadlineStart)"
|
||||||
|
></DateEmbedding>
|
||||||
</p>
|
</p>
|
||||||
<ItButton
|
<ItButton
|
||||||
class="mt-6"
|
class="mt-6"
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,22 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useCurrentCourseSession } from "@/composables";
|
import { useCourseSessionDetailQuery, useCurrentCourseSession } from "@/composables";
|
||||||
import { UPSERT_ASSIGNMENT_COMPLETION_MUTATION } from "@/graphql/mutations";
|
import { UPSERT_ASSIGNMENT_COMPLETION_MUTATION } from "@/graphql/mutations";
|
||||||
import { ASSIGNMENT_COMPLETION_QUERY } from "@/graphql/queries";
|
import { ASSIGNMENT_COMPLETION_QUERY } from "@/graphql/queries";
|
||||||
import AssignmentIntroductionView from "@/pages/learningPath/learningContentPage/assignment/AssignmentIntroductionView.vue";
|
import AssignmentIntroductionView from "@/pages/learningPath/learningContentPage/assignment/AssignmentIntroductionView.vue";
|
||||||
import AssignmentSubmissionView from "@/pages/learningPath/learningContentPage/assignment/AssignmentSubmissionView.vue";
|
import AssignmentSubmissionView from "@/pages/learningPath/learningContentPage/assignment/AssignmentSubmissionView.vue";
|
||||||
import AssignmentTaskView from "@/pages/learningPath/learningContentPage/assignment/AssignmentTaskView.vue";
|
import AssignmentTaskView from "@/pages/learningPath/learningContentPage/assignment/AssignmentTaskView.vue";
|
||||||
import LearningContentMultiLayout from "@/pages/learningPath/learningContentPage/layouts/LearningContentMultiLayout.vue";
|
import LearningContentMultiLayout from "@/pages/learningPath/learningContentPage/layouts/LearningContentMultiLayout.vue";
|
||||||
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
|
||||||
import { useUserStore } from "@/stores/user";
|
import { useUserStore } from "@/stores/user";
|
||||||
import type {
|
import type {
|
||||||
Assignment,
|
Assignment,
|
||||||
AssignmentCompletion,
|
AssignmentCompletion,
|
||||||
AssignmentTask,
|
AssignmentTask,
|
||||||
CourseSessionAssignment,
|
|
||||||
CourseSessionUser,
|
|
||||||
LearningContentAssignment,
|
LearningContentAssignment,
|
||||||
} from "@/types";
|
} from "@/types";
|
||||||
import { useMutation, useQuery } from "@urql/vue";
|
import { useMutation, useQuery } from "@urql/vue";
|
||||||
import { useRouteQuery } from "@vueuse/router";
|
import { useRouteQuery } from "@vueuse/router";
|
||||||
import dayjs from "dayjs";
|
|
||||||
import * as log from "loglevel";
|
import * as log from "loglevel";
|
||||||
import { computed, onMounted, reactive, ref, watchEffect } from "vue";
|
import { computed, onMounted, ref, watchEffect } from "vue";
|
||||||
import { useTranslation } from "i18next-vue";
|
import { useTranslation } from "i18next-vue";
|
||||||
import { bustItGetCache } from "@/fetchHelpers";
|
import { bustItGetCache } from "@/fetchHelpers";
|
||||||
import { learningContentTypeData } from "@/utils/typeMaps";
|
import { learningContentTypeData } from "@/utils/typeMaps";
|
||||||
|
|
@ -30,14 +26,6 @@ const { t } = useTranslation();
|
||||||
const courseSession = useCurrentCourseSession();
|
const courseSession = useCurrentCourseSession();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
|
||||||
interface State {
|
|
||||||
courseSessionAssignment: CourseSessionAssignment | undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const state: State = reactive({
|
|
||||||
courseSessionAssignment: undefined,
|
|
||||||
});
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
learningContent: LearningContentAssignment;
|
learningContent: LearningContentAssignment;
|
||||||
}>();
|
}>();
|
||||||
|
|
@ -52,10 +40,17 @@ const queryResult = useQuery({
|
||||||
pause: true,
|
pause: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const courseSessionDetailResult = useCourseSessionDetailQuery();
|
||||||
|
|
||||||
const upsertAssignmentCompletionMutation = useMutation(
|
const upsertAssignmentCompletionMutation = useMutation(
|
||||||
UPSERT_ASSIGNMENT_COMPLETION_MUTATION
|
UPSERT_ASSIGNMENT_COMPLETION_MUTATION
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const submissionDeadline = computed(() => {
|
||||||
|
return courseSessionDetailResult.findAssignment(props.learningContent.id.toString())
|
||||||
|
?.submission_deadline;
|
||||||
|
});
|
||||||
|
|
||||||
// FIXME daniel: `useRouteQuery` from usevue is currently the reason that we have to
|
// FIXME daniel: `useRouteQuery` from usevue is currently the reason that we have to
|
||||||
// fix the version of @vueuse/router and @vueuse/core to 10.1.0
|
// fix the version of @vueuse/router and @vueuse/core to 10.1.0
|
||||||
// it fails with version 10.2.0. I have a reminder to check out the situation
|
// it fails with version 10.2.0. I have a reminder to check out the situation
|
||||||
|
|
@ -104,10 +99,6 @@ onMounted(async () => {
|
||||||
props.learningContent
|
props.learningContent
|
||||||
);
|
);
|
||||||
|
|
||||||
state.courseSessionAssignment = useCourseSessionsStore().findCourseSessionAssignment(
|
|
||||||
props.learningContent.id
|
|
||||||
);
|
|
||||||
|
|
||||||
// create initial `AssignmentCompletion` first, so that it exists and we don't
|
// create initial `AssignmentCompletion` first, so that it exists and we don't
|
||||||
// have reactivity problem accessing it.
|
// have reactivity problem accessing it.
|
||||||
await initUpsertAssignmentCompletion();
|
await initUpsertAssignmentCompletion();
|
||||||
|
|
@ -120,9 +111,7 @@ const numPages = computed(() => {
|
||||||
});
|
});
|
||||||
const showPreviousButton = computed(() => stepIndex.value != 0);
|
const showPreviousButton = computed(() => stepIndex.value != 0);
|
||||||
const showNextButton = computed(() => stepIndex.value + 1 < numPages.value);
|
const showNextButton = computed(() => stepIndex.value + 1 < numPages.value);
|
||||||
const dueDate = computed(() =>
|
|
||||||
dayjs(state.courseSessionAssignment?.submission_deadline_start)
|
|
||||||
);
|
|
||||||
const currentTask = computed(() => {
|
const currentTask = computed(() => {
|
||||||
if (stepIndex.value > 0 && stepIndex.value <= numTasks.value) {
|
if (stepIndex.value > 0 && stepIndex.value <= numTasks.value) {
|
||||||
return assignment.value?.tasks[stepIndex.value - 1];
|
return assignment.value?.tasks[stepIndex.value - 1];
|
||||||
|
|
@ -194,9 +183,9 @@ const subTitle = computed(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const assignmentUser = computed(() => {
|
const assignmentUser = computed(() => {
|
||||||
return courseSession.value.users.find(
|
return (courseSessionDetailResult.courseSessionDetail.value?.users ?? []).find(
|
||||||
(user) => user.user_id === userStore.id
|
(u) => u.user_id === userStore.id
|
||||||
) as CourseSessionUser;
|
);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -204,7 +193,7 @@ const assignmentUser = computed(() => {
|
||||||
<div v-if="queryResult.fetching.value"></div>
|
<div v-if="queryResult.fetching.value"></div>
|
||||||
<div v-else-if="queryResult.error.value">{{ queryResult.error.value }}</div>
|
<div v-else-if="queryResult.error.value">{{ queryResult.error.value }}</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div v-if="assignment && assignmentCompletion">
|
<div v-if="assignment && assignmentCompletion && assignmentUser">
|
||||||
<div class="flex flex-col lg:flex-row">
|
<div class="flex flex-col lg:flex-row">
|
||||||
<div
|
<div
|
||||||
v-if="assignmentCompletion?.completion_status === 'EVALUATION_SUBMITTED'"
|
v-if="assignmentCompletion?.completion_status === 'EVALUATION_SUBMITTED'"
|
||||||
|
|
@ -239,8 +228,8 @@ const assignmentUser = computed(() => {
|
||||||
<div>
|
<div>
|
||||||
<AssignmentIntroductionView
|
<AssignmentIntroductionView
|
||||||
v-if="stepIndex === 0"
|
v-if="stepIndex === 0"
|
||||||
:due-date="dueDate"
|
|
||||||
:assignment="assignment"
|
:assignment="assignment"
|
||||||
|
:submission-deadline-start="submissionDeadline?.start"
|
||||||
></AssignmentIntroductionView>
|
></AssignmentIntroductionView>
|
||||||
<AssignmentTaskView
|
<AssignmentTaskView
|
||||||
v-else-if="currentTask"
|
v-else-if="currentTask"
|
||||||
|
|
@ -251,11 +240,11 @@ const assignmentUser = computed(() => {
|
||||||
></AssignmentTaskView>
|
></AssignmentTaskView>
|
||||||
<AssignmentSubmissionView
|
<AssignmentSubmissionView
|
||||||
v-else-if="stepIndex + 1 === numPages"
|
v-else-if="stepIndex + 1 === numPages"
|
||||||
:due-date="dueDate"
|
|
||||||
:assignment="assignment"
|
:assignment="assignment"
|
||||||
:assignment-completion="assignmentCompletion"
|
:assignment-completion="assignmentCompletion"
|
||||||
:learning-content-id="props.learningContent.id"
|
:learning-content-id="props.learningContent.id"
|
||||||
:course-session-id="courseSession.id"
|
:course-session-id="courseSession.id"
|
||||||
|
:submission-deadline-start="submissionDeadline?.start"
|
||||||
@edit-task="jumpToTask($event)"
|
@edit-task="jumpToTask($event)"
|
||||||
></AssignmentSubmissionView>
|
></AssignmentSubmissionView>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,12 @@
|
||||||
<it-icon-calendar-light class="w-[60px] grid-in-icon" />
|
<it-icon-calendar-light class="w-[60px] grid-in-icon" />
|
||||||
<h2 class="text-large font-bold grid-in-title">{{ $t("a.Datum") }}</h2>
|
<h2 class="text-large font-bold grid-in-title">{{ $t("a.Datum") }}</h2>
|
||||||
<p class="grid-in-value">
|
<p class="grid-in-value">
|
||||||
{{ formatDueDate(props.attendanceCourse.start, props.attendanceCourse.end) }}
|
{{
|
||||||
|
formatDueDate(
|
||||||
|
props.attendanceCourse.due_date.start,
|
||||||
|
props.attendanceCourse.due_date.end
|
||||||
|
)
|
||||||
|
}}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-12 grid grid-cols-icon-card gap-x-4 grid-areas-icon-card">
|
<div class="mb-12 grid grid-cols-icon-card gap-x-4 grid-areas-icon-card">
|
||||||
|
|
@ -24,8 +29,6 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { formatDueDate } from "@/components/dueDates/dueDatesUtils";
|
import { formatDueDate } from "@/components/dueDates/dueDatesUtils";
|
||||||
import type { CourseSessionAttendanceCourse } from "@/types";
|
import type { CourseSessionAttendanceCourse } from "@/types";
|
||||||
import dayjs from "dayjs";
|
|
||||||
import LocalizedFormat from "dayjs/plugin/localizedFormat";
|
|
||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
|
|
@ -34,7 +37,6 @@ export interface Props {
|
||||||
|
|
||||||
const props = defineProps<Props>();
|
const props = defineProps<Props>();
|
||||||
|
|
||||||
dayjs.extend(LocalizedFormat);
|
|
||||||
const location = computed(() => props.attendanceCourse.location);
|
const location = computed(() => props.attendanceCourse.location);
|
||||||
const trainer = computed(() => props.attendanceCourse.trainer);
|
const trainer = computed(() => props.attendanceCourse.trainer);
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import AttendanceCourse from "@/pages/learningPath/learningContentPage/attendanceCourse/AttendanceCourse.vue";
|
import AttendanceCourse from "@/pages/learningPath/learningContentPage/attendanceCourse/AttendanceCourse.vue";
|
||||||
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
|
||||||
import type { LearningContentAttendanceCourse } from "@/types";
|
import type { LearningContentAttendanceCourse } from "@/types";
|
||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
import LearningContentSimpleLayout from "../layouts/LearningContentSimpleLayout.vue";
|
import LearningContentSimpleLayout from "../layouts/LearningContentSimpleLayout.vue";
|
||||||
|
import { useCourseSessionDetailQuery } from "@/composables";
|
||||||
const courseSessionsStore = useCourseSessionsStore();
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
content: LearningContentAttendanceCourse;
|
content: LearningContentAttendanceCourse;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const courseSessionDetailResult = useCourseSessionDetailQuery();
|
||||||
|
|
||||||
const courseSessionAttendanceCourse = computed(() => {
|
const courseSessionAttendanceCourse = computed(() => {
|
||||||
return courseSessionsStore.findAttendanceCourse(props.content.id);
|
return courseSessionDetailResult.findAttendanceCourse(props.content.id.toString());
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,7 @@ import * as log from "loglevel";
|
||||||
import { itPost } from "@/fetchHelpers";
|
import { itPost } from "@/fetchHelpers";
|
||||||
import { useQuery } from "@urql/vue";
|
import { useQuery } from "@urql/vue";
|
||||||
import { ASSIGNMENT_COMPLETION_QUERY } from "@/graphql/queries";
|
import { ASSIGNMENT_COMPLETION_QUERY } from "@/graphql/queries";
|
||||||
import { useCurrentCourseSession } from "@/composables";
|
import { useCourseSessionDetailQuery, useCurrentCourseSession } from "@/composables";
|
||||||
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import ItSuccessAlert from "@/components/ui/ItSuccessAlert.vue";
|
import ItSuccessAlert from "@/components/ui/ItSuccessAlert.vue";
|
||||||
import {
|
import {
|
||||||
|
|
@ -24,10 +23,10 @@ const props = defineProps<{
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const courseSession = useCurrentCourseSession();
|
const courseSession = useCurrentCourseSession();
|
||||||
const courseSessionsStore = useCourseSessionsStore();
|
const courseSessionDetailResult = useCourseSessionDetailQuery();
|
||||||
|
|
||||||
const courseSessionEdoniqTest = computed(() => {
|
const courseSessionEdoniqTest = computed(() => {
|
||||||
return courseSessionsStore.findCourseSessionEdoniqTest(props.content.id);
|
return courseSessionDetailResult.findEdoniqTest(props.content.id.toString());
|
||||||
});
|
});
|
||||||
|
|
||||||
const queryResult = useQuery({
|
const queryResult = useQuery({
|
||||||
|
|
@ -53,7 +52,7 @@ const extendedTimeTest = ref(false);
|
||||||
|
|
||||||
const deadlineInPast = computed(() => {
|
const deadlineInPast = computed(() => {
|
||||||
// with 16 minutes buffer
|
// with 16 minutes buffer
|
||||||
return dayjs(courseSessionEdoniqTest.value?.deadline_start)
|
return dayjs(courseSessionEdoniqTest.value?.deadline.start)
|
||||||
.add(16, "minute")
|
.add(16, "minute")
|
||||||
.isBefore(dayjs());
|
.isBefore(dayjs());
|
||||||
});
|
});
|
||||||
|
|
@ -90,7 +89,7 @@ async function startTest() {
|
||||||
<p class="mt-2 text-lg">
|
<p class="mt-2 text-lg">
|
||||||
{{
|
{{
|
||||||
$t("edoniqTest.submitDateDescription", {
|
$t("edoniqTest.submitDateDescription", {
|
||||||
x: formatDueDate(courseSessionEdoniqTest.deadline_start),
|
x: formatDueDate(courseSessionEdoniqTest.deadline.start),
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -158,7 +157,7 @@ async function startTest() {
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
{{ $t("a.Abgabetermin") }}:
|
{{ $t("a.Abgabetermin") }}:
|
||||||
{{ getDateString(dayjs(courseSessionEdoniqTest?.deadline_start)) }}
|
{{ getDateString(dayjs(courseSessionEdoniqTest?.deadline.start)) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -10,21 +10,21 @@ import {
|
||||||
} from "@/pages/learningPath/learningContentPage/feedback/feedback.constants";
|
} from "@/pages/learningPath/learningContentPage/feedback/feedback.constants";
|
||||||
import LearningContentMultiLayout from "@/pages/learningPath/learningContentPage/layouts/LearningContentMultiLayout.vue";
|
import LearningContentMultiLayout from "@/pages/learningPath/learningContentPage/layouts/LearningContentMultiLayout.vue";
|
||||||
import { useCircleStore } from "@/stores/circle";
|
import { useCircleStore } from "@/stores/circle";
|
||||||
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
|
||||||
import type { LearningContentFeedback } from "@/types";
|
import type { LearningContentFeedback } from "@/types";
|
||||||
import { useMutation } from "@urql/vue";
|
import { useMutation } from "@urql/vue";
|
||||||
import { useRouteQuery } from "@vueuse/router";
|
import { useRouteQuery } from "@vueuse/router";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import { computed, onMounted, reactive, ref } from "vue";
|
import { computed, onMounted, reactive, ref } from "vue";
|
||||||
import { useTranslation } from "i18next-vue";
|
import { useTranslation } from "i18next-vue";
|
||||||
import { useCurrentCourseSession } from "@/composables";
|
import { useCourseSessionDetailQuery, useCurrentCourseSession } from "@/composables";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
content: LearningContentFeedback;
|
content: LearningContentFeedback;
|
||||||
}>();
|
}>();
|
||||||
const courseSessionsStore = useCourseSessionsStore();
|
|
||||||
const courseSession = useCurrentCourseSession();
|
const courseSession = useCurrentCourseSession();
|
||||||
const circleStore = useCircleStore();
|
const circleStore = useCircleStore();
|
||||||
|
const courseSessionDetailResult = useCourseSessionDetailQuery();
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const stepNo = useRouteQuery("step", "0", { transform: Number, mode: "push" });
|
const stepNo = useRouteQuery("step", "0", { transform: Number, mode: "push" });
|
||||||
|
|
@ -33,6 +33,13 @@ const title = computed(
|
||||||
() => `«${circleStore.circle?.title}»: ${t("feedback.areYouSatisfied")}`
|
() => `«${circleStore.circle?.title}»: ${t("feedback.areYouSatisfied")}`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const circleExperts = computed(() => {
|
||||||
|
if (circleStore.circle) {
|
||||||
|
return courseSessionDetailResult.filterCircleExperts(circleStore.circle.slug);
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
});
|
||||||
|
|
||||||
const stepLabels = [
|
const stepLabels = [
|
||||||
t("general.introduction"),
|
t("general.introduction"),
|
||||||
t("feedback.satisfactionLabel"),
|
t("feedback.satisfactionLabel"),
|
||||||
|
|
@ -244,7 +251,7 @@ onMounted(async () => {
|
||||||
<p v-if="stepNo === 0" class="mt-10">
|
<p v-if="stepNo === 0" class="mt-10">
|
||||||
{{
|
{{
|
||||||
$t("feedback.intro", {
|
$t("feedback.intro", {
|
||||||
name: `${courseSessionsStore.circleExperts[0]?.first_name} ${courseSessionsStore.circleExperts[0]?.last_name}`,
|
name: `${circleExperts[0]?.first_name} ${circleExperts[0]?.last_name}`,
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -265,10 +272,10 @@ onMounted(async () => {
|
||||||
</div>
|
</div>
|
||||||
<FeedbackCompletition
|
<FeedbackCompletition
|
||||||
v-if="stepNo === 11"
|
v-if="stepNo === 11"
|
||||||
:avatar-url="courseSessionsStore.circleExperts[0].avatar_url"
|
:avatar-url="circleExperts[0].avatar_url"
|
||||||
:title="
|
:title="
|
||||||
$t('feedback.completionTitle', {
|
$t('feedback.completionTitle', {
|
||||||
name: `${courseSessionsStore.circleExperts[0].first_name} ${courseSessionsStore.circleExperts[0].last_name}`,
|
name: `${circleExperts[0].first_name} ${circleExperts[0].last_name}`,
|
||||||
})
|
})
|
||||||
"
|
"
|
||||||
:description="$t('feedback.completionDescription')"
|
:description="$t('feedback.completionDescription')"
|
||||||
|
|
|
||||||
|
|
@ -147,23 +147,6 @@ export const useCourseSessionsStore = defineStore("courseSessions", () => {
|
||||||
return Boolean(isCourseExpert && (inLearningPath() || inCompetenceProfile()));
|
return Boolean(isCourseExpert && (inLearningPath() || inCompetenceProfile()));
|
||||||
});
|
});
|
||||||
|
|
||||||
// const circleExperts = computed(() => {
|
|
||||||
// const circleStore = useCircleStore();
|
|
||||||
// const circleTranslationKey = circleStore.circle?.translation_key;
|
|
||||||
//
|
|
||||||
// if (currentCourseSession.value && circleTranslationKey) {
|
|
||||||
// return currentCourseSession.value.users.filter((u) => {
|
|
||||||
// if (u.role === "EXPERT") {
|
|
||||||
// return (u as ExpertSessionUser).circles
|
|
||||||
// .map((c) => c.translation_key)
|
|
||||||
// .includes(circleTranslationKey);
|
|
||||||
// }
|
|
||||||
// return false;
|
|
||||||
// }) as ExpertSessionUser[];
|
|
||||||
// }
|
|
||||||
// return [];
|
|
||||||
// });
|
|
||||||
|
|
||||||
// const canUploadCircleDocuments = computed(() => {
|
// const canUploadCircleDocuments = computed(() => {
|
||||||
// const userStore = useUserStore();
|
// const userStore = useUserStore();
|
||||||
// return (
|
// return (
|
||||||
|
|
@ -249,36 +232,6 @@ export const useCourseSessionsStore = defineStore("courseSessions", () => {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// function findAttendanceCourse(
|
|
||||||
// contentId: number
|
|
||||||
// ): CourseSessionAttendanceCourse | undefined {
|
|
||||||
// if (currentCourseSession.value) {
|
|
||||||
// return currentCourseSession.value.attendance_courses.find(
|
|
||||||
// (attendanceCourse) => attendanceCourse.learning_content_id === contentId
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function findCourseSessionAssignment(
|
|
||||||
// contentId?: number
|
|
||||||
// ): CourseSessionAssignment | undefined {
|
|
||||||
// if (contentId && currentCourseSession.value) {
|
|
||||||
// return currentCourseSession.value.assignments.find(
|
|
||||||
// (a) => a.learning_content_id === contentId
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// function findCourseSessionEdoniqTest(
|
|
||||||
// contentId?: number
|
|
||||||
// ): CourseSessionEdoniqTest | undefined {
|
|
||||||
// if (contentId && currentCourseSession.value) {
|
|
||||||
// return currentCourseSession.value.edoniq_tests.find(
|
|
||||||
// (a) => a.learning_content_id === contentId
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
uniqueCourseSessionsByCourse,
|
uniqueCourseSessionsByCourse,
|
||||||
allCurrentCourseSessions,
|
allCurrentCourseSessions,
|
||||||
|
|
|
||||||
|
|
@ -496,9 +496,15 @@ export interface CourseSessionAssignment {
|
||||||
export interface CourseSessionEdoniqTest {
|
export interface CourseSessionEdoniqTest {
|
||||||
id: number;
|
id: number;
|
||||||
course_session_id: number;
|
course_session_id: number;
|
||||||
learning_content_id: number;
|
deadline: SimpleDueDate;
|
||||||
deadline_id: number;
|
learning_content: {
|
||||||
deadline_start: string;
|
id: string;
|
||||||
|
content_assignment: {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
assignment_type: AssignmentType;
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CourseSession {
|
export interface CourseSession {
|
||||||
|
|
@ -559,6 +565,7 @@ export interface CourseSessionDetail {
|
||||||
};
|
};
|
||||||
assignments: CourseSessionAssignment[];
|
assignments: CourseSessionAssignment[];
|
||||||
attendance_courses: CourseSessionAttendanceCourse[];
|
attendance_courses: CourseSessionAttendanceCourse[];
|
||||||
|
edoniq_tests: CourseSessionEdoniqTest[];
|
||||||
users: CourseSessionUser[];
|
users: CourseSessionUser[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,13 @@ from graphene_django import DjangoObjectType
|
||||||
from graphql import GraphQLError
|
from graphql import GraphQLError
|
||||||
from rest_framework.exceptions import PermissionDenied
|
from rest_framework.exceptions import PermissionDenied
|
||||||
|
|
||||||
from vbv_lernwelt.course.models import Course, CourseBasePage, CoursePage, \
|
from vbv_lernwelt.course.models import (
|
||||||
CourseSession, CourseSessionUser
|
Course,
|
||||||
|
CourseBasePage,
|
||||||
|
CoursePage,
|
||||||
|
CourseSession,
|
||||||
|
CourseSessionUser,
|
||||||
|
)
|
||||||
from vbv_lernwelt.course.permissions import has_course_access
|
from vbv_lernwelt.course.permissions import has_course_access
|
||||||
from vbv_lernwelt.course_session.graphql.types import (
|
from vbv_lernwelt.course_session.graphql.types import (
|
||||||
CourseSessionAttendanceCourseObjectType,
|
CourseSessionAttendanceCourseObjectType,
|
||||||
|
|
@ -134,9 +139,7 @@ class CourseSessionUserObjectsType(DjangoObjectType):
|
||||||
return self.role
|
return self.role
|
||||||
|
|
||||||
def resolve_circles(self, info):
|
def resolve_circles(self, info):
|
||||||
return self.expert.all().values(
|
return self.expert.all().values("id", "title", "slug", "translation_key")
|
||||||
"id", "title", "slug", "translation_key"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class CourseSessionObjectType(DjangoObjectType):
|
class CourseSessionObjectType(DjangoObjectType):
|
||||||
|
|
@ -165,10 +168,8 @@ class CourseSessionObjectType(DjangoObjectType):
|
||||||
def resolve_assignments(self, info):
|
def resolve_assignments(self, info):
|
||||||
return CourseSessionAssignment.objects.filter(course_session=self)
|
return CourseSessionAssignment.objects.filter(course_session=self)
|
||||||
|
|
||||||
def resolve_edoniq_test(self, info):
|
def resolve_edoniq_tests(self, info):
|
||||||
return CourseSessionEdoniqTest.objects.filter(course_session=self)
|
return CourseSessionEdoniqTest.objects.filter(course_session=self)
|
||||||
|
|
||||||
def resolve_users(self, info):
|
def resolve_users(self, info):
|
||||||
return CourseSessionUser.objects.filter(
|
return CourseSessionUser.objects.filter(course_session_id=self.id).distinct()
|
||||||
course_session_id=self.id
|
|
||||||
).distinct()
|
|
||||||
|
|
|
||||||
|
|
@ -7,16 +7,6 @@ from vbv_lernwelt.course.models import (
|
||||||
CourseCompletion,
|
CourseCompletion,
|
||||||
CourseSession,
|
CourseSession,
|
||||||
)
|
)
|
||||||
from vbv_lernwelt.course_session.models import (
|
|
||||||
CourseSessionAssignment,
|
|
||||||
CourseSessionAttendanceCourse,
|
|
||||||
CourseSessionEdoniqTest,
|
|
||||||
)
|
|
||||||
from vbv_lernwelt.course_session.serializers import (
|
|
||||||
CourseSessionAssignmentSerializer,
|
|
||||||
CourseSessionAttendanceCourseSerializer,
|
|
||||||
CourseSessionEdoniqTestSerializer,
|
|
||||||
)
|
|
||||||
from vbv_lernwelt.duedate.models import DueDate
|
from vbv_lernwelt.duedate.models import DueDate
|
||||||
from vbv_lernwelt.duedate.serializers import DueDateSerializer
|
from vbv_lernwelt.duedate.serializers import DueDateSerializer
|
||||||
|
|
||||||
|
|
@ -73,39 +63,12 @@ class CourseSessionSerializer(serializers.ModelSerializer):
|
||||||
def get_course_url(self, obj):
|
def get_course_url(self, obj):
|
||||||
return obj.course.get_course_url()
|
return obj.course.get_course_url()
|
||||||
|
|
||||||
def get_learning_path_url(self, obj):
|
|
||||||
return obj.course.get_learning_path_url()
|
|
||||||
|
|
||||||
def get_cockpit_url(self, obj):
|
|
||||||
return obj.course.get_cockpit_url()
|
|
||||||
|
|
||||||
def get_media_library_url(self, obj):
|
|
||||||
return obj.course.get_media_library_url()
|
|
||||||
|
|
||||||
def get_competence_url(self, obj):
|
|
||||||
return obj.course.get_competence_url()
|
|
||||||
|
|
||||||
def get_documents(self, obj):
|
def get_documents(self, obj):
|
||||||
documents = CircleDocument.objects.filter(
|
documents = CircleDocument.objects.filter(
|
||||||
course_session=obj, file__upload_finished_at__isnull=False
|
course_session=obj, file__upload_finished_at__isnull=False
|
||||||
)
|
)
|
||||||
return CircleDocumentSerializer(documents, many=True).data
|
return CircleDocumentSerializer(documents, many=True).data
|
||||||
|
|
||||||
def get_attendance_courses(self, obj):
|
|
||||||
return CourseSessionAttendanceCourseSerializer(
|
|
||||||
CourseSessionAttendanceCourse.objects.filter(course_session=obj), many=True
|
|
||||||
).data
|
|
||||||
|
|
||||||
def get_assignments(self, obj):
|
|
||||||
return CourseSessionAssignmentSerializer(
|
|
||||||
CourseSessionAssignment.objects.filter(course_session=obj), many=True
|
|
||||||
).data
|
|
||||||
|
|
||||||
def get_edoniq_tests(self, obj):
|
|
||||||
return CourseSessionEdoniqTestSerializer(
|
|
||||||
CourseSessionEdoniqTest.objects.filter(course_session=obj), many=True
|
|
||||||
).data
|
|
||||||
|
|
||||||
def get_due_dates(self, obj):
|
def get_due_dates(self, obj):
|
||||||
due_dates = DueDate.objects.filter(course_session=obj)
|
due_dates = DueDate.objects.filter(course_session=obj)
|
||||||
return DueDateSerializer(due_dates, many=True).data
|
return DueDateSerializer(due_dates, many=True).data
|
||||||
|
|
@ -120,16 +83,7 @@ class CourseSessionSerializer(serializers.ModelSerializer):
|
||||||
"title",
|
"title",
|
||||||
"start_date",
|
"start_date",
|
||||||
"end_date",
|
"end_date",
|
||||||
# "additional_json_data",
|
|
||||||
# "attendance_courses",
|
|
||||||
# "assignments",
|
|
||||||
# "edoniq_tests",
|
|
||||||
# "learning_path_url",
|
|
||||||
# "cockpit_url",
|
|
||||||
# "competence_url",
|
|
||||||
# "media_library_url",
|
|
||||||
"course_url",
|
"course_url",
|
||||||
# "documents",
|
|
||||||
"due_dates",
|
"due_dates",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ from vbv_lernwelt.course.permissions import is_course_session_expert
|
||||||
from vbv_lernwelt.course_session.models import (
|
from vbv_lernwelt.course_session.models import (
|
||||||
CourseSessionAttendanceCourse,
|
CourseSessionAttendanceCourse,
|
||||||
CourseSessionAssignment,
|
CourseSessionAssignment,
|
||||||
|
CourseSessionEdoniqTest,
|
||||||
)
|
)
|
||||||
from vbv_lernwelt.course_session.services.attendance import AttendanceUserStatus
|
from vbv_lernwelt.course_session.services.attendance import AttendanceUserStatus
|
||||||
from vbv_lernwelt.duedate.graphql.types import DueDateObjectType
|
from vbv_lernwelt.duedate.graphql.types import DueDateObjectType
|
||||||
|
|
@ -39,7 +40,6 @@ class CourseSessionAttendanceCourseObjectType(DjangoObjectType):
|
||||||
fields = (
|
fields = (
|
||||||
"id",
|
"id",
|
||||||
"course_session_id",
|
"course_session_id",
|
||||||
"learning_content_id",
|
|
||||||
"learning_content",
|
"learning_content",
|
||||||
"location",
|
"location",
|
||||||
"trainer",
|
"trainer",
|
||||||
|
|
@ -64,10 +64,9 @@ class CourseSessionAssignmentObjectType(DjangoObjectType):
|
||||||
fields = (
|
fields = (
|
||||||
"id",
|
"id",
|
||||||
"course_session_id",
|
"course_session_id",
|
||||||
"learning_content_id",
|
"learning_content",
|
||||||
"submission_deadline",
|
"submission_deadline",
|
||||||
"evaluation_deadline",
|
"evaluation_deadline",
|
||||||
"learning_content",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -78,11 +77,10 @@ class CourseSessionEdoniqTestObjectType(DjangoObjectType):
|
||||||
learning_content = graphene.Field(LearningContentEdoniqTestObjectType)
|
learning_content = graphene.Field(LearningContentEdoniqTestObjectType)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CourseSessionAssignment
|
model = CourseSessionEdoniqTest
|
||||||
fields = (
|
fields = (
|
||||||
"id",
|
"id",
|
||||||
"course_session_id",
|
"course_session_id",
|
||||||
"learning_content_id",
|
|
||||||
"deadline",
|
|
||||||
"learning_content",
|
"learning_content",
|
||||||
|
"deadline",
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue