use monaco editor for quizzes

This commit is contained in:
2023-11-09 15:15:22 -07:00
parent ea6271428a
commit 4a113fc8ca
11 changed files with 87 additions and 26 deletions

View File

@@ -5,20 +5,31 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="~/" /> <base href="~/" />
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script> integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"
integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz"
crossorigin="anonymous"></script>
<link href="css/site.css" rel="stylesheet" /> <link href="css/site.css" rel="stylesheet" />
<link href="Management.Web.styles.css" rel="stylesheet" /> <link href="Management.Web.styles.css" rel="stylesheet" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=DM+Mono:wght@400;500&family=Kanit&family=Mukta&family=Roboto&family=Sofia+Sans+Condensed:wght@400;500&display=swap"
rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,600&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,600&display=swap" rel="stylesheet">
<link rel="icon" type="image/png" href="favicon.png"/> <link rel="icon" type="image/png" href="favicon.png" />
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" /> <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
</head> </head>
<body data-bs-theme="dark"> <body data-bs-theme="dark">
<component type="typeof(App)" render-mode="ServerPrerendered" /> <component type="typeof(App)" render-mode="ServerPrerendered" />
@@ -38,4 +49,5 @@
<script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.js"></script> <script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.js"></script>
<script src="_framework/blazor.server.js"></script> <script src="_framework/blazor.server.js"></script>
</body> </body>
</html> </html>

View File

