put quiz form on its own page

This commit is contained in:
2023-10-18 09:57:11 -06:00
parent c7f9b262da
commit 7413ba8c1b
8 changed files with 153 additions and 80 deletions

View File

@@ -0,0 +1,100 @@
@page "/course/{CourseName}/quiz/{QuizName}"
@using CanvasModel.EnrollmentTerms
@using Management.Web.Shared.Components.AssignmentForm
@using Management.Web.Shared.Course
@using Management.Web.Shared.Module.Assignment.Templates
@using Management.Web.Shared.Semester
@using CanvasModel.Courses
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
@using LocalModels
@using Management.Web.Shared.Module.Assignment
@using Management.Web.Shared.Components
@using Management.Web.Shared.Components.Quiz.Markdown
@inject YamlManager yamlManager
@inject CanvasService canvas
@inject CoursePlanner planner
@inject QuizEditorContext quizContext
@inject ILogger<QuizFormPage> logger
@inject NavigationManager Navigation
@code {
[Parameter]
public string? CourseName { get; set; } = default!;
[Parameter]
public string? QuizName { get; set; } = default!;
private bool loading { get; set; }= true;
protected override async Task OnInitializedAsync()
{
if(loading)
{
loading = false;
logger.LogInformation($"loading quiz {CourseName} {QuizName}");
if(planner.LocalCourse == null)
{
var courses = await yamlManager.LoadSavedCourses();
planner.LocalCourse = courses.First(c => c.Settings.Name == CourseName);
logger.LogInformation($"set course to '{planner.LocalCourse?.Settings.Name}'");
}
if(quizContext.Quiz == null)
{
var quiz = planner
.LocalCourse?
.Modules
.SelectMany(m => m.Quizzes)
.FirstOrDefault(q => q.Name == QuizName);
quizContext.Quiz = quiz;
logger.LogInformation($"set quiz to '{quizContext.Quiz?.Name}'");
}
base.OnInitialized();
StateHasChanged();
}
}
private void deleteQuiz()
{
quizContext.DeleteQuiz();
Navigation.NavigateTo("/course/" + planner.LocalCourse?.Settings.Name);
}
private async Task addToCanvas()
{
await quizContext.AddQuizToCanvas();
}
private void done()
{
quizContext.Quiz = null;
Navigation.NavigateTo("/course/" + planner.LocalCourse?.Settings.Name);
}
}
@if(quizContext.Quiz == null)
{
<Spinner />
}
@if(quizContext.Quiz != null)
{
<MarkdownQuizForm />
}
@if(quizContext.Quiz != null)
{
<div class="row justify-content-end">
<div class="col-auto">
<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="done">
Done
</button>
</div>
</div>
}

View File

