Merge branch 'main' into deadline-feature
This commit is contained in:
Generated
+146
-6567
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,47 @@
|
|||||||
|
<script>
|
||||||
|
import Modal from '../../../../Modal/index.svelte';
|
||||||
|
import PrimaryButton from '../../../../PrimaryButton/index.svelte';
|
||||||
|
|
||||||
|
import { VARIANTS } from '../../../../PrimaryButton/constants';
|
||||||
|
import { deleteConfirmation } from '../store/exercise';
|
||||||
|
|
||||||
|
export let onDelete = () => {};
|
||||||
|
export let onCancel = () => {};
|
||||||
|
|
||||||
|
async function handleDelete() {
|
||||||
|
onDelete();
|
||||||
|
$deleteConfirmation.open = false;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
onClose={() => ($deleteConfirmation.open = false)}
|
||||||
|
bind:open={$deleteConfirmation.open}
|
||||||
|
width="w-96"
|
||||||
|
modalHeading="Delete question"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<h1 class="text-lg">Are you sure you want to delete this question?</h1>
|
||||||
|
|
||||||
|
<div class="mt-5 flex items-center justify-between">
|
||||||
|
<PrimaryButton
|
||||||
|
className="px-6 py-2"
|
||||||
|
variant={VARIANTS.OUTLINED}
|
||||||
|
label="No, please don't"
|
||||||
|
onClick={() => {
|
||||||
|
$deleteConfirmation.open = false;
|
||||||
|
onCancel();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<PrimaryButton
|
||||||
|
className="px-6 py-2"
|
||||||
|
variant={VARIANTS.CONTAINED_DANGER}
|
||||||
|
label="Yes, delete"
|
||||||
|
onClick={() => {
|
||||||
|
onDelete();
|
||||||
|
$deleteConfirmation.open = false;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import { fly } from 'svelte/transition';
|
||||||
import {
|
import {
|
||||||
questionnaire,
|
questionnaire,
|
||||||
|
deleteConfirmation,
|
||||||
questionnaireValidation,
|
questionnaireValidation,
|
||||||
handleAddOption,
|
handleAddOption,
|
||||||
handleRemoveOption,
|
handleRemoveOption,
|
||||||
@@ -27,6 +29,7 @@
|
|||||||
import { VARIANTS } from '../../../../PrimaryButton/constants';
|
import { VARIANTS } from '../../../../PrimaryButton/constants';
|
||||||
import Select from '../../../../Form/Select.svelte';
|
import Select from '../../../../Form/Select.svelte';
|
||||||
import QuestionContainer from '../../../../QuestionContainer/index.svelte';
|
import QuestionContainer from '../../../../QuestionContainer/index.svelte';
|
||||||
|
import DeleteConfirmationModal from './DeleteConfirmation.svelte';
|
||||||
import {
|
import {
|
||||||
QUESTION_TYPE,
|
QUESTION_TYPE,
|
||||||
QUESTION_TYPES,
|
QUESTION_TYPES,
|
||||||
@@ -40,6 +43,7 @@
|
|||||||
const initialQuestionsLength = $questionnaire.questions.length;
|
const initialQuestionsLength = $questionnaire.questions.length;
|
||||||
|
|
||||||
let errors = {};
|
let errors = {};
|
||||||
|
let questionIdToDelete = null;
|
||||||
|
|
||||||
function shouldScrollToLast(index, questions) {
|
function shouldScrollToLast(index, questions) {
|
||||||
const currentQuestionsLength = questions.length;
|
const currentQuestionsLength = questions.length;
|
||||||
@@ -48,6 +52,17 @@
|
|||||||
return isLast && initialQuestionsLength !== currentQuestionsLength;
|
return isLast && initialQuestionsLength !== currentQuestionsLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onInitDeleteClicked(questionId) {
|
||||||
|
return () => {
|
||||||
|
questionIdToDelete = questionId;
|
||||||
|
$deleteConfirmation.open = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFinalDeleteClicked() {
|
||||||
|
handleRemoveQuestion(questionIdToDelete)();
|
||||||
|
}
|
||||||
|
|
||||||
function handleOptionClick(questionIndex) {
|
function handleOptionClick(questionIndex) {
|
||||||
return (actionIndex) => {
|
return (actionIndex) => {
|
||||||
switch (actionIndex) {
|
switch (actionIndex) {
|
||||||
@@ -70,6 +85,11 @@
|
|||||||
$: errors = $questionnaireValidation;
|
$: errors = $questionnaireValidation;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<DeleteConfirmationModal
|
||||||
|
onCancel={() => (questionIdToDelete = null)}
|
||||||
|
onDelete={onFinalDeleteClicked}
|
||||||
|
/>
|
||||||
|
|
||||||
<div class="w-11/12 m-auto">
|
<div class="w-11/12 m-auto">
|
||||||
<QuestionContainer isTitle={true}>
|
<QuestionContainer isTitle={true}>
|
||||||
<TextField
|
<TextField
|
||||||
@@ -102,8 +122,10 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#each filterOutDeleted($questionnaire.questions) as question, index}
|
{#each filterOutDeleted($questionnaire.questions) as question, index}
|
||||||
|
<!-- {#key question.id}
|
||||||
|
<div out:fly={{ x: 500, duration: 1000 }}> -->
|
||||||
<QuestionContainer
|
<QuestionContainer
|
||||||
onClose={handleRemoveQuestion(question.id)}
|
onClose={onInitDeleteClicked(question.id)}
|
||||||
scrollToQuestion={shouldScrollToLast(index, $questionnaire.questions)}
|
scrollToQuestion={shouldScrollToLast(index, $questionnaire.questions)}
|
||||||
bind:points={question.points}
|
bind:points={question.points}
|
||||||
hasError={!!errors[question.id]}
|
hasError={!!errors[question.id]}
|
||||||
@@ -245,5 +267,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</QuestionContainer>
|
</QuestionContainer>
|
||||||
|
<!-- </div>
|
||||||
|
{/key} -->
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
gradeMax={currentQuestion.points}
|
gradeMax={currentQuestion.points}
|
||||||
handleGrade={handleGrade(currentQuestion.id)}
|
handleGrade={handleGrade(currentQuestion.id)}
|
||||||
{disableGrading}
|
{disableGrading}
|
||||||
|
disabled={true}
|
||||||
/>
|
/>
|
||||||
{:else if QUESTION_TYPE.CHECKBOX === currentQuestion.question_type.id}
|
{:else if QUESTION_TYPE.CHECKBOX === currentQuestion.question_type.id}
|
||||||
<CheckboxQuestion
|
<CheckboxQuestion
|
||||||
@@ -46,6 +47,7 @@
|
|||||||
gradeMax={currentQuestion.points}
|
gradeMax={currentQuestion.points}
|
||||||
handleGrade={handleGrade(currentQuestion.id)}
|
handleGrade={handleGrade(currentQuestion.id)}
|
||||||
{disableGrading}
|
{disableGrading}
|
||||||
|
disabled={true}
|
||||||
/>
|
/>
|
||||||
{:else if QUESTION_TYPE.TEXTAREA === currentQuestion.question_type.id}
|
{:else if QUESTION_TYPE.TEXTAREA === currentQuestion.question_type.id}
|
||||||
<TextareaQuestion
|
<TextareaQuestion
|
||||||
@@ -62,6 +64,7 @@
|
|||||||
gradeMax={currentQuestion.points}
|
gradeMax={currentQuestion.points}
|
||||||
handleGrade={handleGrade(currentQuestion.id)}
|
handleGrade={handleGrade(currentQuestion.id)}
|
||||||
{disableGrading}
|
{disableGrading}
|
||||||
|
disabled={true}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
import { upsertExercise } from '../../../../../utils/services/courses';
|
import { upsertExercise } from '../../../../../utils/services/courses';
|
||||||
|
|
||||||
export let exerciseId;
|
export let exerciseId;
|
||||||
|
export let refetchExercise = () => {};
|
||||||
|
|
||||||
let mode = MODES.view;
|
let mode = MODES.view;
|
||||||
let preview = false;
|
let preview = false;
|
||||||
@@ -46,6 +47,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onCancel() {
|
||||||
|
mode = MODES.view;
|
||||||
|
refetchExercise();
|
||||||
|
}
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
reset();
|
reset();
|
||||||
});
|
});
|
||||||
@@ -57,19 +63,27 @@
|
|||||||
<RoleBasedSecurity allowedRoles="[1,2]">
|
<RoleBasedSecurity allowedRoles="[1,2]">
|
||||||
<PrimaryButton
|
<PrimaryButton
|
||||||
className="mr-2"
|
className="mr-2"
|
||||||
variant={VARIANTS.OUTLINED}
|
variant={VARIANTS.CONTAINED}
|
||||||
label={mode === MODES.edit ? 'Save' : 'Edit'}
|
label={mode === MODES.edit ? 'Save' : 'Edit'}
|
||||||
onClick={handleMode}
|
onClick={handleMode}
|
||||||
/>
|
/>
|
||||||
|
{#if mode === MODES.edit}
|
||||||
|
<PrimaryButton
|
||||||
|
className="mr-2"
|
||||||
|
variant={VARIANTS.OUTLINED}
|
||||||
|
label={'Cancel'}
|
||||||
|
onClick={onCancel}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
</RoleBasedSecurity>
|
</RoleBasedSecurity>
|
||||||
|
|
||||||
<!-- {#if mode === MODES.edit || preview} -->
|
{#if mode !== MODES.edit}
|
||||||
<PrimaryButton
|
<PrimaryButton
|
||||||
variant={preview ? VARIANTS.CONTAINED : VARIANTS.OUTLINED}
|
variant={preview ? VARIANTS.CONTAINED : VARIANTS.OUTLINED}
|
||||||
label={'Toggle Preview'}
|
label={'Toggle Preview'}
|
||||||
onClick={() => (preview = !preview)}
|
onClick={() => (preview = !preview)}
|
||||||
/>
|
/>
|
||||||
<!-- {/if} -->
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if mode === MODES.edit}
|
{#if mode === MODES.edit}
|
||||||
|
|||||||
@@ -105,7 +105,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if exerciseId}
|
{#if exerciseId}
|
||||||
<Exercise {exerciseId} />
|
<Exercise {exerciseId} refetchExercise={() => getExercise(exerciseId)} />
|
||||||
{:else}
|
{:else}
|
||||||
<Modal
|
<Modal
|
||||||
onClose={handleCancelAddExercise}
|
onClose={handleCancelAddExercise}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { questionnaireMetaData } from './answers';
|
|||||||
import { isUUID } from '../../../../../utils/functions/isUUID';
|
import { isUUID } from '../../../../../utils/functions/isUUID';
|
||||||
|
|
||||||
export const isQuestionnaireFetching = writable(false);
|
export const isQuestionnaireFetching = writable(false);
|
||||||
|
export const deleteConfirmation = writable({ open: false });
|
||||||
|
|
||||||
// {'question-id': { option: '', title: '', ... }}
|
// {'question-id': { option: '', title: '', ... }}
|
||||||
export const questionnaireValidation = writable({});
|
export const questionnaireValidation = writable({});
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
function handleMainGroupClick(href) {
|
function handleMainGroupClick(href) {
|
||||||
return () => {
|
return () => {
|
||||||
if ($isMobile) {
|
if ($isMobile) {
|
||||||
show = false;
|
setTimeout(() => (show = false), 500);
|
||||||
}
|
}
|
||||||
goto(href);
|
goto(href);
|
||||||
};
|
};
|
||||||
@@ -170,7 +170,11 @@
|
|||||||
href={isStudent && !item.is_complete
|
href={isStudent && !item.is_complete
|
||||||
? $page.path
|
? $page.path
|
||||||
: getLessonsRoute($course.id, item.id)}
|
: getLessonsRoute($course.id, item.id)}
|
||||||
on:click={() => $isMobile && (show = false)}
|
on:click={() => {
|
||||||
|
if ($isMobile) {
|
||||||
|
setTimeout(() => (show = false), 500);
|
||||||
|
}
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<span class="course-counter">
|
<span class="course-counter">
|
||||||
{getLectureNo(index + 1)}
|
{getLectureNo(index + 1)}
|
||||||
|
|||||||
Reference in New Issue
Block a user