mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-25 23:28:33 -06:00
put quiz form on its own page
This commit is contained in:
100
Management.Web/Pages/QuizFormPage.razor
Normal file
100
Management.Web/Pages/QuizFormPage.razor
Normal 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>
|
||||
}
|
||||
@@ -10,21 +10,21 @@
|
||||
|
||||
private string? error { get; set; } = null;
|
||||
private string _quizMarkdownInput { get; set; } = "";
|
||||
private string quizMarkdownInput
|
||||
{
|
||||
private string quizMarkdownInput
|
||||
{
|
||||
get => _quizMarkdownInput;
|
||||
set
|
||||
{
|
||||
_quizMarkdownInput = value;
|
||||
|
||||
try
|
||||
try
|
||||
{
|
||||
var newQuiz = LocalQuiz.ParseMarkdown(_quizMarkdownInput);
|
||||
error = null;
|
||||
testQuiz = newQuiz;
|
||||
quizContext.SaveQuiz(newQuiz);
|
||||
}
|
||||
catch(QuizMarkdownParseException e)
|
||||
catch (QuizMarkdownParseException e)
|
||||
{
|
||||
error = e.Message;
|
||||
StateHasChanged();
|
||||
@@ -34,17 +34,17 @@
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
reload();
|
||||
quizContext.StateHasChanged += reload;
|
||||
}
|
||||
private void reload()
|
||||
{
|
||||
if (quizContext.Quiz != null)
|
||||
{
|
||||
if(quizMarkdownInput == "")
|
||||
if (quizMarkdownInput == "")
|
||||
{
|
||||
quizMarkdownInput = quizContext.Quiz.ToMarkdown();
|
||||
}
|
||||
modal?.Show();
|
||||
this.InvokeAsync(this.StateHasChanged);
|
||||
}
|
||||
}
|
||||
@@ -53,69 +53,33 @@
|
||||
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
|
||||
class="btn btn-outline-secondary"
|
||||
@onclick="addToCanvas"
|
||||
>
|
||||
Add to Canvas
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
@onclick="() => modal?.Hide()"
|
||||
>
|
||||
Done
|
||||
</button>
|
||||
</Footer>
|
||||
</Modal>
|
||||
<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>
|
||||
|
||||
<hr>
|
||||
|
||||
@@ -40,11 +40,6 @@
|
||||
planner.StateHasChanged -= reload;
|
||||
}
|
||||
}
|
||||
|
||||
<MarkdownQuizForm />
|
||||
|
||||
@* <QuizForm /> *@
|
||||
|
||||
<div class="row">
|
||||
<div class="col overflow-y-auto border rounded " style="max-height: 95vh;">
|
||||
@if (planner.LocalCourse != null)
|
||||
|
||||
@@ -148,12 +148,12 @@
|
||||
<div class="row">
|
||||
@foreach (var a in Module.Assignments)
|
||||
{
|
||||
<AssignmentDetails Assignment="a" Module="Module" />
|
||||
<AssignmentListItem Assignment="a" Module="Module" />
|
||||
}
|
||||
<br>
|
||||
@foreach(var quiz in Module.Quizzes)
|
||||
{
|
||||
<QuizDetail Quiz="quiz" />
|
||||
<QuizListItem Quiz="quiz" />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
@inject DragContainer dragContainer
|
||||
@inject QuizEditorContext quizContext
|
||||
@inject CoursePlanner planner
|
||||
@inject NavigationManager Navigation
|
||||
|
||||
@inherits DroppableQuiz
|
||||
|
||||
@@ -21,6 +22,13 @@
|
||||
planner.CanvasQuizzes != null
|
||||
? Quiz.QuizIsCreated(planner.CanvasQuizzes)
|
||||
: false;
|
||||
|
||||
|
||||
private void OnClick()
|
||||
{
|
||||
quizContext.Quiz = Quiz;
|
||||
Navigation.NavigateTo("/course/" + planner.LocalCourse?.Settings.Name + "/quiz/" + Quiz.Name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +37,7 @@
|
||||
draggable="true"
|
||||
@ondragstart="HandleDragStart"
|
||||
@ondragend="HandleDragEnd"
|
||||
@onclick="@(() => quizContext.Quiz = Quiz)"
|
||||
@onclick="OnClick"
|
||||
role="button"
|
||||
>
|
||||
<div class="card">
|
||||
@@ -2,6 +2,7 @@
|
||||
@inject DragContainer dragContainer
|
||||
@inject CoursePlanner planner
|
||||
@inject QuizEditorContext quizContext
|
||||
@inject NavigationManager Navigation
|
||||
|
||||
@inherits DroppableQuiz
|
||||
|
||||
@@ -16,13 +17,18 @@
|
||||
{
|
||||
dragContainer.DropCallback = null;
|
||||
}
|
||||
private void OnClick()
|
||||
{
|
||||
quizContext.Quiz = Quiz;
|
||||
Navigation.NavigateTo("/course/" + planner.LocalCourse?.Settings.Name + "/quiz/" + Quiz.Name);
|
||||
}
|
||||
}
|
||||
|
||||
<li
|
||||
draggable="true"
|
||||
@ondragstart="HandleDragStart"
|
||||
@ondragend="HandleDragEnd"
|
||||
@onclick="@(() => quizContext.Quiz = Quiz)"
|
||||
@onclick="OnClick"
|
||||
role="button"
|
||||
>
|
||||
@Quiz.Name
|
||||
|
||||
@@ -28,7 +28,7 @@ public class QuizEditorContext
|
||||
get => _quiz;
|
||||
set
|
||||
{
|
||||
if(_quiz == null)
|
||||
if(_quiz == null && value != null)
|
||||
{
|
||||
_module = getCurrentModule(value, planner.LocalCourse);
|
||||
}
|
||||
@@ -135,10 +135,10 @@ public class QuizEditorContext
|
||||
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(
|
||||
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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user