@@ -10,21 +10,21 @@
private string? error { get; set; } = null; private string? error { get; set; } = null;
private string _quizMarkdownInput { get; set; } = ""; private string _quizMarkdownInput { get; set; } = "";
private string quizMarkdownInput private string quizMarkdownInput
{ {
get => _quizMarkdownInput; get => _quizMarkdownInput;
set set
{ {
_quizMarkdownInput = value; _quizMarkdownInput = value;
try try
{ {
var newQuiz = LocalQuiz.ParseMarkdown(_quizMarkdownInput); var newQuiz = LocalQuiz.ParseMarkdown(_quizMarkdownInput);
error = null; error = null;
testQuiz = newQuiz; testQuiz = newQuiz;
quizContext.SaveQuiz(newQuiz); quizContext.SaveQuiz(newQuiz);
} }
catch(QuizMarkdownParseException e) catch (QuizMarkdownParseException e)
{ {
error = e.Message; error = e.Message;
StateHasChanged(); StateHasChanged();
@@ -34,17 +34,17 @@
protected override void OnInitialized() protected override void OnInitialized()
{ {
reload();
quizContext.StateHasChanged += reload; quizContext.StateHasChanged += reload;
} }
private void reload() private void reload()
{ {
if (quizContext.Quiz != null) if (quizContext.Quiz != null)
{ {
if(quizMarkdownInput == "") if (quizMarkdownInput == "")
{ {
quizMarkdownInput = quizContext.Quiz.ToMarkdown(); quizMarkdownInput = quizContext.Quiz.ToMarkdown();
} }
modal?.Show();
this.InvokeAsync(this.StateHasChanged); this.InvokeAsync(this.StateHasChanged);
} }
} }
@@ -53,69 +53,33 @@
quizContext.StateHasChanged -= reload; 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 text-truncate">Error: @error</p>
}
<QuizPreview Quiz="testQuiz" />
</div>
</div>
</Body>
<Footer>
<ConfirmationModal Label="Delete" Class="btn btn-danger" OnConfirm="deleteQuiz" />
<div class="row justify-content-between">
<div class="col-auto">
<h2>
@quizContext.Quiz?.Name
</h2>
</div>
<div class="col-auto me-3">
<h3>
Points: @quizContext.Quiz?.Questions.Sum(q => q.Points)
</h3>
</div>
</div>
<button <div class="row">
class="btn btn-outline-secondary" <div class="col-6">
@onclick="addToCanvas" <textarea rows="30" class="form-control" @bind="quizMarkdownInput" @bind:event="oninput" />
> </div>
Add to Canvas <div class="col-6">
</button> @if (error != null)
<button {
class="btn btn-primary" <p class="text-danger text-truncate">Error: @error</p>
@onclick="() => modal?.Hide()" }
> <QuizPreview Quiz="testQuiz" />
Done </div>
</button> </div>
</Footer>
</Modal> <hr>

View File

@@ -40,11 +40,6 @@
planner.StateHasChanged -= reload; planner.StateHasChanged -= reload;
} }
} }
<MarkdownQuizForm />
@* <QuizForm /> *@
<div class="row"> <div class="row">
<div class="col overflow-y-auto border rounded " style="max-height: 95vh;"> <div class="col overflow-y-auto border rounded " style="max-height: 95vh;">
@if (planner.LocalCourse != null) @if (planner.LocalCourse != null)

View File

@@ -148,12 +148,12 @@
<div class="row"> <div class="row">
@foreach (var a in Module.Assignments) @foreach (var a in Module.Assignments)
{ {
<AssignmentDetails Assignment="a" Module="Module" /> <AssignmentListItem Assignment="a" Module="Module" />
} }
<br> <br>
@foreach(var quiz in Module.Quizzes) @foreach(var quiz in Module.Quizzes)
{ {
<QuizDetail Quiz="quiz" /> <QuizListItem Quiz="quiz" />
} }
</div> </div>
</div> </div>

View File

@@ -4,6 +4,7 @@
@inject DragContainer dragContainer @inject DragContainer dragContainer
@inject QuizEditorContext quizContext @inject QuizEditorContext quizContext
@inject CoursePlanner planner @inject CoursePlanner planner
@inject NavigationManager Navigation
@inherits DroppableQuiz @inherits DroppableQuiz
@@ -21,6 +22,13 @@
planner.CanvasQuizzes != null planner.CanvasQuizzes != null
? Quiz.QuizIsCreated(planner.CanvasQuizzes) ? Quiz.QuizIsCreated(planner.CanvasQuizzes)
: false; : false;
private void OnClick()
{
quizContext.Quiz = Quiz;
Navigation.NavigateTo("/course/" + planner.LocalCourse?.Settings.Name + "/quiz/" + Quiz.Name);
}
} }
@@ -29,7 +37,7 @@
draggable="true" draggable="true"
@ondragstart="HandleDragStart" @ondragstart="HandleDragStart"
@ondragend="HandleDragEnd" @ondragend="HandleDragEnd"
@onclick="@(() => quizContext.Quiz = Quiz)" @onclick="OnClick"
role="button" role="button"
> >
<div class="card"> <div class="card">

View File

@@ -2,6 +2,7 @@
@inject DragContainer dragContainer @inject DragContainer dragContainer
@inject CoursePlanner planner @inject CoursePlanner planner
@inject QuizEditorContext quizContext @inject QuizEditorContext quizContext
@inject NavigationManager Navigation
@inherits DroppableQuiz @inherits DroppableQuiz
@@ -16,13 +17,18 @@
{ {
dragContainer.DropCallback = null; dragContainer.DropCallback = null;
} }
private void OnClick()
{
quizContext.Quiz = Quiz;
Navigation.NavigateTo("/course/" + planner.LocalCourse?.Settings.Name + "/quiz/" + Quiz.Name);
}
} }
<li <li
draggable="true" draggable="true"
@ondragstart="HandleDragStart" @ondragstart="HandleDragStart"
@ondragend="HandleDragEnd" @ondragend="HandleDragEnd"
@onclick="@(() => quizContext.Quiz = Quiz)" @onclick="OnClick"
role="button" role="button"
> >
@Quiz.Name @Quiz.Name

View File

@@ -28,7 +28,7 @@ public class QuizEditorContext
get => _quiz; get => _quiz;
set set
{ {
if(_quiz == null) if(_quiz == null && value != null)
{ {
_module = getCurrentModule(value, planner.LocalCourse); _module = getCurrentModule(value, planner.LocalCourse);
} }
@@ -135,10 +135,10 @@ public class QuizEditorContext
logger.Log($"finished adding quiz {Quiz.Name} to canvas"); logger.Log($"finished adding quiz {Quiz.Name} to canvas");
} }
private static LocalModule getCurrentModule(LocalQuiz newQuiz, LocalCourse course) private static LocalModule getCurrentModule(LocalQuiz quiz, LocalCourse course)
{ {
return course.Modules.FirstOrDefault( return course.Modules.FirstOrDefault(
m => m.Quizzes.Select(q => q.Name + q.Description).Contains(newQuiz.Name + newQuiz.Description) m => m.Quizzes.Select(q => q.Name + q.Description).Contains(quiz.Name + quiz.Description)
) )
?? throw new Exception("could not find current module in quiz editor context"); ?? throw new Exception("could not find current module in quiz editor context");
} }