diff --git a/client/src/__tests__/components/GiftTemplate/GIFTTemplatePreview.test.tsx b/client/src/__tests__/components/GiftTemplate/GIFTTemplatePreview.test.tsx index 586c8d1..2b0e36d 100644 --- a/client/src/__tests__/components/GiftTemplate/GIFTTemplatePreview.test.tsx +++ b/client/src/__tests__/components/GiftTemplate/GIFTTemplatePreview.test.tsx @@ -3,49 +3,87 @@ import { render, screen } from '@testing-library/react'; import '@testing-library/jest-dom'; import GIFTTemplatePreview from 'src/components/GiftTemplate/GIFTTemplatePreview'; +const validQuestions = [ + '::TFTitle::[markdown]Troo statement {TRUE}', + '::SATitle::[markdown]What is the answer? {=ShortAnswerOne =ShortAnswerTwo}', + '::MCQTitle::[markdown]MultiChoice question? {=MQAnswerOne ~MQAnswerTwo#feedback####Gen feedback}', +]; + +const unsupportedQuestions = [ + '::Title::[markdown]Essay {}', + '::Title::[markdown]Matching {}', + '::Title::[markdown]Description', + '$CATEGORY a/b/c' +]; + describe('GIFTTemplatePreview Component', () => { - test('renders error message when questions contain invalid syntax', () => { - render(); - const errorMessage = screen.findByText(/Erreur inconnue/i, {}, { timeout: 5000 }); - expect(errorMessage).resolves.toBeInTheDocument(); - }); - test('renders preview when valid questions are provided', () => { - const questions = [ - 'Question 1 { A | B | C }', - 'Question 2 { D | E | F }', - ]; - render(); + it('renders error message when questions contain invalid syntax', () => { + render(); const previewContainer = screen.getByTestId('preview-container'); expect(previewContainer).toBeInTheDocument(); + const errorMessage = previewContainer.querySelector('div[label="error-message"]'); + expect(errorMessage).toBeInTheDocument(); }); - test('hides answers when hideAnswers prop is true', () => { - const questions = [ - 'Question 1 { A | B | C }', - 'Question 2 { D | E | F }', - ]; - render(); + + it('renders preview when valid questions are provided, including answers, has no errors', () => { + render(); const previewContainer = screen.getByTestId('preview-container'); expect(previewContainer).toBeInTheDocument(); + // Check that all question titles are rendered inside the previewContainer + validQuestions.forEach((question) => { + const title = question.split('::')[1].split('::')[0]; + expect(previewContainer).toHaveTextContent(title); + }); + // There should be no errors + const errorMessage = previewContainer.querySelector('div[label="error-message"]'); + expect(errorMessage).not.toBeInTheDocument(); + // Check that some stems and answers are rendered inside the previewContainer + expect(previewContainer).toHaveTextContent('Troo statement'); + expect(previewContainer).toHaveTextContent('What is the answer?'); + expect(previewContainer).toHaveTextContent('MultiChoice question?'); + expect(previewContainer).toHaveTextContent('Vrai'); + // short answers are stored in a textbox + const answerInputElements = screen.getAllByRole('textbox'); + const giftInputElements = answerInputElements.filter(element => element.classList.contains('gift-input')); + + expect(giftInputElements).toHaveLength(1); + expect(giftInputElements[0]).toHaveAttribute('placeholder', 'ShortAnswerOne, ShortAnswerTwo'); + + // Check for correct answer icon just after MQAnswerOne + const mqAnswerOneElement = screen.getByText('MQAnswerOne'); + const correctAnswerIcon = mqAnswerOneElement.parentElement?.querySelector('[data-testid="correct-icon"]'); + expect(correctAnswerIcon).toBeInTheDocument(); + + // Check for incorrect answer icon just after MQAnswerTwo + const mqAnswerTwoElement = screen.getByText('MQAnswerTwo'); + const incorrectAnswerIcon = mqAnswerTwoElement.parentElement?.querySelector('[data-testid="incorrect-icon"]'); + expect(incorrectAnswerIcon).toBeInTheDocument(); + }); + + it('hides answers when hideAnswers prop is true', () => { + render(); + const previewContainer = screen.getByTestId('preview-container'); + expect(previewContainer).toBeInTheDocument(); + expect(previewContainer).toHaveTextContent('Troo statement'); + expect(previewContainer).toHaveTextContent('What is the answer?'); + expect(previewContainer).toHaveTextContent('MultiChoice question?'); + expect(previewContainer).toHaveTextContent('Vrai'); + expect(previewContainer).not.toHaveTextContent('ShortAnswerOne'); + expect(previewContainer).not.toHaveTextContent('ShortAnswerTwo'); + // shouldn't have correct/incorrect icons + const correctAnswerIcon = screen.queryByTestId('correct-icon'); + expect(correctAnswerIcon).not.toBeInTheDocument(); + const incorrectAnswerIcon = screen.queryByTestId('incorrect-icon'); + expect(incorrectAnswerIcon).not.toBeInTheDocument(); }); - // it('renders images correctly', () => { - // const questions = [ - // 'Question 1', - // 'Image 1', - // 'Question 2', - // 'Image 2', - // ]; - // const { getByAltText } = render(); - // const image1 = getByAltText('Image 1'); - // const image2 = getByAltText('Image 2'); - // expect(image1).toBeInTheDocument(); - // expect(image2).toBeInTheDocument(); - // }); - // it('renders non-images correctly', () => { - // const questions = ['Question 1', 'Question 2']; - // const { queryByAltText } = render(); - // const image1 = queryByAltText('Image 1'); - // const image2 = queryByAltText('Image 2'); - // expect(image1).toBeNull(); - // expect(image2).toBeNull(); - // }); + + it('should indicate in the preview that unsupported GIFT questions are not supported', () => { + render(); + const previewContainer = screen.getByTestId('preview-container'); + expect(previewContainer).toBeInTheDocument(); + // find all unsupported errors (should be 4) + const unsupportedMessages = previewContainer.querySelectorAll('div[label="error-message"]'); + expect(unsupportedMessages).toHaveLength(4); + }); + }); diff --git a/client/src/__tests__/components/GiftTemplate/templates/__snapshots__/MultipleChoice.test.tsx.snap b/client/src/__tests__/components/GiftTemplate/templates/__snapshots__/MultipleChoice.test.tsx.snap index 189ede7..0a17bf6 100644 --- a/client/src/__tests__/components/GiftTemplate/templates/__snapshots__/MultipleChoice.test.tsx.snap +++ b/client/src/__tests__/components/GiftTemplate/templates/__snapshots__/MultipleChoice.test.tsx.snap @@ -64,7 +64,7 @@ exports[`MultipleChoice snapshot test 1`] = ` " for="idmocked-id"> Choice 1 </label> - <svg style=" + <svg data-testid="correct-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; @@ -88,7 +88,7 @@ exports[`MultipleChoice snapshot test 1`] = ` " for="idmocked-id"> Choice 2 </label> - <svg style=" + <svg data-testid="incorrect-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; @@ -180,7 +180,7 @@ exports[`MultipleChoice snapshot test with 2 images using markdown text format 1 Choice 1 </label> - <svg style=" + <svg data-testid="correct-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; @@ -205,7 +205,7 @@ exports[`MultipleChoice snapshot test with 2 images using markdown text format 1 Choice 2 </label> - <svg style=" + <svg data-testid="incorrect-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; @@ -229,7 +229,7 @@ exports[`MultipleChoice snapshot test with 2 images using markdown text format 1 " for="idmocked-id"> <img alt="Sample Image" src="https://via.placeholder.com/150"> </label> - <svg style=" + <svg data-testid="incorrect-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; @@ -321,7 +321,7 @@ exports[`MultipleChoice snapshot test with Moodle text format 1`] = ` " for="idmocked-id"> Choice 1 </label> - <svg style=" + <svg data-testid="correct-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; @@ -345,7 +345,7 @@ exports[`MultipleChoice snapshot test with Moodle text format 1`] = ` " for="idmocked-id"> Choice 2 </label> - <svg style=" + <svg data-testid="incorrect-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; @@ -436,7 +436,7 @@ exports[`MultipleChoice snapshot test with image 1`] = ` " for="idmocked-id"> Choice 1 </label> - <svg style=" + <svg data-testid="correct-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; @@ -460,7 +460,7 @@ exports[`MultipleChoice snapshot test with image 1`] = ` " for="idmocked-id"> Choice 2 </label> - <svg style=" + <svg data-testid="incorrect-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; @@ -484,7 +484,7 @@ exports[`MultipleChoice snapshot test with image 1`] = ` " for="idmocked-id"> <img alt="Sample Image" src="https://via.placeholder.com/150"> </label> - <svg style=" + <svg data-testid="incorrect-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; @@ -577,7 +577,7 @@ exports[`MultipleChoice snapshot test with image using markdown text format 1`] Choice 1 </label> - <svg style=" + <svg data-testid="correct-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; @@ -602,7 +602,7 @@ exports[`MultipleChoice snapshot test with image using markdown text format 1`] Choice 2 </label> - <svg style=" + <svg data-testid="incorrect-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; @@ -626,7 +626,7 @@ exports[`MultipleChoice snapshot test with image using markdown text format 1`] " for="idmocked-id"> <img alt="Sample Image" src="https://via.placeholder.com/150"> </label> - <svg style=" + <svg data-testid="incorrect-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; @@ -718,7 +718,7 @@ exports[`MultipleChoice snapshot test with katex 1`] = ` " for="idmocked-id"> Choice 1 </label> - <svg style=" + <svg data-testid="correct-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; @@ -742,7 +742,7 @@ exports[`MultipleChoice snapshot test with katex 1`] = ` " for="idmocked-id"> Choice 2 </label> - <svg style=" + <svg data-testid="correct-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; @@ -833,7 +833,7 @@ exports[`MultipleChoice snapshot test with katex, using html text format 1`] = ` " for="idmocked-id"> Choice 1 </label> - <svg style=" + <svg data-testid="correct-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; @@ -857,7 +857,7 @@ exports[`MultipleChoice snapshot test with katex, using html text format 1`] = ` " for="idmocked-id"> Choice 2 </label> - <svg style=" + <svg data-testid="incorrect-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; diff --git a/client/src/__tests__/components/GiftTemplate/templates/__snapshots__/TrueFalse.test.tsx.snap b/client/src/__tests__/components/GiftTemplate/templates/__snapshots__/TrueFalse.test.tsx.snap index 6ff0e9d..002da61 100644 --- a/client/src/__tests__/components/GiftTemplate/templates/__snapshots__/TrueFalse.test.tsx.snap +++ b/client/src/__tests__/components/GiftTemplate/templates/__snapshots__/TrueFalse.test.tsx.snap @@ -150,7 +150,7 @@ exports[`TrueFalse snapshot test with katex 1`] = ` " for="idmocked-id"> Vrai </label> - <svg style=" + <svg data-testid="correct-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; @@ -174,7 +174,7 @@ exports[`TrueFalse snapshot test with katex 1`] = ` " for="idmocked-id"> Faux </label> - <svg style=" + <svg data-testid="incorrect-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; @@ -265,7 +265,7 @@ exports[`TrueFalse snapshot test with moodle 1`] = ` " for="idmocked-id"> Vrai </label> - <svg style=" + <svg data-testid="correct-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; @@ -289,7 +289,7 @@ exports[`TrueFalse snapshot test with moodle 1`] = ` " for="idmocked-id"> Faux </label> - <svg style=" + <svg data-testid="incorrect-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; @@ -380,7 +380,7 @@ exports[`TrueFalse snapshot test with plain text 1`] = ` " for="idmocked-id"> Vrai </label> - <svg style=" + <svg data-testid="correct-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; @@ -404,7 +404,7 @@ exports[`TrueFalse snapshot test with plain text 1`] = ` " for="idmocked-id"> Faux </label> - <svg style=" + <svg data-testid="incorrect-icon" style=" vertical-align: text-bottom; display: inline-block; margin-left: 0.1rem; diff --git a/client/src/components/GiftTemplate/GIFTTemplatePreview.tsx b/client/src/components/GiftTemplate/GIFTTemplatePreview.tsx index 1bacf8c..9da21c8 100644 --- a/client/src/components/GiftTemplate/GIFTTemplatePreview.tsx +++ b/client/src/components/GiftTemplate/GIFTTemplatePreview.tsx @@ -1,6 +1,6 @@ // GIFTTemplatePreview.tsx import React, { useEffect, useState } from 'react'; -import Template, { ErrorTemplate } from './templates'; +import Template, { ErrorTemplate, UnsupportedQuestionTypeError } from './templates'; import { parse } from 'gift-pegjs'; import './styles.css'; import { FormattedTextTemplate } from './templates/TextTypeTemplate'; @@ -22,19 +22,6 @@ const GIFTTemplatePreview: React.FC = ({ try { let previewHTML = ''; questions.forEach((giftQuestion) => { - // TODO : afficher un message que les images spécifiées par sont dépréciées et qu'il faut utiliser [markdown] et la syntaxe ![alt](url) - - // const isImage = item.includes(']+>/i); - // if (imageUrlMatch) { - // let imageUrl = imageUrlMatch[0]; - // imageUrl = imageUrl.replace('img', 'img style="width:10vw;" src='); - // item = item.replace(imageUrlMatch[0], ''); - // previewHTML += `${imageUrl}`; - // } - // } - try { const question = parse(giftQuestion); previewHTML += Template(question[0], { @@ -42,11 +29,15 @@ const GIFTTemplatePreview: React.FC = ({ theme: 'light' }); } catch (error) { - if (error instanceof Error) { - previewHTML += ErrorTemplate(giftQuestion + '\n' + error.message); + let errorMsg: string; + if (error instanceof UnsupportedQuestionTypeError) { + errorMsg = ErrorTemplate(giftQuestion, `Erreur: ${error.message}`); + } else if (error instanceof Error) { + errorMsg = ErrorTemplate(giftQuestion, `Erreur GIFT: ${error.message}`); } else { - previewHTML += ErrorTemplate(giftQuestion + '\n' + 'Erreur inconnue'); + errorMsg = ErrorTemplate(giftQuestion, 'Erreur inconnue'); } + previewHTML += `
${errorMsg}
`; } }); diff --git a/client/src/components/GiftTemplate/index.ts b/client/src/components/GiftTemplate/index.ts index 04de882..6a9892f 100644 --- a/client/src/components/GiftTemplate/index.ts +++ b/client/src/components/GiftTemplate/index.ts @@ -18,11 +18,11 @@ What is the capital of Canada? {=Canada -> Ottawa =Italy -> Rome =Japan -> Tokyo const items = multiple.map((item) => Template(item, { theme: 'dark' })).join(''); -const errorItemDark = ErrorTemplate('Hello'); +const errorItemDark = ErrorTemplate('Hello', 'Error'); const lightItems = multiple.map((item) => Template(item, { theme: 'light' })).join(''); -const errorItem = ErrorTemplate('Hello'); +const errorItem = ErrorTemplate('Hello', 'Error'); const app = document.getElementById('app'); if (app) app.innerHTML = items + errorItemDark + lightItems + errorItem; diff --git a/client/src/components/GiftTemplate/templates/AnswerIconTemplate.ts b/client/src/components/GiftTemplate/templates/AnswerIconTemplate.ts index aa95386..b9811d5 100644 --- a/client/src/components/GiftTemplate/templates/AnswerIconTemplate.ts +++ b/client/src/components/GiftTemplate/templates/AnswerIconTemplate.ts @@ -25,11 +25,11 @@ export default function AnswerIcon({ correct }: AnswerIconOptions): string { `; const CorrectIcon = (): string => { - return ``; + return ``; }; const IncorrectIcon = (): string => { - return ``; + return ``; }; return correct ? CorrectIcon() : IncorrectIcon(); diff --git a/client/src/components/GiftTemplate/templates/ErrorTemplate.ts b/client/src/components/GiftTemplate/templates/ErrorTemplate.ts index 097c9e7..1da9c5b 100644 --- a/client/src/components/GiftTemplate/templates/ErrorTemplate.ts +++ b/client/src/components/GiftTemplate/templates/ErrorTemplate.ts @@ -1,7 +1,7 @@ import { theme, ParagraphStyle } from '../constants'; import { state } from '.'; -export default function (text: string): string { +export default function (questionText: string, errorText: string): string { const Container = ` flex-wrap: wrap; position: relative; @@ -13,47 +13,49 @@ export default function (text: string): string { box-shadow: 0px 1px 3px ${theme(state.theme, 'gray400', 'black900')}; `; - const document = removeBackslash(lineRegex(documentRegex(text))).split(/\r?\n/); - return document[0] !== `` - ? `
${document - .map((i) => `

${i}

`) - .join('')}
` - : ``; + // const document = removeBackslash(lineRegex(documentRegex(text))).split(/\r?\n/); + // return document[0] !== `` + // ? `
${document + // .map((i) => `

${i}

`) + // .join('')}
` + // : ``; + return `

${questionText}
${errorText}

`; } -function documentRegex(text: string): string { - const newText = text - .split(/\r?\n/) - .map((comment) => comment.replace(/(^[ \\t]+)?(^)((\/\/))(.*)/gm, '')) - .join(''); +// function documentRegex(text: string): string { +// const newText = text +// .split(/\r?\n/) +// .map((comment) => comment.replace(/(^[ \\t]+)?(^)((\/\/))(.*)/gm, '')) +// .join(''); - const newLineAnswer = /([^\\]|[^\S\r\n][^=])(=|~)/g; - const correctAnswer = /([^\\]|^{)(([^\\]|^|\\s*)=(.*)(?=[=~}]|\\n))/g; - const incorrectAnswer = /([^\\]|^{)(([^\\]|^|\\s*)~(.*)(?=[=~}]|\\n))/g; +// const newLineAnswer = /([^\\]|[^\S\r\n][^=])(=|~)/g; +// const correctAnswer = /([^\\]|^{)(([^\\]|^|\\s*)=(.*)(?=[=~}]|\\n))/g; +// const incorrectAnswer = /([^\\]|^{)(([^\\]|^|\\s*)~(.*)(?=[=~}]|\\n))/g; - return newText - .replace(newLineAnswer, `\n$2`) - .replace(correctAnswer, `$1
  • $4
  • `) - .replace(incorrectAnswer, `$1
  • $4
  • `); -} +// return newText +// .replace(newLineAnswer, `\n$2`) +// .replace(correctAnswer, `$1
  • $4
  • `) +// .replace(incorrectAnswer, `$1
  • $4
  • `); +// } -function lineRegex(text: string): string { - return text - .split(/\r?\n/) - .map((category) => - category.replace(/(^[ \\t]+)?(((^|\n)\s*[$]CATEGORY:))(.+)/g, `
    $5
    `) - ) - .map((title) => title.replace(/\s*(::)\s*(.*?)(::)/g, `
    $2
    `)) - .map((openBracket) => openBracket.replace(/([^\\]|^){([#])?/g, `$1
    `)) - .map((closeBracket) => closeBracket.replace(/([^\\]|^)}/g, `$1
    `)) - .join(''); -} +// function lineRegex(text: string): string { +// return text +// // CPF: disabled the following regex because it's not clear what it's supposed to do +// // .split(/\r?\n/) +// // .map((category) => +// // category.replace(/(^[ \\t]+)?(((^|\n)\s*[$]CATEGORY:))(.+)/g, `
    $5
    `) +// // ) +// // .map((title) => title.replace(/\s*(::)\s*(.*?)(::)/g, `
    $2
    `)) +// // .map((openBracket) => openBracket.replace(/([^\\]|^){([#])?/g, `$1
    `)) +// // .map((closeBracket) => closeBracket.replace(/([^\\]|^)}/g, `$1
    `)) +// // .join(''); +// } -function removeBackslash(text: string): string { - return text - .split(/\r?\n/) - .map((colon) => colon.replace(/[\\]:/g, ':')) - .map((openBracket) => openBracket.replace(/[\\]{/g, '{')) - .map((closeBracket) => closeBracket.replace(/[\\]}/g, '}')) - .join(''); -} +// function removeBackslash(text: string): string { +// return text +// .split(/\r?\n/) +// .map((colon) => colon.replace(/[\\]:/g, ':')) +// .map((openBracket) => openBracket.replace(/[\\]{/g, '{')) +// .map((closeBracket) => closeBracket.replace(/[\\]}/g, '}')) +// .join(''); +// } diff --git a/client/src/components/GiftTemplate/templates/index.ts b/client/src/components/GiftTemplate/templates/index.ts index 0ed65e0..53c7e4f 100644 --- a/client/src/components/GiftTemplate/templates/index.ts +++ b/client/src/components/GiftTemplate/templates/index.ts @@ -6,20 +6,32 @@ import { MultipleChoiceQuestion as MultipleChoiceType, NumericalQuestion as NumericalType, ShortAnswerQuestion as ShortAnswerType, - // Essay as EssayType, + // EssayQuestion as EssayType, TrueFalseQuestion as TrueFalseType, // MatchingQuestion as MatchingType, } from 'gift-pegjs'; import { DisplayOptions } from './types'; -import DescriptionTemplate from './DescriptionTemplate'; -import EssayTemplate from './EssayTemplate'; -import MatchingTemplate from './MatchingTemplate'; +// import DescriptionTemplate from './DescriptionTemplate'; +// import EssayTemplate from './EssayTemplate'; +// import MatchingTemplate from './MatchingTemplate'; import MultipleChoiceTemplate from './MultipleChoiceTemplate'; import NumericalTemplate from './NumericalTemplate'; import ShortAnswerTemplate from './ShortAnswerTemplate'; import TrueFalseTemplate from './TrueFalseTemplate'; import Error from './ErrorTemplate'; -import CategoryTemplate from './CategoryTemplate'; +// import CategoryTemplate from './CategoryTemplate'; + +export class UnsupportedQuestionTypeError extends globalThis.Error { + constructor(type: string) { + const userFriendlyType = (type === 'Essay') ? 'Réponse longue (Essay)' + : (type === 'Matching') ? 'Association (Matching)' + : (type === 'Category') ? 'Catégorie (Category)' + : type; + super(`Les questions du type ${userFriendlyType} ne sont pas supportées.`); + this.name = 'UnsupportedQuestionTypeError'; + } +} + export const state: DisplayOptions = { preview: true, theme: 'light' }; @@ -54,23 +66,21 @@ export default function Template( // case 'Matching': // return Matching({ ...(keys as MatchingType) }); default: - // TODO: throw error for unsupported question types? - // throw new Error(`Unsupported question type: ${type}`); - return ``; - } + // convert type to human-readable string + throw new UnsupportedQuestionTypeError(type); } } -export function ErrorTemplate(text: string, options?: Partial): string { +export function ErrorTemplate(questionText: string, errorText: string, options?: Partial): string { Object.assign(state, options); - return Error(text); + return Error(questionText, errorText); } export { - CategoryTemplate, - DescriptionTemplate as Description, - EssayTemplate as Essay, - MatchingTemplate as Matching, + // CategoryTemplate, + // DescriptionTemplate as Description, + // EssayTemplate as Essay, + // MatchingTemplate as Matching, MultipleChoiceTemplate as MultipleChoice, NumericalTemplate as Numerical, ShortAnswerTemplate as ShortAnswer, diff --git a/client/src/components/LiveResults/LiveResultsTable/TableComponents/LiveResultsTableHeader.tsx b/client/src/components/LiveResults/LiveResultsTable/TableComponents/LiveResultsTableHeader.tsx index fb4219b..d8d4159 100644 --- a/client/src/components/LiveResults/LiveResultsTable/TableComponents/LiveResultsTableHeader.tsx +++ b/client/src/components/LiveResults/LiveResultsTable/TableComponents/LiveResultsTableHeader.tsx @@ -1,12 +1,12 @@ -import { TableCell, TableHead, TableRow } from "@mui/material"; import React from "react"; +import { TableCell, TableHead, TableRow } from "@mui/material"; -interface LiveResultsFooterProps { +interface LiveResultsHeaderProps { maxQuestions: number; showSelectedQuestion: (index: number) => void; } -const LiveResultsTableFooter: React.FC = ({ +const LiveResultsTableHeader: React.FC = ({ maxQuestions, showSelectedQuestion, }) => { @@ -47,4 +47,4 @@ const LiveResultsTableFooter: React.FC = ({ ); }; -export default LiveResultsTableFooter; \ No newline at end of file +export default LiveResultsTableHeader; diff --git a/client/src/pages/Teacher/EditorQuiz/EditorQuiz.tsx b/client/src/pages/Teacher/EditorQuiz/EditorQuiz.tsx index 453d5c9..f2c2d69 100644 --- a/client/src/pages/Teacher/EditorQuiz/EditorQuiz.tsx +++ b/client/src/pages/Teacher/EditorQuiz/EditorQuiz.tsx @@ -118,7 +118,11 @@ const QuizForm: React.FC = () => { setValue(value); } - const linesArray = value.split(/(?<=^|[^\\]}.*)[\n]+/); + // split value when there is at least one blank line + const linesArray = value.split(/\n{2,}/); + + // if the first item in linesArray is blank, remove it + if (linesArray[0] === '') linesArray.shift(); if (linesArray[linesArray.length - 1] === '') linesArray.pop();