feat: split assigment submit
This commit is contained in:
parent
acd9c3959b
commit
1979dcd428
|
|
@ -0,0 +1,124 @@
|
|||
<script setup lang="ts">
|
||||
import ItCheckbox from "@/components/ui/ItCheckbox.vue";
|
||||
import { computed, reactive } from "vue";
|
||||
import type { CourseSessionUserObjectsType } from "@/gql/graphql";
|
||||
import dayjs from "dayjs";
|
||||
import DateEmbedding from "@/components/dueDates/DateEmbedding.vue";
|
||||
import ItButton from "@/components/ui/ItButton.vue";
|
||||
import { useMutation } from "@urql/vue";
|
||||
import { UPSERT_ASSIGNMENT_COMPLETION_MUTATION } from "@/graphql/mutations";
|
||||
import { useUserStore } from "@/stores/user";
|
||||
import { bustItGetCache } from "@/fetchHelpers";
|
||||
import eventBus from "@/utils/eventBus";
|
||||
import log from "loglevel";
|
||||
import type { Assignment } from "@/types";
|
||||
|
||||
const props = defineProps<{
|
||||
evaluationDocumentUrl: string;
|
||||
submissionDeadlineStart?: string | null;
|
||||
circleExpert?: CourseSessionUserObjectsType;
|
||||
courseSessionId: string;
|
||||
assignment: Assignment;
|
||||
learningContentId: string;
|
||||
}>();
|
||||
|
||||
const state = reactive({
|
||||
confirmInput: false,
|
||||
confirmPerson: false,
|
||||
});
|
||||
|
||||
const circleExpertName = computed(() => {
|
||||
return `${props.circleExpert?.first_name} ${props.circleExpert?.last_name}`;
|
||||
});
|
||||
|
||||
const cannotSubmit = computed(() => {
|
||||
return !state.confirmInput || !state.confirmPerson;
|
||||
});
|
||||
|
||||
const upsertAssignmentCompletionMutation = useMutation(
|
||||
UPSERT_ASSIGNMENT_COMPLETION_MUTATION
|
||||
);
|
||||
|
||||
const onSubmit = async () => {
|
||||
try {
|
||||
await upsertAssignmentCompletionMutation.executeMutation({
|
||||
assignmentId: props.assignment.id,
|
||||
courseSessionId: props.courseSessionId,
|
||||
learningContentId: props.learningContentId,
|
||||
completionDataString: JSON.stringify({}),
|
||||
completionStatus: "SUBMITTED",
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
id: props.assignmentCompletion?.id,
|
||||
});
|
||||
bustItGetCache(
|
||||
`/api/course/completion/${props.courseSessionId}/${useUserStore().id}/`
|
||||
);
|
||||
// if solution sample is available, do not close the assigment automatically
|
||||
if (!props.assignment.solution_sample) {
|
||||
eventBus.emit("finishedLearningContent", true);
|
||||
}
|
||||
} catch (error) {
|
||||
log.error("Could not submit assignment", error);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<ItCheckbox
|
||||
class="w-full border-b border-gray-400 py-10 sm:py-6"
|
||||
:checkbox-item="{
|
||||
label: $t('assignment.confirmSubmitResults'),
|
||||
value: 'value',
|
||||
checked: state.confirmInput,
|
||||
}"
|
||||
data-cy="confirm-submit-results"
|
||||
@toggle="state.confirmInput = !state.confirmInput"
|
||||
></ItCheckbox>
|
||||
<div class="w-full border-b border-gray-400">
|
||||
<ItCheckbox
|
||||
class="py-6"
|
||||
:checkbox-item="{
|
||||
label: $t('assignment.confirmSubmitPerson'),
|
||||
value: 'value',
|
||||
checked: state.confirmPerson,
|
||||
}"
|
||||
data-cy="confirm-submit-person"
|
||||
@toggle="state.confirmPerson = !state.confirmPerson"
|
||||
></ItCheckbox>
|
||||
<div v-if="circleExpert" class="flex flex-row items-center pb-6 pl-[49px]">
|
||||
<img
|
||||
alt="Notification icon"
|
||||
class="mr-2 h-[45px] min-w-[45px] rounded-full"
|
||||
:src="circleExpert.avatar_url"
|
||||
/>
|
||||
<p class="text-base font-bold">
|
||||
{{ circleExpertName }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col space-x-2 pt-6 text-base sm:flex-row">
|
||||
<p>{{ $t("assignment.assessmentDocumentDisclaimer") }}</p>
|
||||
<a :href="evaluationDocumentUrl" class="underline">
|
||||
{{ $t("assignment.showAssessmentDocument") }}
|
||||
</a>
|
||||
</div>
|
||||
<p v-if="submissionDeadlineStart" class="pt-6">
|
||||
{{ $t("assignment.dueDateSubmission") }}
|
||||
<DateEmbedding
|
||||
:single-date="dayjs(props.submissionDeadlineStart)"
|
||||
></DateEmbedding>
|
||||
</p>
|
||||
<ItButton
|
||||
class="mt-6"
|
||||
variant="blue"
|
||||
size="large"
|
||||
:disabled="cannotSubmit"
|
||||
data-cy="submit-assignment"
|
||||
@click="onSubmit"
|
||||
>
|
||||
<p>{{ $t("assignment.submitAssignment") }}</p>
|
||||
</ItButton>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
<script setup lang="ts">
|
||||
import ItButton from "@/components/ui/ItButton.vue";
|
||||
import ItCheckbox from "@/components/ui/ItCheckbox.vue";
|
||||
import { computed, ref } from "vue";
|
||||
import { bustItGetCache, useCSRFFetch } from "@/fetchHelpers";
|
||||
import { useUserStore } from "@/stores/user";
|
||||
import eventBus from "@/utils/eventBus";
|
||||
import log from "loglevel";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
import { useMutation } from "@urql/vue";
|
||||
import { UPSERT_ASSIGNMENT_COMPLETION_MUTATION } from "@/graphql/mutations";
|
||||
import type { CourseSessionUserObjectsType } from "@/gql/graphql";
|
||||
import type { Assignment } from "@/types";
|
||||
|
||||
const props = defineProps<{
|
||||
submissionDeadlineStart?: string | null;
|
||||
circleExpert?: CourseSessionUserObjectsType;
|
||||
courseSessionId: string;
|
||||
assignment: Assignment;
|
||||
learningContentId: string;
|
||||
}>();
|
||||
|
||||
const confirmPerson = ref(false);
|
||||
|
||||
const upsertAssignmentCompletionMutation = useMutation(
|
||||
UPSERT_ASSIGNMENT_COMPLETION_MUTATION
|
||||
);
|
||||
|
||||
const circleExpertName = computed(() => {
|
||||
return `${props.circleExpert?.first_name} ${props.circleExpert?.last_name}`;
|
||||
});
|
||||
|
||||
const { data: learningMentors } = useCSRFFetch(
|
||||
`/api/mentor/${props.courseSessionId}/mentors`
|
||||
).json();
|
||||
|
||||
const onSubmit = async () => {
|
||||
try {
|
||||
await upsertAssignmentCompletionMutation.executeMutation({
|
||||
assignmentId: props.assignment.id,
|
||||
courseSessionId: props.courseSessionId,
|
||||
learningContentId: props.learningContentId,
|
||||
completionDataString: JSON.stringify({}),
|
||||
completionStatus: "SUBMITTED",
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
id: props.assignmentCompletion?.id,
|
||||
});
|
||||
bustItGetCache(
|
||||
`/api/course/completion/${props.courseSessionId}/${useUserStore().id}/`
|
||||
);
|
||||
// if solution sample is available, do not close the assigment automatically
|
||||
if (!props.assignment.solution_sample) {
|
||||
eventBus.emit("finishedLearningContent", true);
|
||||
}
|
||||
} catch (error) {
|
||||
log.error("Could not submit assignment", error);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full border-b border-gray-400">
|
||||
<ItCheckbox
|
||||
class="py-6"
|
||||
:checkbox-item="{
|
||||
label: $t('a.confirmSubmitPersonPraxisAssignment'),
|
||||
value: 'value',
|
||||
checked: confirmPerson,
|
||||
}"
|
||||
data-cy="confirm-submit-person"
|
||||
@toggle="confirmPerson = !confirmPerson"
|
||||
></ItCheckbox>
|
||||
<div v-if="circleExpert" class="flex flex-row items-center pb-6 pl-[49px]">
|
||||
<img
|
||||
alt="Notification icon"
|
||||
class="mr-2 h-[45px] min-w-[45px] rounded-full"
|
||||
:src="circleExpert.avatar_url"
|
||||
/>
|
||||
<p class="text-base font-bold">
|
||||
{{ circleExpertName }}
|
||||
</p>
|
||||
</div>
|
||||
{{ learningMentors }}
|
||||
</div>
|
||||
<p v-if="props.submissionDeadlineStart" class="pt-6">
|
||||
{{ $t("assignment.dueDateSubmission") }}
|
||||
<DateEmbedding :single-date="dayjs(props.submissionDeadlineStart)"></DateEmbedding>
|
||||
</p>
|
||||
<ItButton
|
||||
class="mt-6"
|
||||
variant="blue"
|
||||
size="large"
|
||||
:disabled="!confirmPerson"
|
||||
data-cy="submit-assignment"
|
||||
@click="onSubmit"
|
||||
>
|
||||
<p>{{ $t("assignment.submitAssignment") }}</p>
|
||||
</ItButton>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
<script setup lang="ts">
|
||||
import ItButton from "@/components/ui/ItButton.vue";
|
||||
import ItCheckbox from "@/components/ui/ItCheckbox.vue";
|
||||
import { ref } from "vue";
|
||||
import { bustItGetCache } from "@/fetchHelpers";
|
||||
import { useUserStore } from "@/stores/user";
|
||||
import eventBus from "@/utils/eventBus";
|
||||
import log from "loglevel";
|
||||
import { useMutation } from "@urql/vue";
|
||||
import { UPSERT_ASSIGNMENT_COMPLETION_MUTATION } from "@/graphql/mutations";
|
||||
import type { Assignment } from "@/types";
|
||||
|
||||
const props = defineProps<{
|
||||
courseSessionId: string;
|
||||
assignment: Assignment;
|
||||
learningContentId: string;
|
||||
}>();
|
||||
|
||||
const upsertAssignmentCompletionMutation = useMutation(
|
||||
UPSERT_ASSIGNMENT_COMPLETION_MUTATION
|
||||
);
|
||||
|
||||
const confirmInput = ref(false);
|
||||
|
||||
const onSubmit = async () => {
|
||||
try {
|
||||
await upsertAssignmentCompletionMutation.executeMutation({
|
||||
assignmentId: props.assignment.id,
|
||||
courseSessionId: props.courseSessionId,
|
||||
learningContentId: props.learningContentId,
|
||||
completionDataString: JSON.stringify({}),
|
||||
completionStatus: "SUBMITTED",
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
id: props.assignmentCompletion?.id,
|
||||
});
|
||||
bustItGetCache(
|
||||
`/api/course/completion/${props.courseSessionId}/${useUserStore().id}/`
|
||||
);
|
||||
// if solution sample is available, do not close the assigment automatically
|
||||
if (!props.assignment.solution_sample) {
|
||||
eventBus.emit("finishedLearningContent", true);
|
||||
}
|
||||
} catch (error) {
|
||||
log.error("Could not submit assignment", error);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ItCheckbox
|
||||
class="w-full border-b border-gray-400 py-10 sm:py-6"
|
||||
:checkbox-item="{
|
||||
label: $t('assignment.confirmSubmitResults'),
|
||||
value: 'value',
|
||||
checked: confirmInput,
|
||||
}"
|
||||
data-cy="confirm-submit-results"
|
||||
@toggle="confirmInput = !confirmInput"
|
||||
></ItCheckbox>
|
||||
<ItButton
|
||||
class="mt-6"
|
||||
variant="blue"
|
||||
size="large"
|
||||
:disabled="!confirmInput"
|
||||
data-cy="submit-assignment"
|
||||
@click="onSubmit"
|
||||
>
|
||||
<p>{{ $t("assignment.submitAssignment") }}</p>
|
||||
</ItButton>
|
||||
</template>
|
||||
|
|
@ -1,25 +1,19 @@
|
|||
<script setup lang="ts">
|
||||
import DateEmbedding from "@/components/dueDates/DateEmbedding.vue";
|
||||
import ItButton from "@/components/ui/ItButton.vue";
|
||||
import ItCheckbox from "@/components/ui/ItCheckbox.vue";
|
||||
import ItSuccessAlert from "@/components/ui/ItSuccessAlert.vue";
|
||||
import {
|
||||
useCourseData,
|
||||
useCourseSessionDetailQuery,
|
||||
useCurrentCourseSession,
|
||||
} from "@/composables";
|
||||
import { bustItGetCache, useCSRFFetch } from "@/fetchHelpers";
|
||||
import { UPSERT_ASSIGNMENT_COMPLETION_MUTATION } from "@/graphql/mutations";
|
||||
import AssignmentSubmissionResponses from "@/pages/learningPath/learningContentPage/assignment/AssignmentSubmissionResponses.vue";
|
||||
import { useUserStore } from "@/stores/user";
|
||||
import type { Assignment, AssignmentCompletion, AssignmentTask } from "@/types";
|
||||
import { useMutation } from "@urql/vue";
|
||||
import log from "loglevel";
|
||||
import { computed, reactive } from "vue";
|
||||
import { computed } from "vue";
|
||||
import { useTranslation } from "i18next-vue";
|
||||
import eventBus from "@/utils/eventBus";
|
||||
import dayjs from "dayjs";
|
||||
import type { AssignmentAssignmentAssignmentTypeChoices } from "@/gql/graphql";
|
||||
import CaseWorkSubmit from "@/components/learningPath/assignment/CaseWorkSubmit.vue";
|
||||
import SimpleSubmit from "@/components/learningPath/assignment/SimpleSubmit.vue";
|
||||
import PraxisAssignmentSubmit from "@/components/learningPath/assignment/PraxisAssignmentSubmit.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
assignment: Assignment;
|
||||
|
|
@ -39,11 +33,6 @@ const courseData = useCourseData(courseSession.value.course.slug);
|
|||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const state = reactive({
|
||||
confirmInput: false,
|
||||
confirmPerson: false,
|
||||
});
|
||||
|
||||
const learningContent = computed(() => {
|
||||
return courseData.findLearningContent(props.learningContentId);
|
||||
});
|
||||
|
|
@ -61,10 +50,6 @@ const circleExpert = computed(() => {
|
|||
return circleExperts.value[0];
|
||||
});
|
||||
|
||||
const { data: learningMentors } = useCSRFFetch(
|
||||
`/api/mentor/${courseSession.value.id}/mentors`
|
||||
).json();
|
||||
|
||||
const circleExpertName = computed(() => {
|
||||
return `${circleExpert.value?.first_name} ${circleExpert.value?.last_name}`;
|
||||
});
|
||||
|
|
@ -81,13 +66,6 @@ const completionTaskData = computed(() => {
|
|||
return props.assignmentCompletion?.task_completion_data ?? {};
|
||||
});
|
||||
|
||||
const cannotSubmit = computed(() => {
|
||||
return (
|
||||
(!state.confirmInput && !isPraxisAssignment.value) ||
|
||||
(props.assignment.assignment_type === "CASEWORK" && !state.confirmPerson)
|
||||
);
|
||||
});
|
||||
|
||||
function checkAssignmentType(
|
||||
assignmentType: AssignmentAssignmentAssignmentTypeChoices[]
|
||||
) {
|
||||
|
|
@ -95,15 +73,8 @@ function checkAssignmentType(
|
|||
}
|
||||
|
||||
const isCasework = computed(() => checkAssignmentType(["CASEWORK"]));
|
||||
const mayBeEvaluated = computed(() =>
|
||||
checkAssignmentType(["CASEWORK", "PRAXIS_ASSIGNMENT"])
|
||||
);
|
||||
const isPraxisAssignment = computed(() => checkAssignmentType(["PRAXIS_ASSIGNMENT"]));
|
||||
|
||||
const upsertAssignmentCompletionMutation = useMutation(
|
||||
UPSERT_ASSIGNMENT_COMPLETION_MUTATION
|
||||
);
|
||||
|
||||
const onEditTask = (task: AssignmentTask) => {
|
||||
emit("editTask", task);
|
||||
};
|
||||
|
|
@ -115,30 +86,6 @@ const openSolutionSample = () => {
|
|||
window.open(url, "_blank");
|
||||
}
|
||||
};
|
||||
|
||||
const onSubmit = async () => {
|
||||
try {
|
||||
await upsertAssignmentCompletionMutation.executeMutation({
|
||||
assignmentId: props.assignment.id,
|
||||
courseSessionId: courseSession.value.id,
|
||||
learningContentId: props.learningContentId,
|
||||
completionDataString: JSON.stringify({}),
|
||||
completionStatus: "SUBMITTED",
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
id: props.assignmentCompletion?.id,
|
||||
});
|
||||
bustItGetCache(
|
||||
`/api/course/completion/${courseSession.value.id}/${useUserStore().id}/`
|
||||
);
|
||||
// if solution sample is available, do not close the assigment automatically
|
||||
if (!props.assignment.solution_sample) {
|
||||
eventBus.emit("finishedLearningContent", true);
|
||||
}
|
||||
} catch (error) {
|
||||
log.error("Could not submit assignment", error);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div class="w-full border border-gray-400 p-8" data-cy="confirm-container">
|
||||
|
|
@ -147,67 +94,31 @@ const onSubmit = async () => {
|
|||
</h3>
|
||||
|
||||
<div v-if="completionStatus === 'IN_PROGRESS'">
|
||||
<ItCheckbox
|
||||
v-if="!isPraxisAssignment"
|
||||
class="w-full border-b border-gray-400 py-10 sm:py-6"
|
||||
:checkbox-item="{
|
||||
label: $t('assignment.confirmSubmitResults'),
|
||||
value: 'value',
|
||||
checked: state.confirmInput,
|
||||
}"
|
||||
data-cy="confirm-submit-results"
|
||||
@toggle="state.confirmInput = !state.confirmInput"
|
||||
></ItCheckbox>
|
||||
<div v-if="mayBeEvaluated" class="w-full border-b border-gray-400">
|
||||
<ItCheckbox
|
||||
class="py-6"
|
||||
:checkbox-item="{
|
||||
label: isPraxisAssignment
|
||||
? $t('a.confirmSubmitPersonPraxisAssignment')
|
||||
: $t('assignment.confirmSubmitPerson'),
|
||||
value: 'value',
|
||||
checked: state.confirmPerson,
|
||||
}"
|
||||
data-cy="confirm-submit-person"
|
||||
@toggle="state.confirmPerson = !state.confirmPerson"
|
||||
></ItCheckbox>
|
||||
<div v-if="circleExpert" class="flex flex-row items-center pb-6 pl-[49px]">
|
||||
<img
|
||||
alt="Notification icon"
|
||||
class="mr-2 h-[45px] min-w-[45px] rounded-full"
|
||||
:src="circleExpert.avatar_url"
|
||||
/>
|
||||
<p class="text-base font-bold">
|
||||
{{ circleExpertName }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
{{ learningMentors }}
|
||||
</div>
|
||||
<!-- TODO: find way to find user that will do the corrections -->
|
||||
</div>
|
||||
<div v-if="isCasework" class="flex flex-col space-x-2 pt-6 text-base sm:flex-row">
|
||||
<p>{{ $t("assignment.assessmentDocumentDisclaimer") }}</p>
|
||||
<a :href="props.assignment.evaluation_document_url" class="underline">
|
||||
{{ $t("assignment.showAssessmentDocument") }}
|
||||
</a>
|
||||
</div>
|
||||
<p v-if="mayBeEvaluated && props.submissionDeadlineStart" class="pt-6">
|
||||
{{ $t("assignment.dueDateSubmission") }}
|
||||
<DateEmbedding
|
||||
:single-date="dayjs(props.submissionDeadlineStart)"
|
||||
></DateEmbedding>
|
||||
</p>
|
||||
<ItButton
|
||||
class="mt-6"
|
||||
variant="blue"
|
||||
size="large"
|
||||
:disabled="cannotSubmit"
|
||||
data-cy="submit-assignment"
|
||||
@click="onSubmit"
|
||||
>
|
||||
<p>{{ $t("assignment.submitAssignment") }}</p>
|
||||
</ItButton>
|
||||
<CaseWorkSubmit
|
||||
v-if="isCasework"
|
||||
:course-session-id="courseSessionId"
|
||||
:assignment="assignment"
|
||||
:learning-content-id="learningContentId"
|
||||
:circle-expert="circleExpert"
|
||||
:evaluation-document-url="assignment.evaluation_document_url"
|
||||
:submission-deadline-start="submissionDeadlineStart"
|
||||
/>
|
||||
|
||||
<PraxisAssignmentSubmit
|
||||
v-else-if="isPraxisAssignment"
|
||||
:course-session-id="courseSessionId"
|
||||
:assignment="assignment"
|
||||
:learning-content-id="learningContentId"
|
||||
:circle-expert="circleExpert"
|
||||
:submission-deadline-start="submissionDeadlineStart"
|
||||
/>
|
||||
|
||||
<SimpleSubmit
|
||||
v-else
|
||||
:course-session-id="courseSessionId"
|
||||
:assignment="assignment"
|
||||
:learning-content-id="learningContentId"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class="pt-6">
|
||||
<ItSuccessAlert
|
||||
|
|
@ -220,7 +131,7 @@ const onSubmit = async () => {
|
|||
}}
|
||||
</p>
|
||||
<div
|
||||
v-if="props.assignment.solution_sample"
|
||||
v-if="assignment.solution_sample"
|
||||
class="pt-2"
|
||||
data-cy="show-sample-solution"
|
||||
>
|
||||
|
|
@ -242,7 +153,7 @@ const onSubmit = async () => {
|
|||
</div>
|
||||
</div>
|
||||
<AssignmentSubmissionResponses
|
||||
:assignment="props.assignment"
|
||||
:assignment="assignment"
|
||||
:assignment-completion-data="completionData"
|
||||
:assignment-task-completion-data="completionTaskData"
|
||||
:allow-edit="completionStatus === 'IN_PROGRESS'"
|
||||
|
|
|
|||
Loading…
Reference in New Issue