@@ -124,7 +124,7 @@
var newAssignment = assignmentContext.Assignment with var newAssignment = assignmentContext.Assignment with
{ {
LocalAssignmentGroupId = group?.Id LocalAssignmentGroupName = group?.Name
}; };
assignmentContext.SaveAssignment(newAssignment); assignmentContext.SaveAssignment(newAssignment);
@@ -135,7 +135,7 @@
.LocalCourse? .LocalCourse?
.Settings .Settings
.AssignmentGroups .AssignmentGroups
.FirstOrDefault(g => g.Id == assignmentContext.Assignment?.LocalAssignmentGroupId); .FirstOrDefault(g => g.Name == assignmentContext.Assignment?.LocalAssignmentGroupName);
private async Task addToCanvas() private async Task addToCanvas()
{ {

View File

@@ -0,0 +1,46 @@
@using BlazorMonaco
@using BlazorMonaco.Editor
@code {
[Parameter, EditorRequired]
public string Value { get; set; }
[Parameter, EditorRequired]
public Action<string> OnChange { get; set; }
private StandaloneCodeEditor _editor = null!;
private StandaloneEditorConstructionOptions EditorConstructionOptions(StandaloneCodeEditor editor)
{
return new StandaloneEditorConstructionOptions
{
Language = "markdown",
Theme = "vs-dark",
TabSize = 2,
Value = Value,
Minimap = new EditorMinimapOptions { Enabled = false },
LineNumbers = "off",
LineDecorationsWidth = 0,
WordWrap = "on",
AutomaticLayout = true,
FontFamily = "DM Mono, monospace",
FontSize = 16,
};
}
private async Task OnDidChangeModelContent()
{
var newValue = await _editor.GetValue();
OnChange(newValue);
}
}
<StandaloneCodeEditor
@ref="_editor"
Id="sample-code-editor-123"
ConstructionOptions="EditorConstructionOptions"
OnDidChangeModelContent="OnDidChangeModelContent"
/>

View File

@@ -15,6 +15,7 @@
get => _quizMarkdownInput; get => _quizMarkdownInput;
set set
{ {
Console.WriteLine("setting");
_quizMarkdownInput = value; _quizMarkdownInput = value;
try try
@@ -102,11 +103,16 @@ short answer";
} }
<div class="row flex-grow-1"> <div class="row flex-grow-1">
<div class="col-6"> <div class="col-6">
<textarea @* <textarea
class="form-control h-100" class="form-control h-100"
@bind="quizMarkdownInput" @bind="quizMarkdownInput"
@bind:event="oninput" @bind:event="oninput"
/> *@
<MonacoTextArea
Value="@quizMarkdownInput"
OnChange="@((v) => quizMarkdownInput = v)"
/> />
</div> </div>
<div class="col-6"> <div class="col-6">
@if (error != null) @if (error != null)

View File

@@ -141,7 +141,7 @@
if(!isSyncedWithCanvas) if(!isSyncedWithCanvas)
{ {
<button <button
class="btn btn-outline-primary" class="btn btn-outline-primarycanvasCourseId"
@onclick="Publish" @onclick="Publish"
disabled="@publishing" disabled="@publishing"
> >

View File

@@ -28,7 +28,7 @@
LockAt = null, LockAt = null,
DueAt = DateTime.Now, DueAt = DateTime.Now,
SubmissionTypes = new string[] { SubmissionType.ONLINE_TEXT_ENTRY }, SubmissionTypes = new string[] { SubmissionType.ONLINE_TEXT_ENTRY },
LocalAssignmentGroupId = selectedAssignmentGroup?.Id, LocalAssignmentGroupName = selectedAssignmentGroup?.Name,
}; };
if(planner.LocalCourse != null) if(planner.LocalCourse != null)

View File

@@ -16,11 +16,9 @@
{ {
var newModule = new LocalModule var newModule = new LocalModule
{ {
Name=Name, Name=Name
Id=Guid.NewGuid().ToString()
}; };
planner.LocalCourse = planner.LocalCourse with planner.LocalCourse = planner.LocalCourse with
{ {
Modules = planner.LocalCourse.Modules.Append(newModule) Modules = planner.LocalCourse.Modules.Append(newModule)

View File

@@ -26,8 +26,9 @@
Name = Name Name = Name
}; };
// Module is the not renamed version
var newModules = planner.LocalCourse.Modules.Select( var newModules = planner.LocalCourse.Modules.Select(
m => m.Id == Module.Id m => m.Name == Module.Name
? newModule ? newModule
: m : m
).ToArray(); ).ToArray();

View File

@@ -49,7 +49,7 @@ public record LocalAssignment
public IEnumerable<RubricItem> Rubric { get; init; } = Array.Empty<RubricItem>(); public IEnumerable<RubricItem> Rubric { get; init; } = Array.Empty<RubricItem>();
public DateTime? LockAt { get; init; } public DateTime? LockAt { get; init; }
public DateTime DueAt { get; init; } public DateTime DueAt { get; init; }
public string? LocalAssignmentGroupId { get; init; } public string? LocalAssignmentGroupName { get; init; }
public int PointsPossible => Rubric.Sum(r => r.IsExtraCredit ? 0 : r.Points); public int PointsPossible => Rubric.Sum(r => r.IsExtraCredit ? 0 : r.Points);
public IEnumerable<string> SubmissionTypes { get; init; } = Array.Empty<string>(); public IEnumerable<string> SubmissionTypes { get; init; } = Array.Empty<string>();
@@ -74,7 +74,7 @@ public record LocalAssignment
public ulong? GetCanvasAssignmentGroupId(IEnumerable<LocalAssignmentGroup> assignmentGroups) => public ulong? GetCanvasAssignmentGroupId(IEnumerable<LocalAssignmentGroup> assignmentGroups) =>
assignmentGroups assignmentGroups
.FirstOrDefault(g => g.Id == LocalAssignmentGroupId)? .FirstOrDefault(g => g.Name == LocalAssignmentGroupName)?
.CanvasId; .CanvasId;

View File

@@ -3,8 +3,6 @@ namespace LocalModels;
public record LocalModule public record LocalModule
{ {
public string Name { get; init; } = string.Empty; public string Name { get; init; } = string.Empty;
public string Id { get; init; } = DateTime.UtcNow.Ticks.ToString();
// public ulong? CanvasId { get; set; } = null;
public string Notes { get; set; } = string.Empty; public string Notes { get; set; } = string.Empty;
public IEnumerable<LocalAssignment> Assignments { get; init; } = public IEnumerable<LocalAssignment> Assignments { get; init; } =
Enumerable.Empty<LocalAssignment>(); Enumerable.Empty<LocalAssignment>();

View File

@@ -36,7 +36,7 @@ public record LocalQuiz
public string ToMarkdown() public string ToMarkdown()
{ {
var questionMarkdownArray = Questions.Select(q => q.ToMarkdown()).ToArray(); var questionMarkdownArray = Questions.Select(q => q.ToMarkdown()).ToArray();
var questionDelimiter = Environment.NewLine + "---" + Environment.NewLine; var questionDelimiter = Environment.NewLine + Environment.NewLine + "---" + Environment.NewLine + Environment.NewLine;
var questionMarkdown = string.Join(questionDelimiter, questionMarkdownArray); var questionMarkdown = string.Join(questionDelimiter, questionMarkdownArray);
return $@"Name: {Name} return $@"Name: {Name}