major layout changes for quizzes

This commit is contained in:
2023-10-18 11:26:34 -06:00
parent 7413ba8c1b
commit b39fd9f223
7 changed files with 241 additions and 80 deletions

View File

@@ -1,6 +1,7 @@
@page "/course/{CourseName}/quiz/{QuizName}"
@using CanvasModel.EnrollmentTerms
@using CanvasModel.Quizzes
@using Management.Web.Shared.Components.AssignmentForm
@using Management.Web.Shared.Course
@using Management.Web.Shared.Module.Assignment.Templates
@@ -26,6 +27,7 @@
public string? QuizName { get; set; } = default!;
private bool loading { get; set; }= true;
private bool addingQuizToCanvas = false;
protected override async Task OnInitializedAsync()
{
@@ -51,6 +53,13 @@
quizContext.Quiz = quiz;
logger.LogInformation($"set quiz to '{quizContext.Quiz?.Name}'");
}
StateHasChanged();
if(planner.CanvasQuizzes == null)
{
await planner.LoadCanvasData();
}
base.OnInitialized();
StateHasChanged();
}
@@ -64,37 +73,116 @@
private async Task addToCanvas()
{
addingQuizToCanvas = true;
await quizContext.AddQuizToCanvas();
await planner.LoadCanvasData();
addingQuizToCanvas = false;
}
private void done()
{
quizContext.Quiz = null;
Navigation.NavigateTo("/course/" + planner.LocalCourse?.Settings.Name);
}
private CanvasQuiz? quizInCanvas => planner.CanvasQuizzes?.FirstOrDefault(q => q.Title == quizContext.Quiz?.Name);
private string canvasQuizUrl => $"https://snow.instructure.com/courses/{planner.LocalCourse?.Settings.CanvasId}/quizzes/{quizInCanvas?.Id}";
}
@if(quizContext.Quiz == null)
{
<div class="d-flex flex-column py-3" style="height: 100vh;">
<section>
<div class="row justify-content-between">
<div class="col-auto my-auto">
<h2>
@quizContext.Quiz?.Name
</h2>
</div>
@if(quizContext.Quiz == null)
{
<div class="col-auto">
<Spinner />
}
</div>
}
<div class="col-auto me-3">
<h3>
Points: @quizContext.Quiz?.Questions.Sum(q => q.Points)
</h3>
@if(quizInCanvas != null)
{
@if(quizInCanvas?.Published == true)
{
<div class="text-success">
Published!
</div>
}
else
{
<div class="text-danger">
Not Published
</div>
}
}
</div>
</div>
</section>
@if(quizContext.Quiz != null)
{
<section
class="flex-grow-1 w-100 d-flex justify-content-center overflow-y-auto overflow-x-hidden border rounded-4 bg-dark-subtle py-3 px-1"
style="min-height: 10%;max-width: 100%;"
>
<div class="w-100" style="max-width: 120em; max-height: 100%;">
@if(quizContext.Quiz != null)
{
<MarkdownQuizForm />
}
}
</div>
</section>
@if(quizContext.Quiz != null)
{
<hr>
<section>
@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">
<ConfirmationModal
Label="Delete"
Class="btn btn-danger"
OnConfirm="deleteQuiz"
Disabled="@addingQuizToCanvas"
/>
<button
class="btn btn-outline-secondary me-1"
@onclick="addToCanvas"
disabled="@addingQuizToCanvas"
>
Add to Canvas
</button>
<button class="btn btn-primary" @onclick="done">
@if(quizInCanvas != null)
{
<a
class="btn btn-outline-secondary me-1"
href="@canvasQuizUrl"
target="_blank"
>
View in Canvas
</a>
}
<button
class="btn btn-primary"
@onclick="done"
disabled="@addingQuizToCanvas"
>
Done
</button>
</div>
</div>
}
}
@if(addingQuizToCanvas)
{
<Spinner />
}
</section>
</div>

View File

@@ -15,6 +15,8 @@
[Parameter]
[EditorRequired]
public string Class { get; set; } = "";
[Parameter]
public bool Disabled { get; set; } = false;
private Modal? modal { get; set; } = null;
@@ -49,6 +51,7 @@
<button
class="btn btn-danger"
@onclick="() => modal?.Show()"
disabled="@Disabled"
>
@Label
</button>
@@ -60,12 +63,14 @@
<button
class="btn btn-secondary"
@onclick="HandleDeny"
disabled="@Disabled"
>
no
</button>
<button
class="btn btn-primary"
@onclick="HandleConfirm"
disabled="@Disabled"
>
yes
</button>

