feat: delete submission
This commit is contained in:
+4
-4
@@ -18,24 +18,24 @@
|
||||
onClose={() => (openDeleteModal = false)}
|
||||
bind:open={openDeleteModal}
|
||||
width="w-96"
|
||||
modalHeading={$t('course.navItem.lessons.delete_lesson.modal_heading')}
|
||||
modalHeading={$t('delete_modal.label')}
|
||||
>
|
||||
<div>
|
||||
<h1 class="dark:text-white text-lg">
|
||||
{$t('course.navItem.lessons.delete_lesson.content')} <strong>{lessonTitle}</strong>?
|
||||
{$t('delete_modal.content')} <strong>{lessonTitle}</strong>?
|
||||
</h1>
|
||||
|
||||
<div class="mt-5 flex items-center justify-between">
|
||||
<PrimaryButton
|
||||
className="px-6 py-3"
|
||||
variant={VARIANTS.OUTLINED}
|
||||
label={$t('course.navItem.lessons.delete_lesson.no')}
|
||||
label={$t('delete_modal.no')}
|
||||
onClick={() => (openDeleteModal = false)}
|
||||
/>
|
||||
<PrimaryButton
|
||||
className="px-6 py-3"
|
||||
variant={VARIANTS.OUTLINED}
|
||||
label={$t('course.navItem.lessons.delete_lesson.yes')}
|
||||
label={$t('delete_modal.yes')}
|
||||
onClick={handleDelete}
|
||||
/>
|
||||
</div>
|
||||
|
||||
+91
-34
@@ -10,14 +10,21 @@
|
||||
import { useCompletion } from 'ai/svelte';
|
||||
import { QUESTION_TYPE } from '$lib/components/Question/constants';
|
||||
import { t } from '$lib/utils/functions/translations';
|
||||
import { OverflowMenu, OverflowMenuItem } from 'carbon-components-svelte';
|
||||
import type { SubmissionIdData } from '$lib/utils/types/submission';
|
||||
|
||||
export let open = false;
|
||||
export let onClose = () => {};
|
||||
export let handleSave = () => {};
|
||||
export let handleSave = (d: SubmissionIdData) => {};
|
||||
export let isGradeWithAI = false;
|
||||
|
||||
export let data = {};
|
||||
export let updateStatus = () => {};
|
||||
export let data: SubmissionIdData;
|
||||
export let deleteSubmission = async (id: string, statusId: number) => {};
|
||||
export let updateStatus = (arg: {
|
||||
submissionId: string;
|
||||
prevStatusId: number;
|
||||
nextStatusId: number;
|
||||
total: number;
|
||||
}) => {};
|
||||
|
||||
const SELECTABLE_STATUS = [
|
||||
{
|
||||
@@ -40,6 +47,9 @@
|
||||
let isLoading = false;
|
||||
let total = 0;
|
||||
let maxPoints = 0;
|
||||
let openMenu = false;
|
||||
let openDeletePrompt = false;
|
||||
let isDeleting = false;
|
||||
|
||||
function getMaxPoints(questions) {
|
||||
return (questions || []).reduce((acc, question) => acc + question.points, 0);
|
||||
@@ -54,12 +64,13 @@
|
||||
const newSelectedId = event.detail.selectedId;
|
||||
|
||||
setStatus({
|
||||
status_id: newSelectedId
|
||||
...data,
|
||||
statusId: newSelectedId
|
||||
});
|
||||
|
||||
updateStatus({
|
||||
submissionId: data.id,
|
||||
prevStatusId: data.status_id,
|
||||
prevStatusId: data.statusId,
|
||||
nextStatusId: status.id,
|
||||
total
|
||||
});
|
||||
@@ -67,8 +78,8 @@
|
||||
snackbar.success(`${$t('snackbar.exercise.submission_updated')} '${status.text}'`);
|
||||
}
|
||||
|
||||
function setStatus(data) {
|
||||
const statusBySelectedId = SELECTABLE_STATUS.find((status) => status.id === data.status_id);
|
||||
function setStatus(data: SubmissionIdData) {
|
||||
const statusBySelectedId = SELECTABLE_STATUS.find((status) => status.id === data.statusId);
|
||||
|
||||
if (!statusBySelectedId) {
|
||||
return;
|
||||
@@ -76,18 +87,28 @@
|
||||
|
||||
status = statusBySelectedId;
|
||||
|
||||
if (data.status_id !== selectedId) {
|
||||
selectedId = data.status_id;
|
||||
if (data.statusId !== selectedId) {
|
||||
selectedId = data.statusId;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleDeleteSubmission() {
|
||||
isDeleting = true;
|
||||
await deleteSubmission(data.id, status.id);
|
||||
isDeleting = false;
|
||||
}
|
||||
|
||||
const { input, handleSubmit, completion } = useCompletion({
|
||||
api: '/api/completion/gradingprompt',
|
||||
onFinish: async () => {
|
||||
try {
|
||||
const responseData = $completion.replace('```json', '').replace('```', '');
|
||||
|
||||
let aiResponses = [];
|
||||
let aiResponses: {
|
||||
id: number;
|
||||
score: number;
|
||||
explanation: string;
|
||||
}[] = [];
|
||||
try {
|
||||
// Parse the modified response data as JSON
|
||||
aiResponses = JSON.parse(responseData);
|
||||
@@ -100,14 +121,14 @@
|
||||
|
||||
if (question_type_id !== QUESTION_TYPE.TEXTAREA) {
|
||||
const answer = data.questionAnswers.find((q) => q.question_id === id);
|
||||
|
||||
const answerPoints = answer?.answers?.length ?? 0;
|
||||
reasons = {
|
||||
...reasons,
|
||||
[id]: `${$t('course.navItem.submissions.grading_modal.questions_tried')} ${
|
||||
answer.answers.length
|
||||
} `
|
||||
[id]: `${$t(
|
||||
'course.navItem.submissions.grading_modal.questions_tried'
|
||||
)} ${answerPoints} `
|
||||
};
|
||||
data.questionAnswerByPoint[id] = points / answer.answers.length;
|
||||
data.questionAnswerByPoint[id] = `${points / answerPoints}`;
|
||||
} else if (aiResponses.length) {
|
||||
const graded = aiResponses.find((res) => res.id === id);
|
||||
|
||||
@@ -116,7 +137,7 @@
|
||||
[id]: `${graded?.explanation}`
|
||||
};
|
||||
|
||||
data.questionAnswerByPoint[id] = graded.score;
|
||||
data.questionAnswerByPoint[id] = `${graded?.score}`;
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -160,26 +181,51 @@
|
||||
headerClass="py-2"
|
||||
labelClass="text-base font-semibold"
|
||||
>
|
||||
<div class="w-full h-full">
|
||||
<Preview
|
||||
questions={Array.isArray(data.questions)
|
||||
? data.questions.sort((a, b) => a.order - b.order)
|
||||
: []}
|
||||
questionnaireMetaData={{
|
||||
answers: data.answers || {},
|
||||
isFinished: true
|
||||
}}
|
||||
bind:grades={data.questionAnswerByPoint}
|
||||
bind:reasons
|
||||
bind:isGradeWithAI
|
||||
bind:isLoading
|
||||
disableGrading={false}
|
||||
/>
|
||||
<div class="w-full h-full mt-2">
|
||||
{#if openDeletePrompt}
|
||||
<div class="w-96 mx-auto p-3 border border-gray-300 rounded-md">
|
||||
<h1 class="dark:text-white text-lg">
|
||||
{$t('delete_modal.content')}
|
||||
</h1>
|
||||
|
||||
<div class="mt-5 flex items-center justify-between">
|
||||
<PrimaryButton
|
||||
className="px-6 py-3"
|
||||
variant={VARIANTS.OUTLINED}
|
||||
label={$t('delete_modal.no')}
|
||||
onClick={() => (openDeletePrompt = false)}
|
||||
isDisabled={isDeleting}
|
||||
/>
|
||||
<PrimaryButton
|
||||
className="px-6 py-3"
|
||||
variant={VARIANTS.OUTLINED}
|
||||
label={$t('delete_modal.yes')}
|
||||
onClick={handleDeleteSubmission}
|
||||
isLoading={isDeleting}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<Preview
|
||||
questions={Array.isArray(data.questions)
|
||||
? data.questions.sort((a, b) => a.order - b.order)
|
||||
: []}
|
||||
questionnaireMetaData={{
|
||||
answers: data.answers || {},
|
||||
isFinished: true
|
||||
}}
|
||||
bind:grades={data.questionAnswerByPoint}
|
||||
bind:reasons
|
||||
bind:isGradeWithAI
|
||||
bind:isLoading
|
||||
disableGrading={false}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="ml-4 w-2/5 sticky top-0">
|
||||
<div class="ml-4 mt-2 w-2/5 sticky top-0">
|
||||
<div class="border border-gray-300 rounded-md">
|
||||
<div
|
||||
class="hover:bg-gray-100 dark:bg-neutral-800 border-b border-t-0 border-l-0 border-r-0 border-gray-300 p-3"
|
||||
class="flex gap-1 justify-between items-center border-b border-t-0 border-l-0 border-r-0 border-gray-300 p-3"
|
||||
>
|
||||
<p class="dark:text-white font-bold text-base">
|
||||
{$t('course.navItem.submissions.grading_modal.details')}
|
||||
@@ -193,6 +239,17 @@
|
||||
</span>
|
||||
{/if}
|
||||
</p>
|
||||
|
||||
<OverflowMenu open={openMenu} flipped>
|
||||
<OverflowMenuItem
|
||||
text={$t('delete_modal.label')}
|
||||
on:click={() => {
|
||||
openDeletePrompt = true;
|
||||
openMenu = false;
|
||||
}}
|
||||
danger
|
||||
/>
|
||||
</OverflowMenu>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center space-x-4 text-sm px-3 py-2">
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ export function getLectureNo(index, initNo = '0') {
|
||||
}
|
||||
|
||||
export function formatAnswers(data) {
|
||||
const answers = {};
|
||||
const answers: Record<string, string> = {};
|
||||
const questionByIdAndName = {};
|
||||
|
||||
for (const question of data.questions) {
|
||||
Reference in New Issue
Block a user