wip: Split cockpit feedback pages
This commit is contained in:
parent
22cfa6ff23
commit
aa5077bf3c
|
|
@ -0,0 +1,86 @@
|
|||
<template>
|
||||
<main v-if="feedbackData">
|
||||
<h1 class="mb-2">{{ $t("feedback.feedbackPageTitle") }}</h1>
|
||||
<p class="mb-10">
|
||||
<span class="font-bold" data-cy="feedback-data-amount">
|
||||
{{ feedbackData.amount }}
|
||||
</span>
|
||||
{{ $t("feedback.feedbackPageInfo") }}
|
||||
</p>
|
||||
<ol v-if="feedbackData.amount > 0">
|
||||
<li
|
||||
v-for="(question, i) in orderedQuestions"
|
||||
:key="i"
|
||||
:data-cy="`question-${i + 1}`"
|
||||
>
|
||||
<RatingScale
|
||||
v-if="ratingKeys.includes(question.key)"
|
||||
class="mb-8 bg-white"
|
||||
:ratings="feedbackData.questions[question.key]"
|
||||
:title="`${$t('feedback.questionTitle')} ${i + 1}`"
|
||||
:text="question.question"
|
||||
/>
|
||||
<VerticalBarChart
|
||||
v-else-if="verticalChartKeys.includes(question.key)"
|
||||
class="mb-8 bg-white"
|
||||
:title="`${$t('feedback.questionTitle')} ${i + 1}`"
|
||||
:ratings="feedbackData.questions[question.key]"
|
||||
:text="question.question"
|
||||
:ratio="0.2"
|
||||
/>
|
||||
<OpenFeedback
|
||||
v-else-if="
|
||||
openKeys.includes(question.key) && feedbackData.questions[question.key]
|
||||
"
|
||||
class="mb-8 bg-white"
|
||||
:title="`${$t('feedback.questionTitle')} ${i + 1}`"
|
||||
:text="question.question"
|
||||
:answers="feedbackData.questions[question.key].filter((a: string) => a !== '')"
|
||||
></OpenFeedback>
|
||||
<HorizontalBarChart
|
||||
v-else-if="
|
||||
horizontalChartKeys.includes(question.key) &&
|
||||
feedbackData.questions[question.key]
|
||||
"
|
||||
class="mb-8 bg-white"
|
||||
:title="`${$t('feedback.questionTitle')} ${i}`"
|
||||
:text="question.question"
|
||||
:items="feedbackData.questions[question.key].map((a: string) => `${a}%`)"
|
||||
/>
|
||||
</li>
|
||||
</ol>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import HorizontalBarChart from "@/components/ui/HorizontalBarChart.vue";
|
||||
import OpenFeedback from "@/components/ui/OpenFeedback.vue";
|
||||
import RatingScale from "@/components/ui/RatingScale.vue";
|
||||
import VerticalBarChart from "@/components/ui/VerticalBarChart.vue";
|
||||
import type { FeedbackData } from "@/types";
|
||||
import * as log from "loglevel";
|
||||
|
||||
interface Props {
|
||||
orderedQuestions?: {
|
||||
key: string;
|
||||
question: string;
|
||||
}[];
|
||||
feedbackData: FeedbackData;
|
||||
ratingKeys?: string[];
|
||||
verticalChartKeys?: string[];
|
||||
horizontalChartKeys?: string[];
|
||||
openKeys?: string[];
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
orderedQuestions: () => [],
|
||||
ratingKeys: () => [],
|
||||
verticalChartKeys: () => [],
|
||||
horizontalChartKeys: () => [],
|
||||
openKeys: () => [],
|
||||
});
|
||||
|
||||
log.debug("FeedbackBasePage created");
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -10,78 +10,29 @@
|
|||
<span>{{ $t("general.back") }}</span>
|
||||
</router-link>
|
||||
</nav>
|
||||
<main v-if="feedbackData">
|
||||
<h1 class="mb-2">{{ $t("feedback.feedbackPageTitle") }}</h1>
|
||||
<p class="mb-10">
|
||||
<span class="font-bold" data-cy="feedback-data-amount">
|
||||
{{ feedbackData.amount }}
|
||||
</span>
|
||||
{{ $t("feedback.feedbackPageInfo") }}
|
||||
</p>
|
||||
<ol v-if="feedbackData.amount > 0">
|
||||
<li
|
||||
v-for="(question, i) in orderedQuestions"
|
||||
:key="i"
|
||||
:data-cy="`question-${i + 1}`"
|
||||
>
|
||||
<RatingScale
|
||||
v-if="ratingKeys.includes(question.key)"
|
||||
class="mb-8 bg-white"
|
||||
:ratings="feedbackData.questions[question.key]"
|
||||
:title="`${$t('feedback.questionTitle')} ${i + 1}`"
|
||||
:text="question.question"
|
||||
/>
|
||||
<VerticalBarChart
|
||||
v-else-if="verticalChartKyes.includes(question.key)"
|
||||
class="mb-8 bg-white"
|
||||
:title="`${$t('feedback.questionTitle')} ${i + 1}`"
|
||||
:ratings="feedbackData.questions[question.key]"
|
||||
:text="question.question"
|
||||
:ratio="0.2"
|
||||
/>
|
||||
<OpenFeedback
|
||||
v-else-if="
|
||||
openKeys.includes(question.key) && feedbackData.questions[question.key]
|
||||
"
|
||||
class="mb-8 bg-white"
|
||||
:title="`${$t('feedback.questionTitle')} ${i + 1}`"
|
||||
:text="question.question"
|
||||
:answers="feedbackData.questions[question.key].filter((a: string) => a !== '')"
|
||||
></OpenFeedback>
|
||||
<HorizontalBarChart
|
||||
v-else-if="
|
||||
horizontalChartKeys.includes(question.key) &&
|
||||
feedbackData.questions[question.key]
|
||||
"
|
||||
class="mb-8 bg-white"
|
||||
:title="`${$t('feedback.questionTitle')} ${i}`"
|
||||
:text="question.question"
|
||||
:items="feedbackData.questions[question.key].map((a: string) => `${a}%`)"
|
||||
/>
|
||||
</li>
|
||||
</ol>
|
||||
</main>
|
||||
<FeedbackPageVV
|
||||
v-if="feedbackData != undefined && feedbackType === 'vv'"
|
||||
:feedback-data="feedbackData"
|
||||
/>
|
||||
<FeedbackPageUK
|
||||
v-else-if="feedbackData != undefined && feedbackType === 'uk'"
|
||||
:feedback-data="feedbackData"
|
||||
/>
|
||||
<div v-else class="flex justify-center">
|
||||
<p>unknown FeedbackType</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import HorizontalBarChart from "@/components/ui/HorizontalBarChart.vue";
|
||||
import OpenFeedback from "@/components/ui/OpenFeedback.vue";
|
||||
import RatingScale from "@/components/ui/RatingScale.vue";
|
||||
import VerticalBarChart from "@/components/ui/VerticalBarChart.vue";
|
||||
import { useCurrentCourseSession } from "@/composables";
|
||||
import { itGet } from "@/fetchHelpers";
|
||||
import * as log from "loglevel";
|
||||
import { onMounted, ref } from "vue";
|
||||
import { useTranslation } from "i18next-vue";
|
||||
|
||||
interface FeedbackData {
|
||||
amount: number;
|
||||
questions: {
|
||||
[key: string]: any;
|
||||
};
|
||||
}
|
||||
import type { FeedbackData } from "@/types";
|
||||
import FeedbackPageVV from "@/pages/cockpit/FeedbackPageVV.vue";
|
||||
import FeedbackPageUK from "@/pages/cockpit/FeedbackPageUK.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
courseSlug: string;
|
||||
|
|
@ -91,72 +42,18 @@ const props = defineProps<{
|
|||
log.debug("FeedbackPage created", props.circleId);
|
||||
|
||||
const courseSession = useCurrentCourseSession();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const orderedQuestions = [
|
||||
{
|
||||
key: "satisfaction",
|
||||
question: t("feedback.satisfactionLabel"),
|
||||
},
|
||||
{
|
||||
key: "goal_attainment",
|
||||
question: t("feedback.goalAttainmentLabel"),
|
||||
},
|
||||
{
|
||||
key: "proficiency",
|
||||
question: t("feedback.proficiencyLabel"),
|
||||
},
|
||||
{
|
||||
key: "preparation_task_clarity",
|
||||
question: t("feedback.preparationTaskClarityLabel"),
|
||||
},
|
||||
{
|
||||
key: "instructor_competence",
|
||||
question: t("feedback.instructorCompetenceLabel"),
|
||||
},
|
||||
{
|
||||
key: "instructor_respect",
|
||||
question: t("feedback.instructorRespectLabel"),
|
||||
},
|
||||
{
|
||||
key: "instructor_open_feedback",
|
||||
question: t("feedback.instructorOpenFeedbackLabel"),
|
||||
},
|
||||
{
|
||||
key: "would_recommend",
|
||||
question: t("feedback.recommendLabel"),
|
||||
},
|
||||
{
|
||||
key: "course_negative_feedback",
|
||||
question: t("feedback.courseNegativeFeedbackLabel"),
|
||||
},
|
||||
{
|
||||
key: "course_positive_feedback",
|
||||
question: t("feedback.coursePositiveFeedbackLabel"),
|
||||
},
|
||||
];
|
||||
|
||||
const ratingKeys = [
|
||||
"satisfaction",
|
||||
"goal_attainment",
|
||||
"instructor_competence",
|
||||
"instructor_respect",
|
||||
];
|
||||
const verticalChartKyes = ["preparation_task_clarity", "would_recommend"];
|
||||
const horizontalChartKeys = ["proficiency"];
|
||||
const openKeys = [
|
||||
"course_negative_feedback",
|
||||
"course_positive_feedback",
|
||||
"instructor_open_feedback",
|
||||
];
|
||||
|
||||
const feedbackData = ref<FeedbackData | undefined>(undefined);
|
||||
const feedbackType = ref<"vv" | undefined>(undefined);
|
||||
|
||||
onMounted(async () => {
|
||||
log.debug("FeedbackPage mounted");
|
||||
feedbackData.value = await itGet(
|
||||
`/api/core/feedback/${courseSession.value.id}/${props.circleId}`
|
||||
);
|
||||
log.debug("FeedbackPage feedbackData", feedbackData.value);
|
||||
if (["uk", "vv"].includes(feedbackData.value?.feedbackType ?? "")) {
|
||||
feedbackType.value = feedbackData.value.feedbackType;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
<template>
|
||||
<FeedbackBasePage
|
||||
:ordered-questions="orderedQuestions"
|
||||
:feedback-data="feedbackData"
|
||||
:rating-keys="ratingKeys"
|
||||
:vertical-chart-keys="verticalChartKeys"
|
||||
:horizontal-chart-keys="horizontalChartKeys"
|
||||
:open-keys="openKeys"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import FeedbackBasePage from "@/pages/cockpit/FeedbackBasePage.vue";
|
||||
import type { FeedbackData } from "@/types";
|
||||
import * as log from "loglevel";
|
||||
import { useTranslation } from "i18next-vue";
|
||||
|
||||
const props = defineProps<{
|
||||
feedbackData: FeedbackData;
|
||||
}>();
|
||||
|
||||
log.debug("FeedbackPageUK created");
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const orderedQuestions = [
|
||||
{
|
||||
key: "satisfaction",
|
||||
question: t("feedback.satisfactionLabel"),
|
||||
},
|
||||
{
|
||||
key: "goal_attainment",
|
||||
question: t("feedback.goalAttainmentLabel"),
|
||||
},
|
||||
{
|
||||
key: "proficiency",
|
||||
question: t("feedback.proficiencyLabel"),
|
||||
},
|
||||
{
|
||||
key: "preparation_task_clarity",
|
||||
question: t("feedback.preparationTaskClarityLabel"),
|
||||
},
|
||||
{
|
||||
key: "instructor_competence",
|
||||
question: t("feedback.instructorCompetenceLabel"),
|
||||
},
|
||||
{
|
||||
key: "instructor_respect",
|
||||
question: t("feedback.instructorRespectLabel"),
|
||||
},
|
||||
{
|
||||
key: "instructor_open_feedback",
|
||||
question: t("feedback.instructorOpenFeedbackLabel"),
|
||||
},
|
||||
{
|
||||
key: "would_recommend",
|
||||
question: t("feedback.recommendLabel"),
|
||||
},
|
||||
{
|
||||
key: "course_negative_feedback",
|
||||
question: t("feedback.courseNegativeFeedbackLabel"),
|
||||
},
|
||||
{
|
||||
key: "course_positive_feedback",
|
||||
question: t("feedback.coursePositiveFeedbackLabel"),
|
||||
},
|
||||
];
|
||||
|
||||
const ratingKeys = [
|
||||
"satisfaction",
|
||||
"goal_attainment",
|
||||
"instructor_competence",
|
||||
"instructor_respect",
|
||||
];
|
||||
const verticalChartKeys = ["preparation_task_clarity", "would_recommend"];
|
||||
const horizontalChartKeys = ["proficiency"];
|
||||
const openKeys = [
|
||||
"course_negative_feedback",
|
||||
"course_positive_feedback",
|
||||
"instructor_open_feedback",
|
||||
];
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
<template>
|
||||
<FeedbackBasePage
|
||||
:ordered-questions="orderedQuestions"
|
||||
:feedback-data="feedbackData"
|
||||
:rating-keys="ratingKeys"
|
||||
:vertical-chart-keys="verticalChartKeys"
|
||||
:horizontal-chart-keys="horizontalChartKeys"
|
||||
:open-keys="openKeys"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import FeedbackBasePage from "@/pages/cockpit/FeedbackBasePage.vue";
|
||||
import type { FeedbackData } from "@/types";
|
||||
import * as log from "loglevel";
|
||||
import { useTranslation } from "i18next-vue";
|
||||
|
||||
const props = defineProps<{
|
||||
feedbackData: FeedbackData;
|
||||
}>();
|
||||
|
||||
log.debug("FeedbackPageVV created");
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const orderedQuestions = [
|
||||
{
|
||||
key: "satisfaction",
|
||||
question: t("feedback.satisfactionLabel"),
|
||||
},
|
||||
{
|
||||
key: "goal_attainment",
|
||||
question: t("feedback.goalAttainmentLabel"),
|
||||
},
|
||||
{
|
||||
key: "proficiency",
|
||||
question: t("feedback.proficiencyLabelVV"),
|
||||
},
|
||||
{
|
||||
key: "preparation_task_clarity",
|
||||
question: t("feedback.praxisAssignmentClarity"),
|
||||
},
|
||||
{
|
||||
key: "would_recommend",
|
||||
question: t("feedback.recommendLabelVV"),
|
||||
},
|
||||
{
|
||||
key: "course_negative_feedback",
|
||||
question: t("feedback.courseNegativeFeedbackLabel"),
|
||||
},
|
||||
{
|
||||
key: "course_positive_feedback",
|
||||
question: t("feedback.coursePositiveFeedbackLabel"),
|
||||
},
|
||||
];
|
||||
|
||||
const ratingKeys = ["satisfaction", "goal_attainment"];
|
||||
const verticalChartKeys = ["preparation_task_clarity", "would_recommend"];
|
||||
const horizontalChartKeys = ["proficiency"];
|
||||
const openKeys = ["course_negative_feedback", "course_positive_feedback"];
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -566,3 +566,13 @@ export type DueDate = SimpleDueDate & {
|
|||
course_session_id: string;
|
||||
circle: CircleLight | null;
|
||||
};
|
||||
|
||||
export type FeedbackType = "uk" | "vv";
|
||||
|
||||
export interface FeedbackData {
|
||||
amount: number;
|
||||
questions: {
|
||||
[key: string]: any;
|
||||
};
|
||||
feedbackType: FeedbackType;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ from vbv_lernwelt.course_session.services.attendance import AttendanceUserStatus
|
|||
from vbv_lernwelt.feedback.models import FeedbackResponse
|
||||
from vbv_lernwelt.learnpath.models import (
|
||||
LearningContentAttendanceCourse,
|
||||
LearningContentFeedbackUK, LearningContentFeedbackVV,
|
||||
LearningContentFeedbackUK,
|
||||
LearningContentFeedbackVV,
|
||||
)
|
||||
from vbv_lernwelt.notify.models import Notification
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ from vbv_lernwelt.feedback.models import FeedbackResponse
|
|||
logger = structlog.get_logger(__name__)
|
||||
|
||||
FEEDBACK_TYPES = (
|
||||
('uk', 'Feedback UK'),
|
||||
('vv', 'Feedback VV'),
|
||||
("uk", "Feedback UK"),
|
||||
("vv", "Feedback VV"),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ def get_feedback_for_circle(request, course_session_id, circle_id):
|
|||
feedback_user__in=feedback_users(course_session_id),
|
||||
).order_by("created_at")
|
||||
|
||||
# I guess this is ok for the üK case
|
||||
feedback_data = {"amount": len(feedbacks), "questions": {}, "feedbackType": None}
|
||||
|
||||
if feedback_data["amount"] == 0:
|
||||
|
|
|
|||
Loading…
Reference in New Issue