View File

@@ -2,13 +2,13 @@
@inject QuizEditorContext quizContext
@code {
private Modal? modal { get; set; }
private LocalQuiz testQuiz;
private string? error { get; set; } = null;
private bool showHelp = false;
private string _quizMarkdownInput { get; set; } = "";
private string quizMarkdownInput
{
@@ -53,25 +53,51 @@
quizContext.StateHasChanged -= reload;
}
private readonly static string exampleMarkdownQuestion = @"HELP
---
Points: 2
this is a question?
*a) correct
b) not correct
---
points: 1
question goes here
[*] correct
[ ] not correct
[] not correct
---
the points default to 1?
*a) true
b) false
---
Markdown is supported
- like
- this
- list
[*] true
[ ] false
";
}
<div class="d-flex flex-column h-100">
<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>
<div class="row">
<div class="d-flex flex-row flex-grow-1">
@if(showHelp)
{
<pre class="bg-dark-subtle me-3 pe-5 ps-3 rounded rounded-3">
@exampleMarkdownQuestion
</pre>
}
<div class="row flex-grow-1">
<div class="col-6">
<textarea rows="30" class="form-control" @bind="quizMarkdownInput" @bind:event="oninput" />
<textarea
class="form-control h-100"
@bind="quizMarkdownInput"
@bind:event="oninput"
/>
</div>
<div class="col-6">
@if (error != null)
@@ -80,6 +106,15 @@
}
<QuizPreview Quiz="testQuiz" />
</div>
</div>
</div>
</div>
<hr>
<div>
<button
class="btn btn-outline-secondary mt-3"
@onclick="@(() => showHelp = !showHelp)"
>
toggle help
</button>
</div>
</div>

View File

@@ -24,7 +24,8 @@
@if(Quiz != null)
{
<div class="row justify-content-start">
<div class="col-auto" style="min-width: 35em;">
<div class="row">
<div class="col-6 text-end">Name: </div>
<div class="col-6">@Quiz.Name</div>
@@ -53,6 +54,8 @@
<div class="col-6 text-end">Assignment Group: </div>
<div class="col-6">@Quiz.LocalAssignmentGroupName</div>
</div>
</div>
</div>
<div class="p-3" style="white-space: pre-wrap;">@Quiz.Description</div>

View File

@@ -13,7 +13,7 @@
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
</div> *@
<article class="content px-4">
<article class="content px-4 py-0">
@Body
</article>
</main>

View File

@@ -1,6 +1,6 @@
@import url("open-iconic/font/css/open-iconic-bootstrap.min.css");
html,
/* html,
body {
font-family: "DM Sans", sans-serif;
}
@@ -42,7 +42,7 @@ a,
.validation-message {
color: red;
}
} */
#blazor-error-ui {
background: lightyellow;
@@ -89,3 +89,33 @@ a,
.decorationContentClass {
background: lightblue;
} */
/* scroll bar */
/* width */
::-webkit-scrollbar {
width: 8px;
}
/* Track */
::-webkit-scrollbar-track {
/* box-shadow: inset 0 0 5px grey; */
border-radius: 8px;
}
/* Handle */
::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, 0.6);
border-radius: 8px;
border-style: solid;
border-color: rgba(255, 255, 255, 0.3);
border-width: 1px;
/* outline-offset: 2px; */
}
/* Handle on hover */
::-webkit-scrollbar-thumb:hover {
background: rgb(31, 31, 31);
}

View File

@@ -20,8 +20,8 @@ public class CanvasServiceUtils
if (response.ErrorMessage?.Length > 0)
{
System.Console.WriteLine("error in response");
System.Console.WriteLine(response.ErrorMessage);
Console.WriteLine("error in response");
Console.WriteLine(response.ErrorMessage);
throw new Exception("error in response");
}
@@ -39,7 +39,7 @@ public class CanvasServiceUtils
}
if (requestCount > 1)
System.Console.WriteLine($"Requesting {typeof(T)} took {requestCount} requests");
Console.WriteLine($"Requesting {typeof(T)} took {requestCount} requests");
return returnData;
}