VBV-731: Bewertungen bearbeiten
This commit is contained in:
parent
cd001a1269
commit
a2b3d63d6d
|
|
@ -2,13 +2,15 @@
|
||||||
import EvaluationIntro from "@/components/assignment/evaluation/EvaluationIntro.vue";
|
import EvaluationIntro from "@/components/assignment/evaluation/EvaluationIntro.vue";
|
||||||
import EvaluationSummary from "@/components/assignment/evaluation/EvaluationSummary.vue";
|
import EvaluationSummary from "@/components/assignment/evaluation/EvaluationSummary.vue";
|
||||||
import EvaluationTask from "@/components/assignment/evaluation/EvaluationTask.vue";
|
import EvaluationTask from "@/components/assignment/evaluation/EvaluationTask.vue";
|
||||||
import { useCourseSessionDetailQuery } from "@/composables";
|
import { useCourseSessionDetailQuery, useCurrentCourseSession } from "@/composables";
|
||||||
|
import { UPSERT_ASSIGNMENT_COMPLETION_MUTATION } from "@/graphql/mutations";
|
||||||
import type {
|
import type {
|
||||||
Assignment,
|
Assignment,
|
||||||
AssignmentCompletion,
|
AssignmentCompletion,
|
||||||
AssignmentEvaluationTask,
|
AssignmentEvaluationTask,
|
||||||
CourseSessionUser,
|
CourseSessionUser,
|
||||||
} from "@/types";
|
} from "@/types";
|
||||||
|
import { useMutation } from "@urql/vue";
|
||||||
import { useRouteQuery } from "@vueuse/router";
|
import { useRouteQuery } from "@vueuse/router";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { findIndex } from "lodash";
|
import { findIndex } from "lodash";
|
||||||
|
|
@ -21,10 +23,12 @@ const props = defineProps<{
|
||||||
assignment: Assignment;
|
assignment: Assignment;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits(["close"]);
|
const emit = defineEmits(["close", "reopen"]);
|
||||||
|
|
||||||
log.debug("UserEvaluation setup");
|
log.debug("UserEvaluation setup");
|
||||||
|
|
||||||
|
const courseSession = useCurrentCourseSession();
|
||||||
|
|
||||||
// 0 = introduction, 1 - n = tasks, n+1 = submission
|
// 0 = introduction, 1 - n = tasks, n+1 = submission
|
||||||
const stepIndex = useRouteQuery("step", "0", { transform: Number, mode: "push" });
|
const stepIndex = useRouteQuery("step", "0", { transform: Number, mode: "push" });
|
||||||
|
|
||||||
|
|
@ -58,6 +62,34 @@ function editTask(task: AssignmentEvaluationTask) {
|
||||||
stepIndex.value = taskIndex + 1;
|
stepIndex.value = taskIndex + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function canReopen() {
|
||||||
|
return (
|
||||||
|
evaluationSubmitted.value &&
|
||||||
|
(props.assignment.assignment_type === "CASEWORK" ||
|
||||||
|
props.assignment.assignment_type === "PRAXIS_ASSIGNMENT")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const upsertAssignmentCompletionMutation = useMutation(
|
||||||
|
UPSERT_ASSIGNMENT_COMPLETION_MUTATION
|
||||||
|
);
|
||||||
|
|
||||||
|
async function reopen() {
|
||||||
|
log.debug("reopen");
|
||||||
|
|
||||||
|
await upsertAssignmentCompletionMutation.executeMutation({
|
||||||
|
assignmentId: props.assignment.id,
|
||||||
|
courseSessionId: courseSession.value.id,
|
||||||
|
assignmentUserId: props.assignmentUser.id,
|
||||||
|
completionStatus: "EVALUATION_IN_PROGRESS",
|
||||||
|
completionDataString: JSON.stringify({}),
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
id: props.assignmentCompletion?.id,
|
||||||
|
});
|
||||||
|
stepIndex.value = 1;
|
||||||
|
}
|
||||||
|
|
||||||
const courseSessionDetailResult = useCourseSessionDetailQuery();
|
const courseSessionDetailResult = useCourseSessionDetailQuery();
|
||||||
|
|
||||||
const assignmentDetail = computed(() => {
|
const assignmentDetail = computed(() => {
|
||||||
|
|
@ -89,11 +121,11 @@ const taskExpertDataText = computed(() => {
|
||||||
const text = computed(() => {
|
const text = computed(() => {
|
||||||
if (props.assignment.assignment_type === "CASEWORK") {
|
if (props.assignment.assignment_type === "CASEWORK") {
|
||||||
return {
|
return {
|
||||||
evaluationFinish: "a.Bewertung abschliessen",
|
evaluationFinish: "a.Schliessen",
|
||||||
};
|
};
|
||||||
} else if (props.assignment.assignment_type === "PRAXIS_ASSIGNMENT") {
|
} else if (props.assignment.assignment_type === "PRAXIS_ASSIGNMENT") {
|
||||||
return {
|
return {
|
||||||
evaluationFinish: "a.Feedback abschliessen",
|
evaluationFinish: "a.Schliessen",
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
|
|
@ -109,6 +141,16 @@ function nextButtonEnabled() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function previousButtonVisible() {
|
||||||
|
if (
|
||||||
|
stepIndex.value > numTasks.value &&
|
||||||
|
props.assignmentCompletion.completion_status === "EVALUATION_SUBMITTED"
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function finishButtonEnabled() {
|
function finishButtonEnabled() {
|
||||||
return props.assignmentCompletion.completion_status === "EVALUATION_SUBMITTED";
|
return props.assignmentCompletion.completion_status === "EVALUATION_SUBMITTED";
|
||||||
}
|
}
|
||||||
|
|
@ -150,18 +192,19 @@ function finishButtonEnabled() {
|
||||||
<nav v-if="stepIndex > 0" class="sticky bottom-0 border-t bg-gray-200 p-6">
|
<nav v-if="stepIndex > 0" class="sticky bottom-0 border-t bg-gray-200 p-6">
|
||||||
<div class="relative flex flex-row place-content-end">
|
<div class="relative flex flex-row place-content-end">
|
||||||
<button
|
<button
|
||||||
v-if="true"
|
v-if="previousButtonVisible()"
|
||||||
class="btn-secondary mr-2 flex items-center"
|
class="btn-secondary flex items-center"
|
||||||
data-cy="previous-step"
|
data-cy="previous-step"
|
||||||
@click="previousPage()"
|
@click="previousPage()"
|
||||||
>
|
>
|
||||||
<it-icon-arrow-left class="mr-2 h-6 w-6"></it-icon-arrow-left>
|
<it-icon-arrow-left class="mr-2 h-6 w-6"></it-icon-arrow-left>
|
||||||
{{ $t("general.backCapitalized") }}
|
{{ $t("general.backCapitalized") }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
v-if="stepIndex <= numTasks"
|
v-if="stepIndex <= numTasks"
|
||||||
:disabled="!nextButtonEnabled()"
|
:disabled="!nextButtonEnabled()"
|
||||||
class="btn-secondary z-10 flex items-center"
|
class="btn-secondary z-10 ml-2 flex items-center"
|
||||||
data-cy="next-step"
|
data-cy="next-step"
|
||||||
@click="nextPage()"
|
@click="nextPage()"
|
||||||
>
|
>
|
||||||
|
|
@ -170,15 +213,25 @@ function finishButtonEnabled() {
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
v-if="stepIndex > numTasks"
|
v-if="stepIndex > numTasks && canReopen()"
|
||||||
|
class="btn-secondary z-10 ml-2"
|
||||||
|
data-cy="btn-reopen"
|
||||||
|
@click="reopen()"
|
||||||
|
>
|
||||||
|
<span class="flex items-center">
|
||||||
|
{{ $t("a.Bewertung bearbeiten") }}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
v-if="stepIndex > numTasks && finishButtonEnabled()"
|
||||||
:disabled="!finishButtonEnabled()"
|
:disabled="!finishButtonEnabled()"
|
||||||
class="btn-secondary z-10"
|
class="btn-primary z-10 ml-2"
|
||||||
data-cy="next-step"
|
data-cy="btn-close"
|
||||||
@click="emit('close')"
|
@click="emit('close')"
|
||||||
>
|
>
|
||||||
<span class="flex items-center">
|
<span class="flex items-center">
|
||||||
{{ $t(text.evaluationFinish) }}
|
{{ $t(text.evaluationFinish) }}
|
||||||
<it-icon-check class="ml-2 h-6 w-6"></it-icon-check>
|
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -76,30 +76,8 @@ async function startEvaluation() {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="mb-4">
|
|
||||||
{{
|
|
||||||
$t("assignment.x hat die Ergebnisse am y um z Uhr abgegeben", {
|
|
||||||
x: props.assignmentUser.first_name + " " + props.assignmentUser.last_name,
|
|
||||||
y: dayjs(props.assignmentCompletion.submitted_at).format("DD.MM.YYYY"),
|
|
||||||
z: dayjs(props.assignmentCompletion.submitted_at).format("HH.mm"),
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h3 data-cy="title">{{ $t(text.evaluationTitle) }}</h3>
|
<h3 data-cy="title">{{ $t(text.evaluationTitle) }}</h3>
|
||||||
|
|
||||||
<p v-if="props.dueDate" class="my-4" data-cy="evaluation-duedate">
|
|
||||||
{{
|
|
||||||
$t(
|
|
||||||
"assignment.Du musst die Bewertung bis am x um y Uhr abschliessen und freigeben",
|
|
||||||
{
|
|
||||||
x: props.dueDate.format("DD.MM.YYYY"),
|
|
||||||
y: props.dueDate.format("HH.mm"),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p class="my-4" data-cy="instruction">
|
<p class="my-4" data-cy="instruction">
|
||||||
{{
|
{{
|
||||||
$t(text.evaluationInstruction, {
|
$t(text.evaluationInstruction, {
|
||||||
|
|
@ -125,6 +103,11 @@ async function startEvaluation() {
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p v-if="props.dueDate" class="my-4" data-cy="evaluation-duedate">
|
||||||
|
{{ "a.Freigabetermin Bewertung" }}: {{ props.dueDate.format("DD.MM.YYYY") }}
|
||||||
|
{{ props.dueDate.format("HH.mm") }}
|
||||||
|
</p>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
class="btn-primary text-large"
|
class="btn-primary text-large"
|
||||||
|
|
@ -148,6 +131,18 @@ async function startEvaluation() {
|
||||||
<span v-else>{{ $t(text.evaluationStart) }}</span>
|
<span v-else>{{ $t(text.evaluationStart) }}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<section class="mt-8">
|
||||||
|
<div
|
||||||
|
v-for="historyEntry in props.assignmentCompletion.additional_json_data
|
||||||
|
?.submission_history ?? []"
|
||||||
|
:key="historyEntry.timestamp"
|
||||||
|
>
|
||||||
|
{{ dayjs(historyEntry.timestamp).format("DD.MM.YYYY HH.mm") }}:
|
||||||
|
{{ $t(historyEntry.translation_key) }}
|
||||||
|
({{ historyEntry.user_display_name }})
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import ItSuccessAlert from "@/components/ui/ItSuccessAlert.vue";
|
import ItSuccessAlert from "@/components/ui/ItSuccessAlert.vue";
|
||||||
|
import ItTextarea from "@/components/ui/ItTextarea.vue";
|
||||||
import RichText from "@/components/ui/RichText.vue";
|
import RichText from "@/components/ui/RichText.vue";
|
||||||
import { useCurrentCourseSession } from "@/composables";
|
import { useCurrentCourseSession } from "@/composables";
|
||||||
import { UPSERT_ASSIGNMENT_COMPLETION_MUTATION } from "@/graphql/mutations";
|
import { UPSERT_ASSIGNMENT_COMPLETION_MUTATION } from "@/graphql/mutations";
|
||||||
|
|
@ -16,7 +17,7 @@ import type {
|
||||||
import { useMutation } from "@urql/vue";
|
import { useMutation } from "@urql/vue";
|
||||||
import dayjs, { Dayjs } from "dayjs";
|
import dayjs, { Dayjs } from "dayjs";
|
||||||
import * as log from "loglevel";
|
import * as log from "loglevel";
|
||||||
import { computed, reactive } from "vue";
|
import { computed, reactive, ref } from "vue";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
assignmentUser: CourseSessionUser;
|
assignmentUser: CourseSessionUser;
|
||||||
|
|
@ -40,6 +41,10 @@ const upsertAssignmentCompletionMutation = useMutation(
|
||||||
UPSERT_ASSIGNMENT_COMPLETION_MUTATION
|
UPSERT_ASSIGNMENT_COMPLETION_MUTATION
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const evaluationComment = ref(
|
||||||
|
props.assignmentCompletion.completion_data.expert_evaluation_comment?.text ?? ""
|
||||||
|
);
|
||||||
|
|
||||||
const text = computed(() => {
|
const text = computed(() => {
|
||||||
if (props.assignment.assignment_type === "CASEWORK") {
|
if (props.assignment.assignment_type === "CASEWORK") {
|
||||||
return {
|
return {
|
||||||
|
|
@ -77,7 +82,11 @@ async function submitEvaluation() {
|
||||||
courseSessionId: courseSession.value.id,
|
courseSessionId: courseSession.value.id,
|
||||||
assignmentUserId: props.assignmentUser.id,
|
assignmentUserId: props.assignmentUser.id,
|
||||||
completionStatus: "EVALUATION_SUBMITTED",
|
completionStatus: "EVALUATION_SUBMITTED",
|
||||||
completionDataString: JSON.stringify({}),
|
completionDataString: JSON.stringify({
|
||||||
|
expert_evaluation_comment: {
|
||||||
|
text: evaluationComment.value,
|
||||||
|
},
|
||||||
|
}),
|
||||||
evaluationPoints: userPoints.value,
|
evaluationPoints: userPoints.value,
|
||||||
// next line used for urql
|
// next line used for urql
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
|
@ -112,9 +121,48 @@ const maxPoints = computed(() => {
|
||||||
}
|
}
|
||||||
return maxAssignmentPoints(props.assignment);
|
return maxAssignmentPoints(props.assignment);
|
||||||
});
|
});
|
||||||
|
|
||||||
const userPoints = computed(() =>
|
const userPoints = computed(() =>
|
||||||
userAssignmentPoints(props.assignment, props.assignmentCompletion)
|
userAssignmentPoints(props.assignment, props.assignmentCompletion)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const userPointsWithDeduction = computed(() => {
|
||||||
|
const points = userPoints.value;
|
||||||
|
if (points && props.assignmentCompletion.evaluation_points_deducted > 0) {
|
||||||
|
return points - props.assignmentCompletion.evaluation_points_deducted;
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
});
|
||||||
|
|
||||||
|
const percentage = computed(() => {
|
||||||
|
if (props.assignmentCompletion.completion_status === "EVALUATION_SUBMITTED") {
|
||||||
|
return (
|
||||||
|
((props.assignmentCompletion?.evaluation_points_final ??
|
||||||
|
userPointsWithDeduction.value ??
|
||||||
|
0) /
|
||||||
|
(props.assignmentCompletion?.evaluation_max_points ?? 1)) *
|
||||||
|
100
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return ((userPointsWithDeduction.value ?? 0) / (maxPoints.value ?? 1)) * 100;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const showNotPassed = computed(() => {
|
||||||
|
if (props.assignment.assignment_type === "CASEWORK") {
|
||||||
|
return percentage.value < 55;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
const showPassed = computed(() => {
|
||||||
|
if (props.assignment.assignment_type === "CASEWORK") {
|
||||||
|
return percentage.value >= 55;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -136,26 +184,23 @@ const userPoints = computed(() =>
|
||||||
<section v-if="props.assignment.assignment_type === 'CASEWORK'">
|
<section v-if="props.assignment.assignment_type === 'CASEWORK'">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="heading-1 py-4" data-cy="user-points">
|
<div class="heading-1 py-4" data-cy="user-points">
|
||||||
<template
|
{{ userPointsWithDeduction }}
|
||||||
v-if="
|
|
||||||
props.assignmentCompletion.completion_status == 'EVALUATION_SUBMITTED'
|
|
||||||
"
|
|
||||||
>
|
|
||||||
{{ props.assignmentCompletion.evaluation_points_final }}
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
{{ userPoints }}
|
|
||||||
</template>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="pl-2" data-cy="total-points">
|
<div class="pl-2" data-cy="total-points">
|
||||||
{{ $t("assignment.von x Punkten", { x: maxPoints }) }}
|
{{ $t("assignment.von x Punkten", { x: maxPoints }) }}
|
||||||
({{
|
({{ percentage.toFixed(0) }}%)
|
||||||
(
|
</div>
|
||||||
((props.assignmentCompletion?.evaluation_points_final ?? 0) /
|
|
||||||
(props.assignmentCompletion?.evaluation_max_points ?? 1)) *
|
<div v-if="showNotPassed" class="ml-2">
|
||||||
100
|
<span class="my-2 rounded-md bg-error-red-200 px-2.5 py-0.5">
|
||||||
).toFixed(0)
|
{{ $t("a.Nicht Bestanden") }}
|
||||||
}}%)
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="showPassed" class="ml-2">
|
||||||
|
<span class="my-2 rounded-md bg-green-200 px-2.5 py-0.5">
|
||||||
|
{{ $t("a.Bestanden") }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -206,6 +251,11 @@ const userPoints = computed(() =>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<p v-if="props.dueDate" class="my-4" data-cy="evaluation-duedate">
|
||||||
|
{{ "a.Freigabetermin Bewertung" }}: {{ props.dueDate.format("DD.MM.YYYY") }}
|
||||||
|
{{ props.dueDate.format("HH.mm") }}
|
||||||
|
</p>
|
||||||
|
|
||||||
<p
|
<p
|
||||||
v-if="
|
v-if="
|
||||||
props.assignment.assignment_type === 'PRAXIS_ASSIGNMENT' &&
|
props.assignment.assignment_type === 'PRAXIS_ASSIGNMENT' &&
|
||||||
|
|
@ -214,18 +264,23 @@ const userPoints = computed(() =>
|
||||||
>
|
>
|
||||||
{{ $t("a.assignment.evaluationFeedbackDescriptionText") }}
|
{{ $t("a.assignment.evaluationFeedbackDescriptionText") }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<div
|
||||||
|
v-for="historyEntry in props.assignmentCompletion.additional_json_data
|
||||||
|
?.submission_history ?? []"
|
||||||
|
:key="historyEntry.timestamp"
|
||||||
|
>
|
||||||
|
{{ dayjs(historyEntry.timestamp).format("DD.MM.YYYY HH.mm") }}:
|
||||||
|
{{ $t(historyEntry.translation_key) }}
|
||||||
|
({{ historyEntry.user_display_name }})
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="props.assignmentCompletion.completion_status === 'EVALUATION_SUBMITTED'"
|
v-if="props.assignmentCompletion.completion_status !== 'EVALUATION_SUBMITTED'"
|
||||||
|
class="mt-8"
|
||||||
>
|
>
|
||||||
{{ $t("assignment.dueDateEvaluation") }}:
|
|
||||||
{{
|
|
||||||
dayjs(props.assignmentCompletion.evaluation_submitted_at).format("DD.MM.YYYY")
|
|
||||||
}}
|
|
||||||
um
|
|
||||||
{{ dayjs(props.assignmentCompletion.evaluation_submitted_at).format("HH.mm") }}
|
|
||||||
Uhr
|
|
||||||
</div>
|
|
||||||
<div v-else>
|
|
||||||
<button
|
<button
|
||||||
class="btn-primary text-large"
|
class="btn-primary text-large"
|
||||||
data-cy="submit-evaluation"
|
data-cy="submit-evaluation"
|
||||||
|
|
@ -233,6 +288,16 @@ const userPoints = computed(() =>
|
||||||
>
|
>
|
||||||
{{ $t(text.evaluationSubmit) }}
|
{{ $t(text.evaluationSubmit) }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<ItTextarea
|
||||||
|
v-model="evaluationComment"
|
||||||
|
class="mt-8"
|
||||||
|
:placeholder="`${$t('a.Kommentar erfassen')}...`"
|
||||||
|
data-cy="reason-text"
|
||||||
|
></ItTextarea>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="evaluationComment" class="mt-4">
|
||||||
|
{{ evaluationComment }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="state.showSuccessInfo" class="mt-4">
|
<div v-if="state.showSuccessInfo" class="mt-4">
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,11 @@ import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-
|
||||||
*/
|
*/
|
||||||
const documents = {
|
const documents = {
|
||||||
"\n mutation AttendanceCheckMutation(\n $attendanceCourseId: ID!\n $attendanceUserList: [AttendanceUserInputType]!\n ) {\n update_course_session_attendance_course_users(\n id: $attendanceCourseId\n attendance_user_list: $attendanceUserList\n ) {\n course_session_attendance_course {\n id\n attendance_user_list {\n user_id\n first_name\n last_name\n email\n status\n }\n }\n }\n }\n": types.AttendanceCheckMutationDocument,
|
"\n mutation AttendanceCheckMutation(\n $attendanceCourseId: ID!\n $attendanceUserList: [AttendanceUserInputType]!\n ) {\n update_course_session_attendance_course_users(\n id: $attendanceCourseId\n attendance_user_list: $attendanceUserList\n ) {\n course_session_attendance_course {\n id\n attendance_user_list {\n user_id\n first_name\n last_name\n email\n status\n }\n }\n }\n }\n": types.AttendanceCheckMutationDocument,
|
||||||
"\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationPoints: Float\n $initializeCompletion: Boolean\n $evaluationUserId: ID\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_points: $evaluationPoints\n initialize_completion: $initializeCompletion\n evaluation_user_id: $evaluationUserId\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_points\n completion_data\n task_completion_data\n }\n }\n }\n": types.UpsertAssignmentCompletionDocument,
|
"\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationPoints: Float\n $initializeCompletion: Boolean\n $evaluationUserId: ID\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_points: $evaluationPoints\n initialize_completion: $initializeCompletion\n evaluation_user_id: $evaluationUserId\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_points\n evaluation_max_points\n evaluation_points_deducted\n evaluation_points_deducted_reason\n evaluation_points_final\n completion_data\n task_completion_data\n additional_json_data\n }\n }\n }\n": types.UpsertAssignmentCompletionDocument,
|
||||||
"\n mutation UpdateCourseSessionProfile($input: CourseSessionProfileMutationInput!) {\n update_course_session_profile(input: $input) {\n clientMutationId\n result {\n __typename\n ... on UpdateCourseProfileSuccess {\n user {\n id\n chosen_profile\n }\n }\n ... on UpdateCourseProfileError {\n message\n }\n }\n }\n }\n": types.UpdateCourseSessionProfileDocument,
|
"\n mutation UpdateCourseSessionProfile($input: CourseSessionProfileMutationInput!) {\n update_course_session_profile(input: $input) {\n clientMutationId\n result {\n __typename\n ... on UpdateCourseProfileSuccess {\n user {\n id\n chosen_profile\n }\n }\n ... on UpdateCourseProfileError {\n message\n }\n }\n }\n }\n": types.UpdateCourseSessionProfileDocument,
|
||||||
"\n fragment CoursePageFields on CoursePageInterface {\n title\n id\n slug\n content_type\n frontend_url\n }\n": types.CoursePageFieldsFragmentDoc,
|
"\n fragment CoursePageFields on CoursePageInterface {\n title\n id\n slug\n content_type\n frontend_url\n }\n": types.CoursePageFieldsFragmentDoc,
|
||||||
"\n query attendanceCheckQuery($courseSessionId: ID!) {\n course_session_attendance_course(id: $courseSessionId) {\n id\n attendance_user_list {\n user_id\n status\n }\n }\n }\n": types.AttendanceCheckQueryDocument,
|
"\n query attendanceCheckQuery($courseSessionId: ID!) {\n course_session_attendance_course(id: $courseSessionId) {\n id\n attendance_user_list {\n user_id\n status\n }\n }\n }\n": types.AttendanceCheckQueryDocument,
|
||||||
"\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n needs_expert_evaluation\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n solution_sample {\n id\n url\n }\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 first_name\n last_name\n }\n assignment_user {\n avatar_url\n first_name\n last_name\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_points_deducted\n evaluation_points_deducted_reason\n evaluation_points_final\n\n evaluation_passed\n edoniq_extended_time_flag\n completion_data\n task_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 solution_sample {\n id\n url\n }\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 first_name\n last_name\n }\n assignment_user {\n avatar_url\n first_name\n last_name\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_points_deducted\n evaluation_points_deducted_reason\n evaluation_points_final\n\n evaluation_passed\n edoniq_extended_time_flag\n completion_data\n task_completion_data\n\n additional_json_data\n }\n }\n": types.AssignmentCompletionQueryDocument,
|
||||||
"\n query competenceCertificateQuery(\n $courseSlug: String!\n $courseSessionId: ID!\n $userIds: [UUID!]\n ) {\n competence_certificate_list(course_slug: $courseSlug, user_ids: $userIds) {\n ...CoursePageFields\n competence_certificates {\n ...CoursePageFields\n assignments {\n ...CoursePageFields\n assignment_type\n max_points\n competence_certificate_weight\n completions(course_session_id: $courseSessionId) {\n id\n assignment_user {\n id\n }\n completion_status\n submitted_at\n evaluation_points\n evaluation_points_deducted\n evaluation_points_final\n evaluation_max_points\n evaluation_passed\n evaluation_percent\n course_session {\n id\n title\n }\n }\n learning_content {\n ...CoursePageFields\n circle {\n id\n title\n slug\n }\n }\n }\n }\n }\n }\n": types.CompetenceCertificateQueryDocument,
|
"\n query competenceCertificateQuery(\n $courseSlug: String!\n $courseSessionId: ID!\n $userIds: [UUID!]\n ) {\n competence_certificate_list(course_slug: $courseSlug, user_ids: $userIds) {\n ...CoursePageFields\n competence_certificates {\n ...CoursePageFields\n assignments {\n ...CoursePageFields\n assignment_type\n max_points\n competence_certificate_weight\n completions(course_session_id: $courseSessionId) {\n id\n assignment_user {\n id\n }\n completion_status\n submitted_at\n evaluation_points\n evaluation_points_deducted\n evaluation_points_final\n evaluation_max_points\n evaluation_passed\n evaluation_percent\n course_session {\n id\n title\n }\n }\n learning_content {\n ...CoursePageFields\n circle {\n id\n title\n slug\n }\n }\n }\n }\n }\n }\n": types.CompetenceCertificateQueryDocument,
|
||||||
"\n query competenceCertificateForUserQuery(\n $courseSlug: String!\n $courseSessionId: ID!\n $userIds: [UUID!]!\n ) {\n competence_certificate_list(course_slug: $courseSlug, user_ids: $userIds) {\n ...CoursePageFields\n competence_certificates {\n ...CoursePageFields\n assignments {\n ...CoursePageFields\n assignment_type\n max_points\n competence_certificate_weight\n completions(course_session_id: $courseSessionId) {\n id\n completion_status\n submitted_at\n evaluation_points\n evaluation_points_final\n evaluation_points_deducted\n evaluation_max_points\n evaluation_passed\n evaluation_percent\n assignment_user {\n id\n }\n course_session {\n id\n title\n }\n }\n learning_content {\n ...CoursePageFields\n circle {\n id\n title\n slug\n }\n }\n }\n }\n }\n }\n": types.CompetenceCertificateForUserQueryDocument,
|
"\n query competenceCertificateForUserQuery(\n $courseSlug: String!\n $courseSessionId: ID!\n $userIds: [UUID!]!\n ) {\n competence_certificate_list(course_slug: $courseSlug, user_ids: $userIds) {\n ...CoursePageFields\n competence_certificates {\n ...CoursePageFields\n assignments {\n ...CoursePageFields\n assignment_type\n max_points\n competence_certificate_weight\n completions(course_session_id: $courseSessionId) {\n id\n completion_status\n submitted_at\n evaluation_points\n evaluation_points_final\n evaluation_points_deducted\n evaluation_max_points\n evaluation_passed\n evaluation_percent\n assignment_user {\n id\n }\n course_session {\n id\n title\n }\n }\n learning_content {\n ...CoursePageFields\n circle {\n id\n title\n slug\n }\n }\n }\n }\n }\n }\n": types.CompetenceCertificateForUserQueryDocument,
|
||||||
"\n query courseSessionDetail($courseSessionId: ID!) {\n course_session(id: $courseSessionId) {\n id\n title\n course {\n id\n title\n slug\n configuration {\n id\n enable_circle_documents\n enable_learning_mentor\n enable_competence_certificates\n }\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 optional_attendance\n }\n attendance_courses {\n id\n location\n trainer\n due_date {\n id\n start\n end\n }\n learning_content_id\n learning_content {\n id\n title\n circle {\n id\n title\n slug\n }\n }\n }\n assignments {\n id\n submission_deadline {\n id\n start\n }\n evaluation_deadline {\n id\n start\n }\n learning_content {\n id\n title\n content_assignment {\n id\n title\n assignment_type\n }\n }\n }\n edoniq_tests {\n id\n deadline {\n id\n start\n end\n }\n learning_content {\n id\n title\n content_assignment {\n id\n title\n assignment_type\n }\n }\n }\n }\n }\n": types.CourseSessionDetailDocument,
|
"\n query courseSessionDetail($courseSessionId: ID!) {\n course_session(id: $courseSessionId) {\n id\n title\n course {\n id\n title\n slug\n configuration {\n id\n enable_circle_documents\n enable_learning_mentor\n enable_competence_certificates\n }\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 optional_attendance\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,
|
||||||
|
|
@ -53,7 +53,7 @@ export function graphql(source: "\n mutation AttendanceCheckMutation(\n $att
|
||||||
/**
|
/**
|
||||||
* 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 mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationPoints: Float\n $initializeCompletion: Boolean\n $evaluationUserId: ID\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_points: $evaluationPoints\n initialize_completion: $initializeCompletion\n evaluation_user_id: $evaluationUserId\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_points\n completion_data\n task_completion_data\n }\n }\n }\n"): (typeof documents)["\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationPoints: Float\n $initializeCompletion: Boolean\n $evaluationUserId: ID\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_points: $evaluationPoints\n initialize_completion: $initializeCompletion\n evaluation_user_id: $evaluationUserId\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_points\n completion_data\n task_completion_data\n }\n }\n }\n"];
|
export function graphql(source: "\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationPoints: Float\n $initializeCompletion: Boolean\n $evaluationUserId: ID\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_points: $evaluationPoints\n initialize_completion: $initializeCompletion\n evaluation_user_id: $evaluationUserId\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_points\n evaluation_max_points\n evaluation_points_deducted\n evaluation_points_deducted_reason\n evaluation_points_final\n completion_data\n task_completion_data\n additional_json_data\n }\n }\n }\n"): (typeof documents)["\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationPoints: Float\n $initializeCompletion: Boolean\n $evaluationUserId: ID\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_points: $evaluationPoints\n initialize_completion: $initializeCompletion\n evaluation_user_id: $evaluationUserId\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_points\n evaluation_max_points\n evaluation_points_deducted\n evaluation_points_deducted_reason\n evaluation_points_final\n completion_data\n task_completion_data\n additional_json_data\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.
|
||||||
*/
|
*/
|
||||||
|
|
@ -69,7 +69,7 @@ export function graphql(source: "\n query attendanceCheckQuery($courseSessionId
|
||||||
/**
|
/**
|
||||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||||
*/
|
*/
|
||||||
export function graphql(source: "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n needs_expert_evaluation\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n solution_sample {\n id\n url\n }\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 first_name\n last_name\n }\n assignment_user {\n avatar_url\n first_name\n last_name\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_points_deducted\n evaluation_points_deducted_reason\n evaluation_points_final\n\n evaluation_passed\n edoniq_extended_time_flag\n completion_data\n task_completion_data\n }\n }\n"): (typeof documents)["\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n needs_expert_evaluation\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n solution_sample {\n id\n url\n }\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 first_name\n last_name\n }\n assignment_user {\n avatar_url\n first_name\n last_name\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_points_deducted\n evaluation_points_deducted_reason\n evaluation_points_final\n\n evaluation_passed\n edoniq_extended_time_flag\n completion_data\n task_completion_data\n }\n }\n"];
|
export function graphql(source: "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n needs_expert_evaluation\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n solution_sample {\n id\n url\n }\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 first_name\n last_name\n }\n assignment_user {\n avatar_url\n first_name\n last_name\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_points_deducted\n evaluation_points_deducted_reason\n evaluation_points_final\n\n evaluation_passed\n edoniq_extended_time_flag\n completion_data\n task_completion_data\n\n additional_json_data\n }\n }\n"): (typeof documents)["\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n needs_expert_evaluation\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n solution_sample {\n id\n url\n }\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 first_name\n last_name\n }\n assignment_user {\n avatar_url\n first_name\n last_name\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_points_deducted\n evaluation_points_deducted_reason\n evaluation_points_final\n\n evaluation_passed\n edoniq_extended_time_flag\n completion_data\n task_completion_data\n\n additional_json_data\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
|
|
@ -594,7 +594,7 @@ type AssignmentCompletionObjectType {
|
||||||
course_session: CourseSessionObjectType!
|
course_session: CourseSessionObjectType!
|
||||||
completion_status: AssignmentAssignmentCompletionCompletionStatusChoices!
|
completion_status: AssignmentAssignmentCompletionCompletionStatusChoices!
|
||||||
completion_data: GenericScalar
|
completion_data: GenericScalar
|
||||||
additional_json_data: JSONString!
|
additional_json_data: GenericScalar
|
||||||
task_completion_data: GenericScalar
|
task_completion_data: GenericScalar
|
||||||
learning_content_page_id: ID
|
learning_content_page_id: ID
|
||||||
evaluation_points: Float
|
evaluation_points: Float
|
||||||
|
|
@ -650,14 +650,6 @@ String, Boolean, Int, Float, List or Object.
|
||||||
"""
|
"""
|
||||||
scalar GenericScalar
|
scalar GenericScalar
|
||||||
|
|
||||||
"""
|
|
||||||
Allows use of a JSON String for input / output from the GraphQL schema.
|
|
||||||
|
|
||||||
Use of this type is *not recommended* as you lose the benefits of having a defined, static
|
|
||||||
schema (one of the key benefits of GraphQL).
|
|
||||||
"""
|
|
||||||
scalar JSONString
|
|
||||||
|
|
||||||
type ContentDocumentObjectType {
|
type ContentDocumentObjectType {
|
||||||
id: ID!
|
id: ID!
|
||||||
display_text: String!
|
display_text: String!
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,6 @@ export const GenericScalar = "GenericScalar";
|
||||||
export const ID = "ID";
|
export const ID = "ID";
|
||||||
export const Int = "Int";
|
export const Int = "Int";
|
||||||
export const JSONStreamField = "JSONStreamField";
|
export const JSONStreamField = "JSONStreamField";
|
||||||
export const JSONString = "JSONString";
|
|
||||||
export const LearningContentAssignmentObjectType = "LearningContentAssignmentObjectType";
|
export const LearningContentAssignmentObjectType = "LearningContentAssignmentObjectType";
|
||||||
export const LearningContentAttendanceCourseObjectType = "LearningContentAttendanceCourseObjectType";
|
export const LearningContentAttendanceCourseObjectType = "LearningContentAttendanceCourseObjectType";
|
||||||
export const LearningContentDocumentListObjectType = "LearningContentDocumentListObjectType";
|
export const LearningContentDocumentListObjectType = "LearningContentDocumentListObjectType";
|
||||||
|
|
|
||||||
|
|
@ -52,8 +52,13 @@ export const UPSERT_ASSIGNMENT_COMPLETION_MUTATION = graphql(`
|
||||||
submitted_at
|
submitted_at
|
||||||
evaluation_submitted_at
|
evaluation_submitted_at
|
||||||
evaluation_points
|
evaluation_points
|
||||||
|
evaluation_max_points
|
||||||
|
evaluation_points_deducted
|
||||||
|
evaluation_points_deducted_reason
|
||||||
|
evaluation_points_final
|
||||||
completion_data
|
completion_data
|
||||||
task_completion_data
|
task_completion_data
|
||||||
|
additional_json_data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,8 @@ export const ASSIGNMENT_COMPLETION_QUERY = graphql(`
|
||||||
edoniq_extended_time_flag
|
edoniq_extended_time_flag
|
||||||
completion_data
|
completion_data
|
||||||
task_completion_data
|
task_completion_data
|
||||||
|
|
||||||
|
additional_json_data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ describe("praxisauftrag.cy.js", () => {
|
||||||
cy.get('[data-cy="next-step"]').click();
|
cy.get('[data-cy="next-step"]').click();
|
||||||
|
|
||||||
cy.get('[data-cy="submit-evaluation"]').click();
|
cy.get('[data-cy="submit-evaluation"]').click();
|
||||||
cy.get('[data-cy="next-step"]').click();
|
cy.get('[data-cy="btn-close"]').click();
|
||||||
|
|
||||||
cy.visit("/");
|
cy.visit("/");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ DATABASES = {
|
||||||
default="postgres://postgres@localhost:5432/vbv_lernwelt",
|
default="postgres://postgres@localhost:5432/vbv_lernwelt",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
DATABASES["default"]["ATOMIC_REQUESTS"] = env.bool(
|
DATABASES["default"]["ATOMIC_REQUESTS"] = env.bool(
|
||||||
"DATABASE_ATOMIC_REQUESTS", default=True
|
"DATABASE_ATOMIC_REQUESTS", default=True
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.db.models import JSONField
|
from django.db.models import JSONField
|
||||||
|
|
||||||
from vbv_lernwelt.assignment.models import AssignmentCompletion
|
from vbv_lernwelt.assignment.models import (
|
||||||
|
AssignmentCompletion,
|
||||||
|
AssignmentCompletionAuditLog,
|
||||||
|
)
|
||||||
|
from vbv_lernwelt.core.admin import LogAdmin
|
||||||
from vbv_lernwelt.core.admin_utils import PrettyJSONWidget
|
from vbv_lernwelt.core.admin_utils import PrettyJSONWidget
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -16,6 +20,7 @@ class AssignmentCompletionAdmin(admin.ModelAdmin):
|
||||||
"assignment",
|
"assignment",
|
||||||
"get_circle",
|
"get_circle",
|
||||||
"assignment_user",
|
"assignment_user",
|
||||||
|
"evaluation_user",
|
||||||
"course_session",
|
"course_session",
|
||||||
"completion_status",
|
"completion_status",
|
||||||
"evaluation_points",
|
"evaluation_points",
|
||||||
|
|
@ -27,7 +32,14 @@ class AssignmentCompletionAdmin(admin.ModelAdmin):
|
||||||
"course_session__course",
|
"course_session__course",
|
||||||
"course_session",
|
"course_session",
|
||||||
]
|
]
|
||||||
search_fields = ["assignment_user__email"]
|
search_fields = [
|
||||||
|
"assignment_user__email",
|
||||||
|
"assignment_user__first_name",
|
||||||
|
"assignment_user__last_name",
|
||||||
|
"evaluation_user__email",
|
||||||
|
"evaluation_user__first_name",
|
||||||
|
"evaluation_user__last_name",
|
||||||
|
]
|
||||||
readonly_fields = [
|
readonly_fields = [
|
||||||
"assignment_user",
|
"assignment_user",
|
||||||
"assignment",
|
"assignment",
|
||||||
|
|
@ -53,3 +65,40 @@ class AssignmentCompletionAdmin(admin.ModelAdmin):
|
||||||
if change and "evaluation_points_deducted" in form.changed_data:
|
if change and "evaluation_points_deducted" in form.changed_data:
|
||||||
obj.evaluation_points_deducted_user = request.user
|
obj.evaluation_points_deducted_user = request.user
|
||||||
super().save_model(request, obj, form, change)
|
super().save_model(request, obj, form, change)
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(AssignmentCompletionAuditLog)
|
||||||
|
class AssignmentCompletionAuditLogAdmin(LogAdmin):
|
||||||
|
date_hierarchy = "created_at"
|
||||||
|
list_display = [
|
||||||
|
"created_at",
|
||||||
|
"assignment",
|
||||||
|
"get_circle",
|
||||||
|
"assignment_user",
|
||||||
|
"evaluation_user",
|
||||||
|
"course_session",
|
||||||
|
"completion_status",
|
||||||
|
"evaluation_points",
|
||||||
|
]
|
||||||
|
list_filter = [
|
||||||
|
"completion_status",
|
||||||
|
"assignment__assignment_type",
|
||||||
|
"course_session__course",
|
||||||
|
"course_session",
|
||||||
|
]
|
||||||
|
search_fields = [
|
||||||
|
"assignment_user__email",
|
||||||
|
"assignment_user__first_name",
|
||||||
|
"assignment_user__last_name",
|
||||||
|
"evaluation_user__email",
|
||||||
|
"evaluation_user__first_name",
|
||||||
|
"evaluation_user__last_name",
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_circle(self, obj):
|
||||||
|
try:
|
||||||
|
return obj.learning_content_page.specific.get_circle().title
|
||||||
|
except Exception:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
get_circle.short_description = "Circle"
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ class AssignmentCompletionObjectType(DjangoObjectType):
|
||||||
completion_data = GenericScalar()
|
completion_data = GenericScalar()
|
||||||
task_completion_data = GenericScalar()
|
task_completion_data = GenericScalar()
|
||||||
learning_content_page_id = graphene.ID(source="learning_content_page_id")
|
learning_content_page_id = graphene.ID(source="learning_content_page_id")
|
||||||
|
additional_json_data = GenericScalar()
|
||||||
|
|
||||||
# rounded to sensible representation
|
# rounded to sensible representation
|
||||||
evaluation_points = graphene.Float()
|
evaluation_points = graphene.Float()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
import djclick as click
|
||||||
|
import structlog
|
||||||
|
|
||||||
|
from vbv_lernwelt.assignment.models import AssignmentCompletion
|
||||||
|
|
||||||
|
logger = structlog.get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def create_initial_submission_history(apps=None, schema_editor=None):
|
||||||
|
if apps is None:
|
||||||
|
# pylint: disable=import-outside-toplevel
|
||||||
|
from vbv_lernwelt.assignment.models import AssignmentCompletion
|
||||||
|
else:
|
||||||
|
AssignmentCompletion = apps.get_model("assignment", "AssignmentCompletion")
|
||||||
|
|
||||||
|
for ac in AssignmentCompletion.objects.filter(
|
||||||
|
assignment__assignment_type__in=["PRAXIS_ASSIGNMENT", "CASEWORK"]
|
||||||
|
):
|
||||||
|
num_entries = ac_create_initial_submission_history(ac)
|
||||||
|
# print(f"Created initial submission history for {ac} {num_entries}")
|
||||||
|
|
||||||
|
|
||||||
|
def ac_create_initial_submission_history(ac: AssignmentCompletion):
|
||||||
|
submission_history = ac.additional_json_data.get("submission_history", [])
|
||||||
|
|
||||||
|
num_entries = 0
|
||||||
|
|
||||||
|
if len(submission_history) > 0:
|
||||||
|
return num_entries
|
||||||
|
|
||||||
|
if ac.submitted_at:
|
||||||
|
entry = {
|
||||||
|
"timestamp": ac.submitted_at.isoformat(),
|
||||||
|
"status": "SUBMITTED",
|
||||||
|
"translation_key": "a.Ergebnisse abgegeben",
|
||||||
|
"user_id": str(ac.assignment_user.id),
|
||||||
|
"user_email": ac.assignment_user.email,
|
||||||
|
"user_display_name": (
|
||||||
|
f"{ac.assignment_user.first_name} {ac.assignment_user.last_name}"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
submission_history.append(entry)
|
||||||
|
num_entries += 1
|
||||||
|
|
||||||
|
if ac.evaluation_submitted_at:
|
||||||
|
translation_key = "a.Bewertung freigegeben"
|
||||||
|
if ac.assignment.assignment_type == "PRAXIS_ASSIGNMENT":
|
||||||
|
translation_key = "Feedback freigegeben"
|
||||||
|
|
||||||
|
entry = {
|
||||||
|
"timestamp": ac.evaluation_submitted_at.isoformat(),
|
||||||
|
"status": "EVALUATION_SUBMITTED",
|
||||||
|
"translation_key": translation_key,
|
||||||
|
"user_id": str(ac.evaluation_user.id),
|
||||||
|
"user_email": ac.evaluation_user.email,
|
||||||
|
"user_display_name": (
|
||||||
|
f"{ac.evaluation_user.first_name} {ac.evaluation_user.last_name}"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
submission_history.append(entry)
|
||||||
|
num_entries += 1
|
||||||
|
|
||||||
|
ac.additional_json_data["submission_history"] = submission_history
|
||||||
|
ac.save()
|
||||||
|
|
||||||
|
return num_entries
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
def command():
|
||||||
|
create_initial_submission_history()
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
# Generated by Django 4.2.13 on 2024-09-16 12:00
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
("assignment", "0014_evaluation_points_deducted"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="assignmentcompletionauditlog",
|
||||||
|
name="evaluation_points_deducted",
|
||||||
|
field=models.FloatField(default=0.0, verbose_name="Punkteabzug"),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="assignmentcompletionauditlog",
|
||||||
|
name="evaluation_points_deducted_reason",
|
||||||
|
field=models.TextField(
|
||||||
|
blank=True, default="", verbose_name="Punkteabzug Begründung"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="assignmentcompletionauditlog",
|
||||||
|
name="evaluation_points_deducted_user",
|
||||||
|
field=models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.SET_NULL,
|
||||||
|
related_name="+",
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="assignmentcompletionauditlog",
|
||||||
|
name="evaluation_points_deducted_user_email",
|
||||||
|
field=models.CharField(blank=True, default="", max_length=255),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 4.2.13 on 2024-09-17 11:37
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
from vbv_lernwelt.assignment.management.commands.assignment_create_initial_submission_history import (
|
||||||
|
create_initial_submission_history,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
(
|
||||||
|
"assignment",
|
||||||
|
"0015_assignmentcompletionauditlog_evaluation_points_deducted_and_more",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [migrations.RunPython(create_initial_submission_history)]
|
||||||
|
|
@ -485,6 +485,23 @@ class AssignmentCompletionAuditLog(models.Model):
|
||||||
evaluation_max_points = models.FloatField(null=True, blank=True)
|
evaluation_max_points = models.FloatField(null=True, blank=True)
|
||||||
evaluation_passed = models.BooleanField(null=True, blank=True)
|
evaluation_passed = models.BooleanField(null=True, blank=True)
|
||||||
|
|
||||||
|
evaluation_points_deducted = models.FloatField(
|
||||||
|
default=0.0, verbose_name="Punkteabzug"
|
||||||
|
)
|
||||||
|
evaluation_points_deducted_reason = models.TextField(
|
||||||
|
default="", blank=True, verbose_name="Punkteabzug Begründung"
|
||||||
|
)
|
||||||
|
evaluation_points_deducted_user = models.ForeignKey(
|
||||||
|
User,
|
||||||
|
on_delete=models.SET_NULL,
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
related_name="+",
|
||||||
|
)
|
||||||
|
evaluation_points_deducted_user_email = models.CharField(
|
||||||
|
max_length=255, blank=True, default=""
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def recalculate_assignment_passed(ac: AssignmentCompletion):
|
def recalculate_assignment_passed(ac: AssignmentCompletion):
|
||||||
if ac.evaluation_points_final is not None and ac.evaluation_max_points is not None:
|
if ac.evaluation_points_final is not None and ac.evaluation_max_points is not None:
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,13 @@ def update_assignment_completion(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
evaluation_reopened = False
|
||||||
|
if (
|
||||||
|
completion_status == AssignmentCompletionStatus.EVALUATION_IN_PROGRESS
|
||||||
|
and ac.completion_status == "EVALUATION_SUBMITTED"
|
||||||
|
):
|
||||||
|
evaluation_reopened = True
|
||||||
|
|
||||||
if evaluation_max_points is None:
|
if evaluation_max_points is None:
|
||||||
ac.evaluation_max_points = assignment.get_max_points()
|
ac.evaluation_max_points = assignment.get_max_points()
|
||||||
else:
|
else:
|
||||||
|
|
@ -229,9 +236,16 @@ def update_assignment_completion(
|
||||||
evaluation_points=evaluation_points,
|
evaluation_points=evaluation_points,
|
||||||
evaluation_max_points=ac.evaluation_max_points,
|
evaluation_max_points=ac.evaluation_max_points,
|
||||||
evaluation_passed=ac.evaluation_passed,
|
evaluation_passed=ac.evaluation_passed,
|
||||||
|
evaluation_points_deducted=ac.evaluation_points_deducted,
|
||||||
|
evaluation_points_deducted_reason=ac.evaluation_points_deducted_reason,
|
||||||
|
evaluation_points_deducted_user=ac.evaluation_points_deducted_user,
|
||||||
)
|
)
|
||||||
if evaluation_user:
|
if evaluation_user:
|
||||||
acl.evaluation_user_email = evaluation_user.email
|
acl.evaluation_user_email = evaluation_user.email
|
||||||
|
if ac.evaluation_points_deducted_user:
|
||||||
|
acl.evaluation_points_deducted_user_email = (
|
||||||
|
ac.evaluation_points_deducted_user.email
|
||||||
|
)
|
||||||
|
|
||||||
# copy over the question data, so that we don't lose the context
|
# copy over the question data, so that we don't lose the context
|
||||||
subtasks = assignment.get_input_tasks()
|
subtasks = assignment.get_input_tasks()
|
||||||
|
|
@ -241,23 +255,66 @@ def update_assignment_completion(
|
||||||
acl.completion_data[key].update(task_data)
|
acl.completion_data[key].update(task_data)
|
||||||
acl.save()
|
acl.save()
|
||||||
|
|
||||||
if completion_status in [
|
if (
|
||||||
|
completion_status
|
||||||
|
in [
|
||||||
AssignmentCompletionStatus.EVALUATION_SUBMITTED,
|
AssignmentCompletionStatus.EVALUATION_SUBMITTED,
|
||||||
AssignmentCompletionStatus.EVALUATION_IN_PROGRESS,
|
|
||||||
AssignmentCompletionStatus.SUBMITTED,
|
AssignmentCompletionStatus.SUBMITTED,
|
||||||
]:
|
]
|
||||||
learning_content = (
|
or evaluation_reopened
|
||||||
learning_content_page
|
) and assignment.assignment_type != AssignmentType.EDONIQ_TEST.value:
|
||||||
if learning_content_page
|
# make history entry
|
||||||
else assignment.find_attached_learning_content()
|
submission_history = ac.additional_json_data.get("submission_history", [])
|
||||||
|
entry = {
|
||||||
|
"timestamp": timezone.now().isoformat(),
|
||||||
|
"status": completion_status.value,
|
||||||
|
}
|
||||||
|
|
||||||
|
if completion_status == AssignmentCompletionStatus.SUBMITTED:
|
||||||
|
entry["translation_key"] = "a.Ergebnisse abgegeben"
|
||||||
|
entry["user_id"] = str(assignment_user.id)
|
||||||
|
entry["user_email"] = assignment_user.email
|
||||||
|
entry["user_display_name"] = (
|
||||||
|
f"{assignment_user.first_name} {assignment_user.last_name}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
entry["user_id"] = str(evaluation_user.id)
|
||||||
|
entry["user_email"] = evaluation_user.email
|
||||||
|
entry["user_display_name"] = (
|
||||||
|
f"{evaluation_user.first_name} {evaluation_user.last_name}"
|
||||||
|
)
|
||||||
|
if completion_status == AssignmentCompletionStatus.EVALUATION_SUBMITTED:
|
||||||
|
if assignment.assignment_type == AssignmentType.PRAXIS_ASSIGNMENT.value:
|
||||||
|
entry["translation_key"] = "a.Feedback freigegeben"
|
||||||
|
else:
|
||||||
|
entry["translation_key"] = "a.Bewertung freigegeben"
|
||||||
|
elif completion_status == AssignmentCompletionStatus.EVALUATION_IN_PROGRESS:
|
||||||
|
if assignment.assignment_type == AssignmentType.PRAXIS_ASSIGNMENT.value:
|
||||||
|
entry["translation_key"] = "a.Feedback erneut bearbeitet"
|
||||||
|
else:
|
||||||
|
entry["translation_key"] = "a.Bewertung erneut bearbeitet"
|
||||||
|
|
||||||
|
submission_history.append(entry)
|
||||||
|
ac.additional_json_data["submission_history"] = submission_history
|
||||||
|
ac.save()
|
||||||
|
|
||||||
|
if completion_status in [
|
||||||
|
AssignmentCompletionStatus.EVALUATION_SUBMITTED,
|
||||||
|
AssignmentCompletionStatus.EVALUATION_IN_PROGRESS,
|
||||||
|
AssignmentCompletionStatus.SUBMITTED,
|
||||||
|
]:
|
||||||
|
learning_content = (
|
||||||
|
learning_content_page
|
||||||
|
if learning_content_page
|
||||||
|
else assignment.find_attached_learning_content()
|
||||||
|
)
|
||||||
|
if learning_content:
|
||||||
|
mark_course_completion(
|
||||||
|
user=assignment_user,
|
||||||
|
page=learning_content,
|
||||||
|
course_session=course_session,
|
||||||
|
completion_status=CourseCompletionStatus.SUCCESS.value,
|
||||||
)
|
)
|
||||||
if learning_content:
|
|
||||||
mark_course_completion(
|
|
||||||
user=assignment_user,
|
|
||||||
page=learning_content,
|
|
||||||
course_session=course_session,
|
|
||||||
completion_status=CourseCompletionStatus.SUCCESS.value,
|
|
||||||
)
|
|
||||||
|
|
||||||
return ac, created
|
return ac, created
|
||||||
|
|
||||||
|
|
@ -267,7 +324,8 @@ def _remove_unknown_entries(assignment, completion_data):
|
||||||
Removes all entries from completion_data which are not known to the assignment
|
Removes all entries from completion_data which are not known to the assignment
|
||||||
"""
|
"""
|
||||||
input_task_ids = [task["id"] for task in assignment.get_input_tasks()]
|
input_task_ids = [task["id"] for task in assignment.get_input_tasks()]
|
||||||
|
keys = set(input_task_ids) | {"expert_evaluation_comment"}
|
||||||
filtered_completion_data = {
|
filtered_completion_data = {
|
||||||
key: value for key, value in completion_data.items() if key in input_task_ids
|
key: value for key, value in completion_data.items() if key in keys
|
||||||
}
|
}
|
||||||
return filtered_completion_data
|
return filtered_completion_data
|
||||||
|
|
|
||||||
|
|
@ -190,6 +190,13 @@ class UpdateAssignmentCompletionTestCase(TestCase):
|
||||||
"test-lehrgang-assignment-überprüfen-einer-motorfahrzeugs-versicherungspolice",
|
"test-lehrgang-assignment-überprüfen-einer-motorfahrzeugs-versicherungspolice",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# will create submission_history entry
|
||||||
|
submission_history = ac.additional_json_data.get("submission_history", [])
|
||||||
|
self.assertEqual(len(submission_history), 1)
|
||||||
|
entry = submission_history[0]
|
||||||
|
self.assertEqual(entry["status"], "SUBMITTED")
|
||||||
|
self.assertEqual(entry["user_email"], "student")
|
||||||
|
|
||||||
# AssignmentCompletionAuditLog entry will remain event after deletion of foreign keys
|
# AssignmentCompletionAuditLog entry will remain event after deletion of foreign keys
|
||||||
ac.delete()
|
ac.delete()
|
||||||
self.user.delete()
|
self.user.delete()
|
||||||
|
|
@ -512,6 +519,13 @@ class UpdateAssignmentCompletionTestCase(TestCase):
|
||||||
user_input["user_data"], {"text": "Ich würde nichts weiteres empfehlen."}
|
user_input["user_data"], {"text": "Ich würde nichts weiteres empfehlen."}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# will create submission_history entry
|
||||||
|
submission_history = ac.additional_json_data.get("submission_history", [])
|
||||||
|
self.assertEqual(len(submission_history), 1)
|
||||||
|
entry = submission_history[0]
|
||||||
|
self.assertEqual(entry["status"], "EVALUATION_SUBMITTED")
|
||||||
|
self.assertEqual(entry["user_email"], "admin")
|
||||||
|
|
||||||
# will create AssignmentCompletionAuditLog entry
|
# will create AssignmentCompletionAuditLog entry
|
||||||
acl = AssignmentCompletionAuditLog.objects.get(
|
acl = AssignmentCompletionAuditLog.objects.get(
|
||||||
assignment_user=self.user,
|
assignment_user=self.user,
|
||||||
|
|
@ -553,3 +567,156 @@ class UpdateAssignmentCompletionTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertIsNone(acl.assignment_user)
|
self.assertIsNone(acl.assignment_user)
|
||||||
self.assertIsNone(acl.assignment)
|
self.assertIsNone(acl.assignment)
|
||||||
|
|
||||||
|
def test_can_reopen_evaluated_submission(self):
|
||||||
|
subtasks = self.assignment.filter_user_subtasks(
|
||||||
|
subtask_types=["user_text_input"]
|
||||||
|
)
|
||||||
|
user_text_input = find_first(
|
||||||
|
subtasks,
|
||||||
|
pred=lambda x: (value := x.get("value"))
|
||||||
|
and value.get("text", "").startswith(
|
||||||
|
"Gibt es zusätzliche Deckungen, die du der Person empfehlen würdest?"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ac = AssignmentCompletion.objects.create(
|
||||||
|
assignment_user=self.user,
|
||||||
|
assignment=self.assignment,
|
||||||
|
course_session=self.course_session,
|
||||||
|
completion_status=AssignmentCompletionStatus.SUBMITTED.value,
|
||||||
|
completion_data={
|
||||||
|
user_text_input["id"]: {
|
||||||
|
"user_data": {"text": "Ich würde nichts weiteres empfehlen."}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
evaluation_task = self.assignment.get_evaluation_tasks()[0]
|
||||||
|
|
||||||
|
update_assignment_completion(
|
||||||
|
assignment_user=self.user,
|
||||||
|
assignment=self.assignment,
|
||||||
|
course_session=self.course_session,
|
||||||
|
completion_data={
|
||||||
|
evaluation_task["id"]: {
|
||||||
|
"expert_data": {"points": 2, "text": "Gut gemacht!"}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
completion_status=AssignmentCompletionStatus.EVALUATION_IN_PROGRESS,
|
||||||
|
evaluation_user=self.trainer,
|
||||||
|
)
|
||||||
|
|
||||||
|
update_assignment_completion(
|
||||||
|
assignment_user=self.user,
|
||||||
|
assignment=self.assignment,
|
||||||
|
course_session=self.course_session,
|
||||||
|
completion_data={},
|
||||||
|
completion_status=AssignmentCompletionStatus.EVALUATION_SUBMITTED,
|
||||||
|
evaluation_user=self.trainer,
|
||||||
|
evaluation_points=16,
|
||||||
|
)
|
||||||
|
|
||||||
|
ac = AssignmentCompletion.objects.get(
|
||||||
|
assignment_user=self.user,
|
||||||
|
assignment=self.assignment,
|
||||||
|
course_session=self.course_session,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(ac.completion_status, "EVALUATION_SUBMITTED")
|
||||||
|
self.assertEqual(ac.evaluation_points, 16)
|
||||||
|
self.assertEqual(ac.evaluation_max_points, 24)
|
||||||
|
self.assertTrue(ac.evaluation_passed)
|
||||||
|
trainer_input = ac.completion_data[evaluation_task["id"]]
|
||||||
|
self.assertDictEqual(
|
||||||
|
trainer_input["expert_data"], {"points": 2, "text": "Gut gemacht!"}
|
||||||
|
)
|
||||||
|
user_input = ac.completion_data[user_text_input["id"]]
|
||||||
|
self.assertDictEqual(
|
||||||
|
user_input["user_data"], {"text": "Ich würde nichts weiteres empfehlen."}
|
||||||
|
)
|
||||||
|
|
||||||
|
update_assignment_completion(
|
||||||
|
assignment_user=self.user,
|
||||||
|
assignment=self.assignment,
|
||||||
|
course_session=self.course_session,
|
||||||
|
completion_data={},
|
||||||
|
completion_status=AssignmentCompletionStatus.EVALUATION_IN_PROGRESS,
|
||||||
|
evaluation_user=self.trainer,
|
||||||
|
)
|
||||||
|
|
||||||
|
ac = AssignmentCompletion.objects.get(
|
||||||
|
assignment_user=self.user,
|
||||||
|
assignment=self.assignment,
|
||||||
|
course_session=self.course_session,
|
||||||
|
)
|
||||||
|
self.assertEqual(ac.completion_status, "EVALUATION_IN_PROGRESS")
|
||||||
|
|
||||||
|
update_assignment_completion(
|
||||||
|
assignment_user=self.user,
|
||||||
|
assignment=self.assignment,
|
||||||
|
course_session=self.course_session,
|
||||||
|
completion_data={
|
||||||
|
evaluation_task["id"]: {
|
||||||
|
"expert_data": {
|
||||||
|
"points": 2,
|
||||||
|
"text": "Gut gemacht. Ich musste es noch einmal anschauen.",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
completion_status=AssignmentCompletionStatus.EVALUATION_IN_PROGRESS,
|
||||||
|
evaluation_user=self.trainer,
|
||||||
|
)
|
||||||
|
|
||||||
|
# will create submission_history entry
|
||||||
|
submission_history = ac.additional_json_data.get("submission_history", [])
|
||||||
|
self.assertEqual(len(submission_history), 2)
|
||||||
|
entry = submission_history[1]
|
||||||
|
self.assertEqual(entry["status"], "EVALUATION_IN_PROGRESS")
|
||||||
|
self.assertEqual(entry["user_email"], "admin")
|
||||||
|
|
||||||
|
update_assignment_completion(
|
||||||
|
assignment_user=self.user,
|
||||||
|
assignment=self.assignment,
|
||||||
|
course_session=self.course_session,
|
||||||
|
completion_data={},
|
||||||
|
completion_status=AssignmentCompletionStatus.EVALUATION_SUBMITTED,
|
||||||
|
evaluation_user=self.trainer,
|
||||||
|
evaluation_points=16,
|
||||||
|
)
|
||||||
|
|
||||||
|
ac = AssignmentCompletion.objects.get(
|
||||||
|
assignment_user=self.user,
|
||||||
|
assignment=self.assignment,
|
||||||
|
course_session=self.course_session,
|
||||||
|
)
|
||||||
|
|
||||||
|
# will create submission_history entry
|
||||||
|
submission_history = ac.additional_json_data.get("submission_history", [])
|
||||||
|
self.assertEqual(len(submission_history), 3)
|
||||||
|
entry = submission_history[2]
|
||||||
|
self.assertEqual(entry["status"], "EVALUATION_SUBMITTED")
|
||||||
|
self.assertEqual(entry["user_email"], "admin")
|
||||||
|
|
||||||
|
self.assertEqual(ac.completion_status, "EVALUATION_SUBMITTED")
|
||||||
|
self.assertEqual(ac.evaluation_points, 16)
|
||||||
|
self.assertEqual(ac.evaluation_max_points, 24)
|
||||||
|
self.assertTrue(ac.evaluation_passed)
|
||||||
|
trainer_input = ac.completion_data[evaluation_task["id"]]
|
||||||
|
self.assertDictEqual(
|
||||||
|
trainer_input["expert_data"],
|
||||||
|
{"points": 2, "text": "Gut gemacht. Ich musste es noch einmal anschauen."},
|
||||||
|
)
|
||||||
|
user_input = ac.completion_data[user_text_input["id"]]
|
||||||
|
self.assertDictEqual(
|
||||||
|
user_input["user_data"], {"text": "Ich würde nichts weiteres empfehlen."}
|
||||||
|
)
|
||||||
|
|
||||||
|
# it will have created another AssignmentCompletionAuditLog entry
|
||||||
|
acl_qs = AssignmentCompletionAuditLog.objects.filter(
|
||||||
|
assignment_user=self.user,
|
||||||
|
assignment=self.assignment,
|
||||||
|
course_session=self.course_session,
|
||||||
|
completion_status="EVALUATION_SUBMITTED",
|
||||||
|
)
|
||||||
|
self.assertEqual(acl_qs.count(), 2)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue