wip: Add new content types
This commit is contained in:
parent
421a10524b
commit
d1504f592d
|
|
@ -585,8 +585,25 @@ export type LearningContentEdoniqTestObjectType = CoursePageInterface & Learning
|
|||
translation_key: Scalars['String']['output'];
|
||||
};
|
||||
|
||||
export type LearningContentFeedbackObjectType = CoursePageInterface & LearningContentInterface & {
|
||||
__typename?: 'LearningContentFeedbackObjectType';
|
||||
export type LearningContentFeedbackUkObjectType = CoursePageInterface & LearningContentInterface & {
|
||||
__typename?: 'LearningContentFeedbackUKObjectType';
|
||||
can_user_self_toggle_course_completion: Scalars['Boolean']['output'];
|
||||
circle?: Maybe<CircleLightObjectType>;
|
||||
content_type: Scalars['String']['output'];
|
||||
content_url: Scalars['String']['output'];
|
||||
course?: Maybe<CourseObjectType>;
|
||||
description: Scalars['String']['output'];
|
||||
frontend_url: Scalars['String']['output'];
|
||||
id: Scalars['ID']['output'];
|
||||
live: Scalars['Boolean']['output'];
|
||||
minutes?: Maybe<Scalars['Int']['output']>;
|
||||
slug: Scalars['String']['output'];
|
||||
title: Scalars['String']['output'];
|
||||
translation_key: Scalars['String']['output'];
|
||||
};
|
||||
|
||||
export type LearningContentFeedbackVvObjectType = CoursePageInterface & LearningContentInterface & {
|
||||
__typename?: 'LearningContentFeedbackVVObjectType';
|
||||
can_user_self_toggle_course_completion: Scalars['Boolean']['output'];
|
||||
circle?: Maybe<CircleLightObjectType>;
|
||||
content_type: Scalars['String']['output'];
|
||||
|
|
@ -870,7 +887,8 @@ export type Query = {
|
|||
learning_content_assignment?: Maybe<LearningContentAssignmentObjectType>;
|
||||
learning_content_attendance_course?: Maybe<LearningContentAttendanceCourseObjectType>;
|
||||
learning_content_document_list?: Maybe<LearningContentDocumentListObjectType>;
|
||||
learning_content_feedback?: Maybe<LearningContentFeedbackObjectType>;
|
||||
learning_content_feedback_uk?: Maybe<LearningContentFeedbackUkObjectType>;
|
||||
learning_content_feedback_vv?: Maybe<LearningContentFeedbackVvObjectType>;
|
||||
learning_content_knowledge_assessment?: Maybe<LearningContentKnowledgeAssessmentObjectType>;
|
||||
learning_content_learning_module?: Maybe<LearningContentLearningModuleObjectType>;
|
||||
learning_content_media_library?: Maybe<LearningContentMediaLibraryObjectType>;
|
||||
|
|
@ -1045,7 +1063,9 @@ type CoursePageFieldsLearningContentDocumentListObjectTypeFragment = { __typenam
|
|||
|
||||
type CoursePageFieldsLearningContentEdoniqTestObjectTypeFragment = { __typename?: 'LearningContentEdoniqTestObjectType', title: string, id: string, slug: string, content_type: string, frontend_url: string } & { ' $fragmentName'?: 'CoursePageFieldsLearningContentEdoniqTestObjectTypeFragment' };
|
||||
|
||||
type CoursePageFieldsLearningContentFeedbackObjectTypeFragment = { __typename?: 'LearningContentFeedbackObjectType', title: string, id: string, slug: string, content_type: string, frontend_url: string } & { ' $fragmentName'?: 'CoursePageFieldsLearningContentFeedbackObjectTypeFragment' };
|
||||
type CoursePageFieldsLearningContentFeedbackUkObjectTypeFragment = { __typename?: 'LearningContentFeedbackUKObjectType', title: string, id: string, slug: string, content_type: string, frontend_url: string } & { ' $fragmentName'?: 'CoursePageFieldsLearningContentFeedbackUkObjectTypeFragment' };
|
||||
|
||||
type CoursePageFieldsLearningContentFeedbackVvObjectTypeFragment = { __typename?: 'LearningContentFeedbackVVObjectType', title: string, id: string, slug: string, content_type: string, frontend_url: string } & { ' $fragmentName'?: 'CoursePageFieldsLearningContentFeedbackVvObjectTypeFragment' };
|
||||
|
||||
type CoursePageFieldsLearningContentKnowledgeAssessmentObjectTypeFragment = { __typename?: 'LearningContentKnowledgeAssessmentObjectType', title: string, id: string, slug: string, content_type: string, frontend_url: string } & { ' $fragmentName'?: 'CoursePageFieldsLearningContentKnowledgeAssessmentObjectTypeFragment' };
|
||||
|
||||
|
|
@ -1069,7 +1089,7 @@ type CoursePageFieldsPerformanceCriteriaObjectTypeFragment = { __typename?: 'Per
|
|||
|
||||
type CoursePageFieldsTopicObjectTypeFragment = { __typename?: 'TopicObjectType', title: string, id: string, slug: string, content_type: string, frontend_url: string } & { ' $fragmentName'?: 'CoursePageFieldsTopicObjectTypeFragment' };
|
||||
|
||||
export type CoursePageFieldsFragment = CoursePageFieldsActionCompetenceObjectTypeFragment | CoursePageFieldsAssignmentObjectTypeFragment | CoursePageFieldsCircleObjectTypeFragment | CoursePageFieldsCompetenceCertificateListObjectTypeFragment | CoursePageFieldsCompetenceCertificateObjectTypeFragment | CoursePageFieldsLearningContentAssignmentObjectTypeFragment | CoursePageFieldsLearningContentAttendanceCourseObjectTypeFragment | CoursePageFieldsLearningContentDocumentListObjectTypeFragment | CoursePageFieldsLearningContentEdoniqTestObjectTypeFragment | CoursePageFieldsLearningContentFeedbackObjectTypeFragment | CoursePageFieldsLearningContentKnowledgeAssessmentObjectTypeFragment | CoursePageFieldsLearningContentLearningModuleObjectTypeFragment | CoursePageFieldsLearningContentMediaLibraryObjectTypeFragment | CoursePageFieldsLearningContentPlaceholderObjectTypeFragment | CoursePageFieldsLearningContentRichTextObjectTypeFragment | CoursePageFieldsLearningContentVideoObjectTypeFragment | CoursePageFieldsLearningPathObjectTypeFragment | CoursePageFieldsLearningSequenceObjectTypeFragment | CoursePageFieldsLearningUnitObjectTypeFragment | CoursePageFieldsPerformanceCriteriaObjectTypeFragment | CoursePageFieldsTopicObjectTypeFragment;
|
||||
export type CoursePageFieldsFragment = CoursePageFieldsActionCompetenceObjectTypeFragment | CoursePageFieldsAssignmentObjectTypeFragment | CoursePageFieldsCircleObjectTypeFragment | CoursePageFieldsCompetenceCertificateListObjectTypeFragment | CoursePageFieldsCompetenceCertificateObjectTypeFragment | CoursePageFieldsLearningContentAssignmentObjectTypeFragment | CoursePageFieldsLearningContentAttendanceCourseObjectTypeFragment | CoursePageFieldsLearningContentDocumentListObjectTypeFragment | CoursePageFieldsLearningContentEdoniqTestObjectTypeFragment | CoursePageFieldsLearningContentFeedbackUkObjectTypeFragment | CoursePageFieldsLearningContentFeedbackVvObjectTypeFragment | CoursePageFieldsLearningContentKnowledgeAssessmentObjectTypeFragment | CoursePageFieldsLearningContentLearningModuleObjectTypeFragment | CoursePageFieldsLearningContentMediaLibraryObjectTypeFragment | CoursePageFieldsLearningContentPlaceholderObjectTypeFragment | CoursePageFieldsLearningContentRichTextObjectTypeFragment | CoursePageFieldsLearningContentVideoObjectTypeFragment | CoursePageFieldsLearningPathObjectTypeFragment | CoursePageFieldsLearningSequenceObjectTypeFragment | CoursePageFieldsLearningUnitObjectTypeFragment | CoursePageFieldsPerformanceCriteriaObjectTypeFragment | CoursePageFieldsTopicObjectTypeFragment;
|
||||
|
||||
export type AttendanceCheckQueryQueryVariables = Exact<{
|
||||
courseSessionId: Scalars['ID']['input'];
|
||||
|
|
@ -1113,8 +1133,11 @@ export type CompetenceCertificateQueryQuery = { __typename?: 'Query', competence
|
|||
{ __typename?: 'LearningContentEdoniqTestObjectType', circle?: { __typename?: 'CircleLightObjectType', id: string, title: string, slug: string } | null }
|
||||
& { ' $fragmentRefs'?: { 'CoursePageFieldsLearningContentEdoniqTestObjectTypeFragment': CoursePageFieldsLearningContentEdoniqTestObjectTypeFragment } }
|
||||
) | (
|
||||
{ __typename?: 'LearningContentFeedbackObjectType', circle?: { __typename?: 'CircleLightObjectType', id: string, title: string, slug: string } | null }
|
||||
& { ' $fragmentRefs'?: { 'CoursePageFieldsLearningContentFeedbackObjectTypeFragment': CoursePageFieldsLearningContentFeedbackObjectTypeFragment } }
|
||||
{ __typename?: 'LearningContentFeedbackUKObjectType', circle?: { __typename?: 'CircleLightObjectType', id: string, title: string, slug: string } | null }
|
||||
& { ' $fragmentRefs'?: { 'CoursePageFieldsLearningContentFeedbackUkObjectTypeFragment': CoursePageFieldsLearningContentFeedbackUkObjectTypeFragment } }
|
||||
) | (
|
||||
{ __typename?: 'LearningContentFeedbackVVObjectType', circle?: { __typename?: 'CircleLightObjectType', id: string, title: string, slug: string } | null }
|
||||
& { ' $fragmentRefs'?: { 'CoursePageFieldsLearningContentFeedbackVvObjectTypeFragment': CoursePageFieldsLearningContentFeedbackVvObjectTypeFragment } }
|
||||
) | (
|
||||
{ __typename?: 'LearningContentKnowledgeAssessmentObjectType', circle?: { __typename?: 'CircleLightObjectType', id: string, title: string, slug: string } | null }
|
||||
& { ' $fragmentRefs'?: { 'CoursePageFieldsLearningContentKnowledgeAssessmentObjectTypeFragment': CoursePageFieldsLearningContentKnowledgeAssessmentObjectTypeFragment } }
|
||||
|
|
@ -1186,8 +1209,11 @@ export type CourseQueryQuery = { __typename?: 'Query', course?: { __typename?: '
|
|||
) | null }
|
||||
& { ' $fragmentRefs'?: { 'CoursePageFieldsLearningContentEdoniqTestObjectTypeFragment': CoursePageFieldsLearningContentEdoniqTestObjectTypeFragment } }
|
||||
) | (
|
||||
{ __typename?: 'LearningContentFeedbackObjectType', can_user_self_toggle_course_completion: boolean, content_url: string, minutes?: number | null, description: string }
|
||||
& { ' $fragmentRefs'?: { 'CoursePageFieldsLearningContentFeedbackObjectTypeFragment': CoursePageFieldsLearningContentFeedbackObjectTypeFragment } }
|
||||
{ __typename?: 'LearningContentFeedbackUKObjectType', can_user_self_toggle_course_completion: boolean, content_url: string, minutes?: number | null, description: string }
|
||||
& { ' $fragmentRefs'?: { 'CoursePageFieldsLearningContentFeedbackUkObjectTypeFragment': CoursePageFieldsLearningContentFeedbackUkObjectTypeFragment } }
|
||||
) | (
|
||||
{ __typename?: 'LearningContentFeedbackVVObjectType', can_user_self_toggle_course_completion: boolean, content_url: string, minutes?: number | null, description: string }
|
||||
& { ' $fragmentRefs'?: { 'CoursePageFieldsLearningContentFeedbackVvObjectTypeFragment': CoursePageFieldsLearningContentFeedbackVvObjectTypeFragment } }
|
||||
) | (
|
||||
{ __typename?: 'LearningContentKnowledgeAssessmentObjectType', can_user_self_toggle_course_completion: boolean, content_url: string, minutes?: number | null, description: string }
|
||||
& { ' $fragmentRefs'?: { 'CoursePageFieldsLearningContentKnowledgeAssessmentObjectTypeFragment': CoursePageFieldsLearningContentKnowledgeAssessmentObjectTypeFragment } }
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ type Query {
|
|||
learning_content_media_library: LearningContentMediaLibraryObjectType
|
||||
learning_content_assignment: LearningContentAssignmentObjectType
|
||||
learning_content_attendance_course: LearningContentAttendanceCourseObjectType
|
||||
learning_content_feedback: LearningContentFeedbackObjectType
|
||||
learning_content_feedback_uk: LearningContentFeedbackUKObjectType
|
||||
learning_content_feedback_vv: LearningContentFeedbackVVObjectType
|
||||
learning_content_learning_module: LearningContentLearningModuleObjectType
|
||||
learning_content_knowledge_assessment: LearningContentKnowledgeAssessmentObjectType
|
||||
learning_content_placeholder: LearningContentPlaceholderObjectType
|
||||
|
|
@ -708,7 +709,23 @@ type LearningContentMediaLibraryObjectType implements CoursePageInterface & Lear
|
|||
circle: CircleLightObjectType
|
||||
}
|
||||
|
||||
type LearningContentFeedbackObjectType implements CoursePageInterface & LearningContentInterface {
|
||||
type LearningContentFeedbackUKObjectType implements CoursePageInterface & LearningContentInterface {
|
||||
id: ID!
|
||||
title: String!
|
||||
slug: String!
|
||||
content_type: String!
|
||||
live: Boolean!
|
||||
translation_key: String!
|
||||
frontend_url: String!
|
||||
course: CourseObjectType
|
||||
minutes: Int
|
||||
description: String!
|
||||
content_url: String!
|
||||
can_user_self_toggle_course_completion: Boolean!
|
||||
circle: CircleLightObjectType
|
||||
}
|
||||
|
||||
type LearningContentFeedbackVVObjectType implements CoursePageInterface & LearningContentInterface {
|
||||
id: ID!
|
||||
title: String!
|
||||
slug: String!
|
||||
|
|
|
|||
|
|
@ -54,7 +54,8 @@ export const LearningContentAssignmentObjectType = "LearningContentAssignmentObj
|
|||
export const LearningContentAttendanceCourseObjectType = "LearningContentAttendanceCourseObjectType";
|
||||
export const LearningContentDocumentListObjectType = "LearningContentDocumentListObjectType";
|
||||
export const LearningContentEdoniqTestObjectType = "LearningContentEdoniqTestObjectType";
|
||||
export const LearningContentFeedbackObjectType = "LearningContentFeedbackObjectType";
|
||||
export const LearningContentFeedbackUKObjectType = "LearningContentFeedbackUKObjectType";
|
||||
export const LearningContentFeedbackVVObjectType = "LearningContentFeedbackVVObjectType";
|
||||
export const LearningContentInterface = "LearningContentInterface";
|
||||
export const LearningContentKnowledgeAssessmentObjectType = "LearningContentKnowledgeAssessmentObjectType";
|
||||
export const LearningContentLearningModuleObjectType = "LearningContentLearningModuleObjectType";
|
||||
|
|
|
|||
|
|
@ -52,7 +52,8 @@ const submittables = computed(() => {
|
|||
const learningContents = circleFlatLearningContents(circle).filter(
|
||||
(lc) =>
|
||||
lc.content_type === "learnpath.LearningContentAssignment" ||
|
||||
lc.content_type === "learnpath.LearningContentFeedback" ||
|
||||
lc.content_type === "learnpath.LearningContentFeedbackUK" ||
|
||||
lc.content_type === "learnpath.LearningContentFeedbackVV" ||
|
||||
lc.content_type === "learnpath.LearningContentEdoniqTest"
|
||||
);
|
||||
|
||||
|
|
@ -72,7 +73,10 @@ const submittables = computed(() => {
|
|||
});
|
||||
|
||||
const isFeedback = (lc: LearningContent) => {
|
||||
return lc.content_type === "learnpath.LearningContentFeedback";
|
||||
return (
|
||||
lc.content_type === "learnpath.LearningContentFeedbackUK" ||
|
||||
lc.content_type === "learnpath.LearningContentFeedbackVV"
|
||||
);
|
||||
};
|
||||
|
||||
const isAssignment = (lc: LearningContent) => {
|
||||
|
|
|
|||
|
|
@ -14,12 +14,13 @@ import type { Component } from "vue";
|
|||
import { computed, onUnmounted } from "vue";
|
||||
import AssignmentBlock from "./blocks/AssignmentBlock.vue";
|
||||
import AttendanceCourseBlock from "./blocks/AttendanceCourseBlock.vue";
|
||||
import FeedbackBlock from "./feedback/FeedbackBlock.vue";
|
||||
import IframeBlock from "./blocks/IframeBlock.vue";
|
||||
import MediaLibraryBlock from "./blocks/MediaLibraryBlock.vue";
|
||||
import PlaceholderBlock from "./blocks/PlaceholderBlock.vue";
|
||||
import RichTextBlock from "./blocks/RichTextBlock.vue";
|
||||
import VideoBlock from "./blocks/VideoBlock.vue";
|
||||
import FeedbackBlockUK from "./feedback/FeedbackBlockUK.vue";
|
||||
import FeedbackBlockVV from "./feedback/FeedbackBlockVV.vue";
|
||||
import { getPreviousRoute } from "@/router/history";
|
||||
import { stringifyParse } from "@/utils/utils";
|
||||
import { useCourseDataWithCompletion } from "@/composables";
|
||||
|
|
@ -42,7 +43,8 @@ const COMPONENTS: Record<LearningContentContentType, Component> = {
|
|||
"learnpath.LearningContentAssignment": AssignmentBlock,
|
||||
"learnpath.LearningContentAttendanceCourse": AttendanceCourseBlock,
|
||||
"learnpath.LearningContentDocumentList": DocumentListBlock,
|
||||
"learnpath.LearningContentFeedback": FeedbackBlock,
|
||||
"learnpath.LearningContentFeedbackUK": FeedbackBlockUK,
|
||||
"learnpath.LearningContentFeedbackVV": FeedbackBlockVV,
|
||||
"learnpath.LearningContentLearningModule": IframeBlock,
|
||||
"learnpath.LearningContentKnowledgeAssessment": IframeBlock,
|
||||
"learnpath.LearningContentMediaLibrary": MediaLibraryBlock,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,285 @@
|
|||
<script setup lang="ts">
|
||||
import ItRadioGroup from "@/components/ui/ItRadioGroup.vue";
|
||||
import ItTextarea from "@/components/ui/ItTextarea.vue";
|
||||
import { graphql } from "@/gql";
|
||||
import FeedbackCompletition from "@/pages/learningPath/learningContentPage/feedback/FeedbackCompletition.vue";
|
||||
import {
|
||||
PERCENTAGES,
|
||||
RATINGS,
|
||||
YES_NO,
|
||||
} from "@/pages/learningPath/learningContentPage/feedback/feedback.constants";
|
||||
import LearningContentMultiLayout from "@/pages/learningPath/learningContentPage/layouts/LearningContentMultiLayout.vue";
|
||||
import type { LearningContentFeedback } from "@/types";
|
||||
import { useMutation } from "@urql/vue";
|
||||
import { useRouteQuery } from "@vueuse/router";
|
||||
import log from "loglevel";
|
||||
import { computed, onMounted, reactive, ref } from "vue";
|
||||
import { useTranslation } from "i18next-vue";
|
||||
import { useCourseSessionDetailQuery, useCurrentCourseSession } from "@/composables";
|
||||
|
||||
const props = defineProps<{
|
||||
content: LearningContentFeedback;
|
||||
}>();
|
||||
const courseSession = useCurrentCourseSession();
|
||||
const courseSessionDetailResult = useCourseSessionDetailQuery();
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const stepNo = useRouteQuery("step", "0", { transform: Number, mode: "push" });
|
||||
|
||||
const title = computed(
|
||||
() => `«${props.content.circle?.title}»: ${t("feedback.areYouSatisfied")}`
|
||||
);
|
||||
|
||||
const circleExperts = computed(() => {
|
||||
if (props.content?.circle?.slug) {
|
||||
return courseSessionDetailResult.filterCircleExperts(props.content.circle.slug);
|
||||
}
|
||||
return [];
|
||||
});
|
||||
|
||||
const stepLabels = [
|
||||
t("general.introduction"),
|
||||
t("feedback.satisfactionLabel"),
|
||||
t("feedback.goalAttainmentLabel"),
|
||||
t("feedback.proficiencyLabel"),
|
||||
t("feedback.preparationTaskClarityLabel"),
|
||||
t("feedback.instructorCompetenceLabel"),
|
||||
t("feedback.instructorRespectLabel"),
|
||||
t("feedback.instructorOpenFeedbackLabel"),
|
||||
t("feedback.recommendLabel"),
|
||||
t("feedback.coursePositiveFeedbackLabel"),
|
||||
t("feedback.courseNegativeFeedbackLabel"),
|
||||
t("general.submission"),
|
||||
];
|
||||
|
||||
const numSteps = stepLabels.length;
|
||||
|
||||
// noinspection GraphQLUnresolvedReference -> mute IntelliJ warning
|
||||
const sendFeedbackMutation = graphql(`
|
||||
mutation SendFeedbackMutation(
|
||||
$courseSessionId: ID!
|
||||
$learningContentId: ID!
|
||||
$data: GenericScalar!
|
||||
$submitted: Boolean
|
||||
) {
|
||||
send_feedback(
|
||||
course_session_id: $courseSessionId
|
||||
learning_content_page_id: $learningContentId
|
||||
data: $data
|
||||
submitted: $submitted
|
||||
) {
|
||||
feedback_response {
|
||||
id
|
||||
data
|
||||
submitted
|
||||
}
|
||||
errors {
|
||||
field
|
||||
messages
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
const feedbackSubmitted = ref(false);
|
||||
|
||||
const { executeMutation } = useMutation(sendFeedbackMutation);
|
||||
|
||||
interface FeedbackData {
|
||||
[key: string]: number | string | null;
|
||||
}
|
||||
|
||||
const feedbackData: FeedbackData = reactive({
|
||||
satisfaction: null,
|
||||
goal_attainment: null,
|
||||
proficiency: null,
|
||||
preparation_task_clarity: null,
|
||||
instructor_competence: null,
|
||||
instructor_respect: null,
|
||||
instructor_open_feedback: "",
|
||||
would_recommend: null,
|
||||
course_positive_feedback: "",
|
||||
course_negative_feedback: "",
|
||||
});
|
||||
|
||||
const questionData = [
|
||||
{
|
||||
modelKey: "satisfaction",
|
||||
items: RATINGS,
|
||||
component: ItRadioGroup,
|
||||
},
|
||||
{
|
||||
modelKey: "goal_attainment",
|
||||
items: RATINGS,
|
||||
component: ItRadioGroup,
|
||||
},
|
||||
{
|
||||
modelKey: "proficiency",
|
||||
items: PERCENTAGES,
|
||||
component: ItRadioGroup,
|
||||
},
|
||||
{
|
||||
modelKey: "preparation_task_clarity",
|
||||
items: YES_NO,
|
||||
component: ItRadioGroup,
|
||||
},
|
||||
{
|
||||
modelKey: "instructor_competence",
|
||||
items: RATINGS,
|
||||
component: ItRadioGroup,
|
||||
},
|
||||
{
|
||||
modelKey: "instructor_respect",
|
||||
items: RATINGS,
|
||||
component: ItRadioGroup,
|
||||
},
|
||||
{
|
||||
modelKey: "instructor_open_feedback",
|
||||
component: ItTextarea,
|
||||
},
|
||||
{
|
||||
modelKey: "would_recommend",
|
||||
items: YES_NO,
|
||||
component: ItRadioGroup,
|
||||
},
|
||||
{
|
||||
modelKey: "course_positive_feedback",
|
||||
component: ItTextarea,
|
||||
},
|
||||
{
|
||||
modelKey: "course_negative_feedback",
|
||||
component: ItTextarea,
|
||||
},
|
||||
];
|
||||
|
||||
const previousStep = () => {
|
||||
if (stepNo.value > 0) {
|
||||
stepNo.value -= 1;
|
||||
}
|
||||
};
|
||||
|
||||
const nextStep = () => {
|
||||
if (stepNo.value < numSteps && hasStepValidInput(stepNo.value)) {
|
||||
stepNo.value += 1;
|
||||
}
|
||||
log.debug(`next step ${stepNo.value} of ${numSteps}`);
|
||||
mutateFeedback(feedbackData);
|
||||
};
|
||||
|
||||
function hasStepValidInput(stepNumber: number) {
|
||||
const question = questionData[stepNumber - 1];
|
||||
if (question) {
|
||||
if (
|
||||
[
|
||||
"instructor_open_feedback",
|
||||
"course_negative_feedback",
|
||||
"course_positive_feedback",
|
||||
].includes(question.modelKey)
|
||||
) {
|
||||
// text response questions need to have a "truthy" value (not "" or null)
|
||||
return feedbackData[question.modelKey];
|
||||
} else {
|
||||
// other responses need to have data, can be `0` or `false`
|
||||
return feedbackData[question.modelKey] !== null;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function mutateFeedback(data: FeedbackData, submit = false) {
|
||||
log.debug("mutate feedback", feedbackData);
|
||||
return executeMutation({
|
||||
courseSessionId: courseSession.value.id,
|
||||
learningContentId: props.content.id,
|
||||
data: data,
|
||||
submitted: submit,
|
||||
})
|
||||
.then((result) => {
|
||||
log.debug("feedback mutation result", result);
|
||||
if (result.data?.send_feedback?.feedback_response?.data) {
|
||||
const responseData = result.data.send_feedback.feedback_response.data;
|
||||
if (!responseData.instructor_open_feedback) {
|
||||
responseData.instructor_open_feedback = "";
|
||||
}
|
||||
if (!responseData.course_negative_feedback) {
|
||||
responseData.course_negative_feedback = "";
|
||||
}
|
||||
if (!responseData.course_positive_feedback) {
|
||||
responseData.course_positive_feedback = "";
|
||||
}
|
||||
Object.assign(feedbackData, responseData);
|
||||
log.debug("feedback data", feedbackData);
|
||||
feedbackSubmitted.value =
|
||||
result.data?.send_feedback?.feedback_response?.submitted || false;
|
||||
}
|
||||
})
|
||||
.catch((e) => log.error(e));
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
log.debug("Feedback mounted");
|
||||
await mutateFeedback({});
|
||||
if (feedbackSubmitted.value) {
|
||||
stepNo.value = numSteps - 1;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<LearningContentMultiLayout
|
||||
:title="title"
|
||||
sub-title="Feedback"
|
||||
:learning-content="content"
|
||||
:show-start-button="stepNo === 0"
|
||||
:show-next-button="stepNo > 0 && stepNo + 1 < numSteps"
|
||||
:disable-next-button="!hasStepValidInput(stepNo)"
|
||||
:show-previous-button="stepNo > 0 && !feedbackSubmitted"
|
||||
:show-exit-button="stepNo + 1 === numSteps"
|
||||
:current-step="stepNo"
|
||||
:steps-count="numSteps"
|
||||
:start-badge-text="$t('general.introduction')"
|
||||
:end-badge-text="$t('general.submission')"
|
||||
:base-url="props.content.frontend_url"
|
||||
close-button-variant="close"
|
||||
@previous="previousStep()"
|
||||
@next="nextStep()"
|
||||
>
|
||||
<div>
|
||||
<p v-if="stepNo === 0" class="mt-10">
|
||||
{{
|
||||
$t("feedback.intro", {
|
||||
name: `${circleExperts[0]?.first_name} ${circleExperts[0]?.last_name}`,
|
||||
})
|
||||
}}
|
||||
</p>
|
||||
<p v-if="stepNo > 0 && stepNo + 1 < numSteps" class="pb-2">
|
||||
{{ stepLabels[stepNo] }}
|
||||
</p>
|
||||
<div v-for="(question, index) in questionData" :key="index">
|
||||
<!-- eslint-disable -->
|
||||
<!-- eslint does not like the dynamic v-model... -->
|
||||
<component
|
||||
:is="question.component"
|
||||
v-if="index + 1 === stepNo"
|
||||
v-model="feedbackData[question.modelKey] as any"
|
||||
:items="question['items']"
|
||||
:cy-key="question.modelKey"
|
||||
/>
|
||||
<!-- eslint-enable -->
|
||||
</div>
|
||||
<FeedbackCompletition
|
||||
v-if="stepNo === 11"
|
||||
:avatar-url="circleExperts[0].avatar_url"
|
||||
:title="
|
||||
$t('feedback.completionTitle', {
|
||||
name: `${circleExperts[0].first_name} ${circleExperts[0].last_name}`,
|
||||
})
|
||||
"
|
||||
:description="$t('feedback.completionDescription')"
|
||||
:feedback-sent="feedbackSubmitted"
|
||||
@send-feedback="mutateFeedback(feedbackData, true)"
|
||||
/>
|
||||
</div>
|
||||
</LearningContentMultiLayout>
|
||||
</template>
|
||||
|
|
@ -11,7 +11,8 @@ import type {
|
|||
LearningContentAttendanceCourseObjectType,
|
||||
LearningContentDocumentListObjectType,
|
||||
LearningContentEdoniqTestObjectType,
|
||||
LearningContentFeedbackObjectType,
|
||||
LearningContentFeedbackUkObjectType,
|
||||
LearningContentFeedbackVvObjectType,
|
||||
LearningContentKnowledgeAssessmentObjectType,
|
||||
LearningContentLearningModuleObjectType,
|
||||
LearningContentMediaLibraryObjectType,
|
||||
|
|
@ -68,8 +69,12 @@ export type LearningContentEdoniqTest = LearningContentEdoniqTestObjectType & {
|
|||
readonly content_type: "learnpath.LearningContentEdoniqTest";
|
||||
};
|
||||
|
||||
export type LearningContentFeedback = LearningContentFeedbackObjectType & {
|
||||
readonly content_type: "learnpath.LearningContentFeedback";
|
||||
export type LearningContentFeedbackVV = LearningContentFeedbackVvObjectType & {
|
||||
readonly content_type: "learnpath.LearningContentFeedbackVV";
|
||||
};
|
||||
|
||||
export type LearningContentFeedbackUK = LearningContentFeedbackUkObjectType & {
|
||||
readonly content_type: "learnpath.LearningContentFeedbackUK";
|
||||
};
|
||||
|
||||
export type LearningContentLearningModule = LearningContentLearningModuleObjectType & {
|
||||
|
|
@ -102,7 +107,8 @@ export type LearningContent =
|
|||
| LearningContentAttendanceCourse
|
||||
| LearningContentDocumentList
|
||||
| LearningContentEdoniqTest
|
||||
| LearningContentFeedback
|
||||
| LearningContentFeedbackUK
|
||||
| LearningContentFeedbackVV
|
||||
| LearningContentLearningModule
|
||||
| LearningContentKnowledgeAssessment
|
||||
| LearningContentMediaLibrary
|
||||
|
|
|
|||
|
|
@ -46,7 +46,8 @@ export function learningContentTypeData(
|
|||
return { title: t("learningContentTypes.test"), icon: "it-icon-lc-test" };
|
||||
case "learnpath.LearningContentRichText":
|
||||
return { title: t("learningContentTypes.text"), icon: "it-icon-lc-resource" };
|
||||
case "learnpath.LearningContentFeedback":
|
||||
case "learnpath.LearningContentFeedbackUK":
|
||||
case "learnpath.LearningContentFeedbackVV":
|
||||
return { title: t("learningContentTypes.feedback"), icon: "it-icon-lc-feedback" };
|
||||
case "learnpath.LearningContentPlaceholder":
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ from vbv_lernwelt.learnpath.graphql.types import (
|
|||
LearningContentAttendanceCourseObjectType,
|
||||
LearningContentDocumentListObjectType,
|
||||
LearningContentEdoniqTestObjectType,
|
||||
LearningContentFeedbackObjectType,
|
||||
LearningContentFeedbackUKObjectType,
|
||||
LearningContentFeedbackVVObjectType,
|
||||
LearningContentKnowledgeAssessmentObjectType,
|
||||
LearningContentLearningModuleObjectType,
|
||||
LearningContentMediaLibraryObjectType,
|
||||
|
|
@ -50,7 +51,8 @@ class CourseQuery(graphene.ObjectType):
|
|||
learning_content_attendance_course = graphene.Field(
|
||||
LearningContentAttendanceCourseObjectType
|
||||
)
|
||||
learning_content_feedback = graphene.Field(LearningContentFeedbackObjectType)
|
||||
learning_content_feedback_uk = graphene.Field(LearningContentFeedbackUKObjectType)
|
||||
learning_content_feedback_vv = graphene.Field(LearningContentFeedbackVVObjectType)
|
||||
learning_content_learning_module = graphene.Field(
|
||||
LearningContentLearningModuleObjectType
|
||||
)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ from vbv_lernwelt.learnpath.models import (
|
|||
LearningContentDocumentList,
|
||||
LearningContentEdoniqTest,
|
||||
LearningContentFeedback,
|
||||
LearningContentFeedbackVV,
|
||||
LearningContentKnowledgeAssessment,
|
||||
LearningContentLearningModule,
|
||||
LearningContentMediaLibrary,
|
||||
|
|
@ -50,7 +51,9 @@ class LearningContentInterface(CoursePageInterface):
|
|||
elif isinstance(instance, LearningContentAttendanceCourse):
|
||||
return LearningContentAttendanceCourseObjectType
|
||||
elif isinstance(instance, LearningContentFeedback):
|
||||
return LearningContentFeedbackObjectType
|
||||
return LearningContentFeedbackUKObjectType
|
||||
elif isinstance(instance, LearningContentFeedbackVV):
|
||||
return LearningContentFeedbackVVObjectType
|
||||
elif isinstance(instance, LearningContentLearningModule):
|
||||
return LearningContentLearningModuleObjectType
|
||||
elif isinstance(instance, LearningContentKnowledgeAssessment):
|
||||
|
|
@ -105,7 +108,7 @@ class LearningContentPlaceholderObjectType(DjangoObjectType):
|
|||
fields = []
|
||||
|
||||
|
||||
class LearningContentFeedbackObjectType(DjangoObjectType):
|
||||
class LearningContentFeedbackUKObjectType(DjangoObjectType):
|
||||
class Meta:
|
||||
model = LearningContentFeedback
|
||||
interfaces = (
|
||||
|
|
@ -115,6 +118,16 @@ class LearningContentFeedbackObjectType(DjangoObjectType):
|
|||
fields = []
|
||||
|
||||
|
||||
class LearningContentFeedbackVVObjectType(DjangoObjectType):
|
||||
class Meta:
|
||||
model = LearningContentFeedbackVV
|
||||
interfaces = (
|
||||
CoursePageInterface,
|
||||
LearningContentInterface,
|
||||
)
|
||||
fields = []
|
||||
|
||||
|
||||
class LearningContentLearningModuleObjectType(DjangoObjectType):
|
||||
class Meta:
|
||||
model = LearningContentLearningModule
|
||||
|
|
|
|||
|
|
@ -0,0 +1,87 @@
|
|||
# Generated by Django 3.2.20 on 2023-11-29 07:27
|
||||
|
||||
import django.db.models.deletion
|
||||
import wagtail.fields
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("wagtailcore", "0089_log_entry_data_json_null_to_object"),
|
||||
("learnpath", "0011_learningcontentknowledgeassessment"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="LearningContentFeedbackUK",
|
||||
fields=[
|
||||
(
|
||||
"page_ptr",
|
||||
models.OneToOneField(
|
||||
auto_created=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
parent_link=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
to="wagtailcore.page",
|
||||
),
|
||||
),
|
||||
("minutes", models.PositiveIntegerField(default=15)),
|
||||
("description", wagtail.fields.RichTextField(blank=True)),
|
||||
("content_url", models.TextField(blank=True)),
|
||||
("has_course_completion_status", models.BooleanField(default=True)),
|
||||
(
|
||||
"can_user_self_toggle_course_completion",
|
||||
models.BooleanField(default=False),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"abstract": False,
|
||||
},
|
||||
bases=("wagtailcore.page",),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="LearningContentFeedbackVV",
|
||||
fields=[
|
||||
(
|
||||
"page_ptr",
|
||||
models.OneToOneField(
|
||||
auto_created=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
parent_link=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
to="wagtailcore.page",
|
||||
),
|
||||
),
|
||||
("minutes", models.PositiveIntegerField(default=15)),
|
||||
("description", wagtail.fields.RichTextField(blank=True)),
|
||||
("content_url", models.TextField(blank=True)),
|
||||
("has_course_completion_status", models.BooleanField(default=True)),
|
||||
(
|
||||
"can_user_self_toggle_course_completion",
|
||||
models.BooleanField(default=False),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"abstract": False,
|
||||
},
|
||||
bases=("wagtailcore.page",),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="learningcontentassignment",
|
||||
name="assignment_type",
|
||||
field=models.CharField(
|
||||
choices=[
|
||||
("VOLUNTARY_CASEWORK", "VOLUNTARY_CASEWORK"),
|
||||
("MANDATORY_CASEWORK", "MANDATORY_CASEWORK"),
|
||||
("PREP_ASSIGNMENT", "PREP_ASSIGNMENT"),
|
||||
("REFLECTION", "REFLECTION"),
|
||||
("CONDITION_ACCEPTANCE", "CONDITION_ACCEPTANCE"),
|
||||
("EDONIQ_TEST", "EDONIQ_TEST"),
|
||||
],
|
||||
default="MANDATORY_CASEWORK",
|
||||
max_length=50,
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
@ -72,7 +72,8 @@ class Circle(CourseBasePage):
|
|||
"learnpath.LearningUnit",
|
||||
"learnpath.LearningContentAssignment",
|
||||
"learnpath.LearningContentAttendanceCourse",
|
||||
"learnpath.LearningContentFeedback",
|
||||
"learnpath.LearningContentFeedbackUK",
|
||||
"learnpath.LearningContentFeedbackVV",
|
||||
"learnpath.LearningContentLearningModule",
|
||||
"learnpath.LearningContentKnowledgeAssessment",
|
||||
"learnpath.LearningContentMediaLibrary",
|
||||
|
|
@ -324,6 +325,18 @@ class LearningContentFeedback(LearningContent):
|
|||
can_user_self_toggle_course_completion = models.BooleanField(default=False)
|
||||
|
||||
|
||||
class LearningContentFeedbackUK(LearningContent):
|
||||
parent_page_types = ["learnpath.Circle"]
|
||||
subpage_types = []
|
||||
can_user_self_toggle_course_completion = models.BooleanField(default=False)
|
||||
|
||||
|
||||
class LearningContentFeedbackVV(LearningContent):
|
||||
parent_page_types = ["learnpath.Circle"]
|
||||
subpage_types = []
|
||||
can_user_self_toggle_course_completion = models.BooleanField(default=False)
|
||||
|
||||
|
||||
class LearningContentLearningModule(LearningContent):
|
||||
parent_page_types = ["learnpath.Circle"]
|
||||
subpage_types = []
|
||||
|
|
|
|||
Loading…
Reference in New Issue