mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-25 23:28:33 -06:00
have basic quiz editor implemented
This commit is contained in:
@@ -35,7 +35,7 @@ this is my description in markdown
|
||||
markdown.Should().Contain("LockAtDueDate: true");
|
||||
markdown.Should().Contain("ShuffleAnswers: true");
|
||||
markdown.Should().Contain("OneQuestionAtATime: false");
|
||||
markdown.Should().Contain("LocalAssignmentGroupName: someId");
|
||||
markdown.Should().Contain("AssignmentGroup: someId");
|
||||
markdown.Should().Contain("AllowedAttempts: -1");
|
||||
}
|
||||
[Test]
|
||||
@@ -70,8 +70,8 @@ lines
|
||||
QuestionType = QuestionType.MULTIPLE_CHOICE,
|
||||
Answers = new LocalQuizQuestionAnswer[]
|
||||
{
|
||||
new LocalQuizQuestionAnswer() { Id = "asdfa", Correct = true, Text = "true" },
|
||||
new LocalQuizQuestionAnswer() { Id = "wef", Correct = false, Text = "false" + Environment.NewLine +Environment.NewLine + "endline" },
|
||||
new LocalQuizQuestionAnswer() { Correct = true, Text = "true" },
|
||||
new LocalQuizQuestionAnswer() { Correct = false, Text = "false" + Environment.NewLine +Environment.NewLine + "endline" },
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,9 +120,9 @@ b) false
|
||||
QuestionType = QuestionType.MULTIPLE_ANSWERS,
|
||||
Answers = new LocalQuizQuestionAnswer[]
|
||||
{
|
||||
new LocalQuizQuestionAnswer() { Id = "asdfsa", Correct = true, Text = "true" },
|
||||
new LocalQuizQuestionAnswer() { Id = "wsef", Correct = true, Text = "false"},
|
||||
new LocalQuizQuestionAnswer() { Id = "ws5ef", Correct = false, Text = "neither"},
|
||||
new LocalQuizQuestionAnswer() { Correct = true, Text = "true" },
|
||||
new LocalQuizQuestionAnswer() { Correct = true, Text = "false"},
|
||||
new LocalQuizQuestionAnswer() { Correct = false, Text = "neither"},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
@using Markdig
|
||||
|
||||
@code {
|
||||
[Parameter, EditorRequired]
|
||||
public LocalQuizQuestion Question { get; set; } = default!;
|
||||
|
||||
}
|
||||
|
||||
@((MarkupString)Question.HtmlText)
|
||||
|
||||
@foreach(var answer in Question.Answers)
|
||||
{
|
||||
|
||||
<div class="mx-3 mb-1 bg-dark px-2 rounded rounded-2 d-flex flex-row border">
|
||||
<div>
|
||||
@if(answer.Correct)
|
||||
{
|
||||
<svg
|
||||
style="width: 1em;"
|
||||
class="me-1"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M4 12.6111L8.92308 17.5L20 6.5"
|
||||
stroke="var(--bs-success)"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div
|
||||
class="me-1"
|
||||
style="width: 1em;"
|
||||
></div>
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
@((MarkupString)answer.HtmlText)
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
@using Management.Web.Shared.Components
|
||||
|
||||
@inject QuizEditorContext quizContext
|
||||
|
||||
|
||||
@code {
|
||||
private Modal? modal { get; set; }
|
||||
|
||||
private LocalQuiz testQuiz;
|
||||
|
||||
private string? error { get; set; } = null;
|
||||
private string _quizMarkdownInput { get; set; } = "";
|
||||
private string quizMarkdownInput
|
||||
{
|
||||
get => _quizMarkdownInput;
|
||||
set
|
||||
{
|
||||
_quizMarkdownInput = value;
|
||||
|
||||
try
|
||||
{
|
||||
var newQuiz = LocalQuiz.ParseMarkdown(_quizMarkdownInput);
|
||||
error = null;
|
||||
testQuiz = newQuiz;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
error = e.Message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
quizContext.StateHasChanged += reload;
|
||||
}
|
||||
private void reload()
|
||||
{
|
||||
if (quizContext.Quiz != null)
|
||||
{
|
||||
Console.WriteLine("reloading quiz editor");
|
||||
|
||||
if(quizMarkdownInput == "")
|
||||
{
|
||||
quizMarkdownInput = quizContext.Quiz.ToMarkdown();
|
||||
}
|
||||
modal?.Show();
|
||||
this.InvokeAsync(this.StateHasChanged);
|
||||
}
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
quizContext.StateHasChanged -= reload;
|
||||
}
|
||||
|
||||
private void deleteQuiz()
|
||||
{
|
||||
quizContext.DeleteQuiz();
|
||||
modal?.Hide();
|
||||
}
|
||||
|
||||
private async Task addToCanvas()
|
||||
{
|
||||
await quizContext.AddQuizToCanvas();
|
||||
}
|
||||
|
||||
private void onHide()
|
||||
{
|
||||
quizMarkdownInput = "";
|
||||
quizContext.Quiz = null;
|
||||
}
|
||||
}
|
||||
|
||||
<Modal @ref="modal" OnHide="onHide" >
|
||||
<Title>
|
||||
<div class="row justify-content-between">
|
||||
<div class="col-auto">
|
||||
@quizContext.Quiz?.Name
|
||||
</div>
|
||||
<div class="col-auto me-3">
|
||||
Points: @quizContext.Quiz?.Questions.Sum(q => q.Points)
|
||||
</div>
|
||||
</div>
|
||||
</Title>
|
||||
<Body>
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<textarea
|
||||
rows="30"
|
||||
class="form-control"
|
||||
@bind="quizMarkdownInput"
|
||||
@bind:event="oninput"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
@if(error != null)
|
||||
{
|
||||
<p class="text-danger">@error</p>
|
||||
}
|
||||
<QuizPreview Quiz="testQuiz" />
|
||||
</div>
|
||||
</div>
|
||||
</Body>
|
||||
<Footer>
|
||||
<ConfirmationModal Label="Delete" Class="btn btn-danger" OnConfirm="deleteQuiz" />
|
||||
|
||||
|
||||
<button
|
||||
class="btn btn-outline-secondary"
|
||||
@onclick="addToCanvas"
|
||||
>
|
||||
Add to Canvas
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
@onclick="() => modal?.Hide()"
|
||||
>
|
||||
Done
|
||||
</button>
|
||||
</Footer>
|
||||
</Modal>
|
||||
@@ -0,0 +1,48 @@
|
||||
@using Management.Web.Shared.Components
|
||||
|
||||
@inject QuizEditorContext quizContext
|
||||
|
||||
|
||||
@code {
|
||||
|
||||
[Parameter, EditorRequired]
|
||||
public LocalQuiz Quiz { get; set; } = default!;
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
quizContext.StateHasChanged += reload;
|
||||
}
|
||||
private void reload()
|
||||
{
|
||||
Console.WriteLine(JsonSerializer.Serialize(quizContext.Quiz));
|
||||
this.InvokeAsync(this.StateHasChanged);
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
quizContext.StateHasChanged -= reload;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@if(Quiz != null)
|
||||
{
|
||||
<div>Name: @Quiz.Name</div>
|
||||
<div>Due At: @Quiz.DueAt</div>
|
||||
<div>Lock At: @Quiz.LockAt</div>
|
||||
<div>Shuffle Answers: @Quiz.ShuffleAnswers</div>
|
||||
<div>Allowed Attempts: @Quiz.AllowedAttempts</div>
|
||||
<div>One question at a time: @Quiz.OneQuestionAtATime</div>
|
||||
<div>Assignment Group: @Quiz.LocalAssignmentGroupName</div>
|
||||
|
||||
<div class="p-3">@Quiz.Description</div>
|
||||
|
||||
@foreach(var question in Quiz.Questions)
|
||||
{
|
||||
|
||||
<div class="bg-dark-subtle mt-1 p-1 rounded rounded-2">
|
||||
<MarkdownQuestionPreview
|
||||
Question="question"
|
||||
@key="question"
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
@using Management.Web.Shared.Semester
|
||||
@using Management.Web.Shared.Components.AssignmentForm
|
||||
@using Management.Web.Shared.Components.Quiz
|
||||
@using Management.Web.Shared.Components.Quiz.Markdown
|
||||
|
||||
@inject CanvasService canvas
|
||||
@inject CoursePlanner planner
|
||||
@@ -40,7 +41,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
<QuizForm />
|
||||
<MarkdownQuizForm />
|
||||
@* <QuizForm /> *@
|
||||
|
||||
<div class="row">
|
||||
<div class="col overflow-y-auto border rounded " style="max-height: 95vh;">
|
||||
|
||||
@@ -49,7 +49,7 @@ LockAt: {LockAt}
|
||||
DueAt: {DueAt}
|
||||
ShuffleAnswers: {ShuffleAnswers.ToString().ToLower()}
|
||||
OneQuestionAtATime: {OneQuestionAtATime.ToString().ToLower()}
|
||||
LocalAssignmentGroupName: {LocalAssignmentGroupName}
|
||||
AssignmentGroup: {LocalAssignmentGroupName}
|
||||
AllowedAttempts: {AllowedAttempts}
|
||||
Description: {Description}
|
||||
---
|
||||
@@ -84,8 +84,8 @@ Description: {Description}
|
||||
var dueAt = DateTime.Parse(extractLabelValue(settings, "DueAt"));
|
||||
var lockAt = DateTime.Parse(extractLabelValue(settings, "LockAt"));
|
||||
var description = extractDescription(settings);
|
||||
var assignmentGroup = extractLabelValue(settings, "AssignmentGroup");
|
||||
|
||||
// var assignmentGroup = ExtractLabelValue(settings, "AssignmentGroup");
|
||||
return new LocalQuiz()
|
||||
{
|
||||
Id = "id-" + name,
|
||||
@@ -96,7 +96,7 @@ Description: {Description}
|
||||
DueAt = dueAt,
|
||||
ShuffleAnswers = shuffleAnswers,
|
||||
OneQuestionAtATime = oneQuestionAtATime,
|
||||
// LocalAssignmentGroupId = "someId",
|
||||
LocalAssignmentGroupName = assignmentGroup,
|
||||
AllowedAttempts = allowedAttempts,
|
||||
Questions = new LocalQuizQuestion[] { }
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@ public record LocalQuizQuestionAnswer
|
||||
public static LocalQuizQuestionAnswer ParseMarkdown(string input)
|
||||
{
|
||||
var isCorrect = input[0] == '*' || input[1] == '*';
|
||||
string startingQuestionPattern = @"^(?:\*[a-z]\))|\[\s*\]|\[\*\] ";
|
||||
string startingQuestionPattern = @"^(\*?[a-z]\))|\[\s*\]|\[\*\] ";
|
||||
var text = Regex.Replace(input, startingQuestionPattern, string.Empty).Trim();
|
||||
|
||||
return new LocalQuizQuestionAnswer()
|
||||
@@ -22,5 +22,4 @@ public record LocalQuizQuestionAnswer
|
||||
Text=text,
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user