CLASSROOMIO-T-15: Delete exercise
This commit is contained in:
@@ -36,7 +36,8 @@
|
||||
QUESTION_TYPES,
|
||||
} from '../../../../Question/constants';
|
||||
import { filterOutDeleted } from './functions';
|
||||
import Date from '../../../../Form/Date.svelte';
|
||||
import { deleteExercise } from '../../../../../utils/services/courses';
|
||||
import { lesson } from '../store/lessons';
|
||||
// import EditContent from "../../../../EditContent/index.svelte";
|
||||
// import readme from "../../readme.js";
|
||||
|
||||
@@ -45,10 +46,14 @@
|
||||
const initialQuestionsLength = $questionnaire.questions.length;
|
||||
|
||||
export let editDescription = false;
|
||||
export let exerciseId;
|
||||
export let goBack = () => {};
|
||||
|
||||
let errors = {};
|
||||
let questionIdToDelete = null;
|
||||
let questions = [];
|
||||
let shouldDelete = false;
|
||||
let isDeleting = false;
|
||||
|
||||
function shouldScrollToLast(questionId, questions) {
|
||||
const currentQuestionsLength = questions.length;
|
||||
@@ -88,6 +93,22 @@
|
||||
return errors[question.id] ? errors[question.id][errorKey] : null;
|
||||
}
|
||||
|
||||
async function handleDelete() {
|
||||
console.log('delete');
|
||||
isDeleting = true;
|
||||
await deleteExercise(questions, exerciseId);
|
||||
|
||||
lesson.update((_lesson) => ({
|
||||
..._lesson,
|
||||
exercises: _lesson.exercises.filter(
|
||||
(exercise) => exercise.id !== exerciseId
|
||||
),
|
||||
}));
|
||||
|
||||
shouldDelete = false;
|
||||
goBack();
|
||||
}
|
||||
|
||||
$: errors = $questionnaireValidation;
|
||||
$: questions = filterOutDeleted($questionnaire.questions);
|
||||
</script>
|
||||
@@ -105,32 +126,62 @@
|
||||
width="w-2/4"
|
||||
modalHeading="Update description"
|
||||
>
|
||||
<div>
|
||||
<QuestionContainer isTitle={true}>
|
||||
<TextField
|
||||
placeholder="Title"
|
||||
bind:value={$questionnaire.title}
|
||||
className="mb-2"
|
||||
onChange={() => ($questionnaire.is_title_dirty = true)}
|
||||
/>
|
||||
<DateTime
|
||||
label="Due by"
|
||||
className="w-50"
|
||||
value={$questionnaire.due_by}
|
||||
onInput={(e) => {
|
||||
$questionnaire.due_by = e.target.value;
|
||||
$questionnaire.is_due_by_dirty = true;
|
||||
}}
|
||||
/>
|
||||
<EditContent
|
||||
writeLabel="Description"
|
||||
bind:value={$questionnaire.description}
|
||||
placeholder="Start typing your lesson"
|
||||
textAreaHeight="100px"
|
||||
onInputChange={() => ($questionnaire.is_description_dirty = true)}
|
||||
/>
|
||||
</QuestionContainer>
|
||||
</div>
|
||||
{#if shouldDelete}
|
||||
<form on:submit|preventDefault={() => (shouldDelete = false)}>
|
||||
<h1 class="text-2xl">Are you sure?</h1>
|
||||
|
||||
<div class="mt-5 flex items-center justify-between">
|
||||
<PrimaryButton
|
||||
className="px-6 py-2"
|
||||
variant={VARIANTS.OUTLINED}
|
||||
label="No, cancel"
|
||||
type="submit"
|
||||
/>
|
||||
<PrimaryButton
|
||||
className="px-6 py-2"
|
||||
variant={VARIANTS.CONTAINED_DANGER}
|
||||
label={isDeleting ? 'Deleting...' : 'Yes, delete'}
|
||||
isDisabled={isDeleting}
|
||||
onClick={handleDelete}
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
{:else}
|
||||
<div>
|
||||
<QuestionContainer isTitle={true}>
|
||||
<TextField
|
||||
placeholder="Title"
|
||||
bind:value={$questionnaire.title}
|
||||
className="mb-2"
|
||||
onChange={() => ($questionnaire.is_title_dirty = true)}
|
||||
/>
|
||||
<DateTime
|
||||
label="Due by"
|
||||
className="w-50"
|
||||
value={$questionnaire.due_by}
|
||||
onInput={(e) => {
|
||||
$questionnaire.due_by = e.target.value;
|
||||
$questionnaire.is_due_by_dirty = true;
|
||||
}}
|
||||
/>
|
||||
<EditContent
|
||||
writeLabel="Description"
|
||||
bind:value={$questionnaire.description}
|
||||
placeholder="Start typing your lesson"
|
||||
textAreaHeight="100px"
|
||||
onInputChange={() => ($questionnaire.is_description_dirty = true)}
|
||||
/>
|
||||
</QuestionContainer>
|
||||
<div class="float-right">
|
||||
<PrimaryButton
|
||||
className="px-6 py-2"
|
||||
variant={VARIANTS.CONTAINED_DANGER}
|
||||
label="Delete this exercise"
|
||||
onClick={() => (shouldDelete = true)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</Modal>
|
||||
|
||||
<div class="w-full">
|
||||
|
||||
@@ -230,13 +230,12 @@
|
||||
<span
|
||||
class="status-text bg-green-700 text-white rounded-full py-2 px-6 text-center"
|
||||
title="Status: Pending Review"
|
||||
|
||||
>
|
||||
Graded
|
||||
</span>
|
||||
{:else}
|
||||
<span
|
||||
class=" status-text bg-yellow-600 text-white rounded-full py-2 px-6 text-center"
|
||||
class="status-text bg-yellow-600 text-white rounded-full py-2 px-6 text-center"
|
||||
title="Status: Pending Review"
|
||||
>
|
||||
Pending
|
||||
@@ -245,7 +244,7 @@
|
||||
</div>
|
||||
{#if STATUS.GRADED === $questionnaireMetaData.status}
|
||||
<span
|
||||
class="border-2 border-gray-700 rounded-full h-24 w-24 flex items-center justify-center text-2xl"
|
||||
class="p-5 border-2 border-gray-700 rounded-full h-24 w-24 flex items-center justify-center text-2xl"
|
||||
title="Status: Pending Review"
|
||||
>
|
||||
{$questionnaireMetaData.finalTotalGrade}/{$questionnaireMetaData.totalPossibleGrade}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
export let exerciseId;
|
||||
export let refetchExercise = () => {};
|
||||
export let goBack = () => {};
|
||||
|
||||
let mode = MODES.view;
|
||||
let preview = false;
|
||||
@@ -135,7 +136,7 @@
|
||||
</svelte:fragment>
|
||||
|
||||
{#if mode === MODES.edit && !preview}
|
||||
<EditMode bind:editDescription />
|
||||
<EditMode bind:editDescription {exerciseId} {goBack} />
|
||||
{:else}
|
||||
<ViewMode {preview} {exerciseId} />
|
||||
{/if}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<script>
|
||||
import { goto } from '@sapper/app';
|
||||
import { onMount } from 'svelte';
|
||||
import AudioConsole32 from 'carbon-icons-svelte/lib/AudioConsole32';
|
||||
import Box from '../../../../Box/index.svelte';
|
||||
@@ -79,14 +80,18 @@
|
||||
.eq('id', exerciseId)
|
||||
.single();
|
||||
|
||||
// Need to set the question type inorder for the select in the questionnaire builder to match
|
||||
data.questions.forEach((question) => {
|
||||
question.question_type = QUESTION_TYPES.find(
|
||||
(type) => type.id === question.question_type.id
|
||||
);
|
||||
return question;
|
||||
});
|
||||
data.questions = data.questions.sort((a, b) => a.order - b.order);
|
||||
if (data && Array.isArray(data.questions)) {
|
||||
// Need to set the question type inorder for the select in the questionnaire builder to match
|
||||
data.questions.forEach((question) => {
|
||||
question.question_type = QUESTION_TYPES.find(
|
||||
(type) => type.id === question.question_type.id
|
||||
);
|
||||
return question;
|
||||
});
|
||||
data.questions = data.questions.sort((a, b) => a.order - b.order);
|
||||
} else {
|
||||
data.questions = [];
|
||||
}
|
||||
|
||||
data.is_title_dirty = false;
|
||||
data.is_description_dirty = false;
|
||||
@@ -98,6 +103,10 @@
|
||||
isQuestionnaireFetching.update(() => false);
|
||||
}
|
||||
|
||||
function goBack() {
|
||||
goto(path);
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
getExercises();
|
||||
});
|
||||
@@ -106,7 +115,11 @@
|
||||
</script>
|
||||
|
||||
{#if exerciseId}
|
||||
<Exercise {exerciseId} refetchExercise={() => getExercise(exerciseId)} />
|
||||
<Exercise
|
||||
{exerciseId}
|
||||
{goBack}
|
||||
refetchExercise={() => getExercise(exerciseId)}
|
||||
/>
|
||||
{:else}
|
||||
<Modal
|
||||
onClose={handleCancelAddExercise}
|
||||
|
||||
Reference in New Issue
Block a user