mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-25 23:28:33 -06:00
working with quiz editor
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="BlazorMonaco" Version="3.0.0" />
|
||||||
<PackageReference Include="dotenv.net" Version="3.1.2" />
|
<PackageReference Include="dotenv.net" Version="3.1.2" />
|
||||||
<PackageReference Include="Markdig" Version="0.31.0" />
|
<PackageReference Include="Markdig" Version="0.31.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -111,3 +111,6 @@
|
|||||||
<CourseDetails />
|
<CourseDetails />
|
||||||
}
|
}
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
|
||||||
|
@* <MonacoEditorDemo /> *@
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
<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">
|
||||||
@@ -33,6 +34,9 @@
|
|||||||
<a class="dismiss">🗙</a>
|
<a class="dismiss">🗙</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script src="_content/BlazorMonaco/jsInterop.js"></script>
|
||||||
|
<script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/loader.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>
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ if (canvas_url == null)
|
|||||||
builder.Services.AddRazorPages();
|
builder.Services.AddRazorPages();
|
||||||
builder.Services.AddServerSideBlazor();
|
builder.Services.AddServerSideBlazor();
|
||||||
|
|
||||||
|
|
||||||
builder.Services.AddScoped<IWebRequestor, WebRequestor>();
|
builder.Services.AddScoped<IWebRequestor, WebRequestor>();
|
||||||
builder.Services.AddScoped<CanvasServiceUtils>();
|
builder.Services.AddScoped<CanvasServiceUtils>();
|
||||||
builder.Services.AddScoped<CanvasAssignmentService>();
|
builder.Services.AddScoped<CanvasAssignmentService>();
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
if (assignmentContext.Assignment != null)
|
if (assignmentContext.Assignment != null)
|
||||||
{
|
{
|
||||||
Description = assignmentContext.Assignment.Description;
|
Description = assignmentContext.Assignment.Description;
|
||||||
Preview = Markdown.ToHtml(Description);
|
|
||||||
TemplateId = assignmentContext.Assignment.TemplateId;
|
TemplateId = assignmentContext.Assignment.TemplateId;
|
||||||
UseTemplate = TemplateId != null && TemplateId != "";
|
UseTemplate = TemplateId != null && TemplateId != "";
|
||||||
VariableValues = assignmentContext.Assignment.TemplateVariables;
|
VariableValues = assignmentContext.Assignment.TemplateVariables;
|
||||||
@@ -27,7 +26,26 @@
|
|||||||
assignmentContext.StateHasChanged -= reload;
|
assignmentContext.StateHasChanged -= reload;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Description { get; set; } = default!;
|
private string description { get; set; } = default!;
|
||||||
|
public string Description
|
||||||
|
{
|
||||||
|
get => description;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
description = value;
|
||||||
|
if (description != string.Empty)
|
||||||
|
{
|
||||||
|
if(assignmentContext.Assignment != null)
|
||||||
|
{
|
||||||
|
var newAssignment = assignmentContext.Assignment with
|
||||||
|
{
|
||||||
|
Description = description
|
||||||
|
};
|
||||||
|
assignmentContext.SaveAssignment(newAssignment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
public bool? UseTemplate { get; set; } = null;
|
public bool? UseTemplate { get; set; } = null;
|
||||||
|
|
||||||
public string? TemplateId { get; set; }
|
public string? TemplateId { get; set; }
|
||||||
@@ -40,18 +58,9 @@
|
|||||||
.AssignmentTemplates
|
.AssignmentTemplates
|
||||||
.FirstOrDefault(t => t.Id == TemplateId);
|
.FirstOrDefault(t => t.Id == TemplateId);
|
||||||
|
|
||||||
public string Preview { get; set; } = String.Empty;
|
|
||||||
|
|
||||||
private void saveDescription(ChangeEventArgs e)
|
private void saveDescription(ChangeEventArgs e)
|
||||||
{
|
{
|
||||||
if(assignmentContext.Assignment != null)
|
|
||||||
{
|
|
||||||
var newAssignment = assignmentContext.Assignment with
|
|
||||||
{
|
|
||||||
Description = e.Value?.ToString() ?? ""
|
|
||||||
};
|
|
||||||
assignmentContext.SaveAssignment(newAssignment);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveTemplateId(ChangeEventArgs e)
|
private void saveTemplateId(ChangeEventArgs e)
|
||||||
@@ -67,6 +76,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MarkupString preview { get => (MarkupString) Markdown.ToHtml(Description); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +147,6 @@
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -159,11 +168,11 @@
|
|||||||
class="form-control"
|
class="form-control"
|
||||||
rows=12
|
rows=12
|
||||||
@bind="Description"
|
@bind="Description"
|
||||||
@oninput="saveDescription"
|
@bind:event="oninput"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col" @key="Description">
|
||||||
@((MarkupString)Preview)
|
@(preview)
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,6 +82,7 @@
|
|||||||
await canvas.Assignments.Delete(courseId, assignment);
|
await canvas.Assignments.Delete(courseId, assignment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
AssignmentModal?.Hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleNameChange(ChangeEventArgs e)
|
private void handleNameChange(ChangeEventArgs e)
|
||||||
|
|||||||
84
Management.Web/Shared/Components/MonacoEditorDemo.razor
Normal file
84
Management.Web/Shared/Components/MonacoEditorDemo.razor
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
|
||||||
|
@using BlazorMonaco
|
||||||
|
@using BlazorMonaco.Editor
|
||||||
|
|
||||||
|
<h3>Code Editor</h3>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div style="margin:10px 0;">
|
||||||
|
New Value: <input type="text" @bind="_valueToSet" style="width: 400px;" /> <button @onclick="SetValue">Set Value</button>
|
||||||
|
</div>
|
||||||
|
<div style="margin:10px 0;">
|
||||||
|
<button @onclick="GetValue">Get Value</button>
|
||||||
|
</div>
|
||||||
|
<div style="margin:10px 0;">
|
||||||
|
See the console for results.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style="height: 300px"
|
||||||
|
>
|
||||||
|
<StandaloneCodeEditor
|
||||||
|
@ref="_editor"
|
||||||
|
Id="sample-code-editor-123"
|
||||||
|
ConstructionOptions="EditorConstructionOptions"
|
||||||
|
OnDidInit="EditorOnDidInit"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private StandaloneCodeEditor _editor = null!;
|
||||||
|
private string _valueToSet = "";
|
||||||
|
|
||||||
|
private StandaloneEditorConstructionOptions EditorConstructionOptions(StandaloneCodeEditor editor)
|
||||||
|
{
|
||||||
|
return new StandaloneEditorConstructionOptions
|
||||||
|
{
|
||||||
|
Language = "markdown",
|
||||||
|
Theme = "vs-dark",
|
||||||
|
TabSize = 2,
|
||||||
|
Value = "this is the default \n value",
|
||||||
|
Minimap = new EditorMinimapOptions { Enabled = false }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task EditorOnDidInit()
|
||||||
|
{
|
||||||
|
await _editor.AddCommand((int)KeyMod.CtrlCmd | (int)KeyCode.KeyH, (args) =>
|
||||||
|
{
|
||||||
|
Console.WriteLine("Ctrl+H : Initial editor command is triggered.");
|
||||||
|
});
|
||||||
|
|
||||||
|
var newDecorations = new ModelDeltaDecoration[]
|
||||||
|
{
|
||||||
|
new ModelDeltaDecoration
|
||||||
|
{
|
||||||
|
Range = new BlazorMonaco.Range(3,1,3,1),
|
||||||
|
Options = new ModelDecorationOptions
|
||||||
|
{
|
||||||
|
IsWholeLine = true,
|
||||||
|
ClassName = "decorationContentClass",
|
||||||
|
GlyphMarginClassName = "decorationGlyphMarginClass"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
decorationIds = await _editor.DeltaDecorations(null, newDecorations);
|
||||||
|
// You can now use 'decorationIds' to change or remove the decorations
|
||||||
|
}
|
||||||
|
|
||||||
|
private string[] decorationIds = new string[0];
|
||||||
|
|
||||||
|
private async Task SetValue()
|
||||||
|
{
|
||||||
|
Console.WriteLine($"setting value to: {_valueToSet}");
|
||||||
|
await _editor.SetValue(_valueToSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task GetValue()
|
||||||
|
{
|
||||||
|
var val = await _editor.GetValue();
|
||||||
|
Console.WriteLine($"value is: {val}");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,6 +26,12 @@
|
|||||||
quizContext.StateHasChanged -= reload;
|
quizContext.StateHasChanged -= reload;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void deleteQuiz()
|
||||||
|
{
|
||||||
|
quizContext.DeleteQuiz();
|
||||||
|
modal?.Hide();
|
||||||
|
}
|
||||||
|
|
||||||
private void addQuestion()
|
private void addQuestion()
|
||||||
{
|
{
|
||||||
if(quizContext.Quiz != null)
|
if(quizContext.Quiz != null)
|
||||||
@@ -149,6 +155,8 @@
|
|||||||
}
|
}
|
||||||
</Body>
|
</Body>
|
||||||
<Footer>
|
<Footer>
|
||||||
|
<ConfirmationModal Label="Delete" Class="btn btn-danger" OnConfirm="deleteQuiz" />
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="btn btn-primary"
|
class="btn btn-primary"
|
||||||
@onclick="() => modal?.Hide()"
|
@onclick="() => modal?.Hide()"
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
@using Management.Web.Shared.Components.Quiz
|
@using Management.Web.Shared.Components.Quiz
|
||||||
@using Management.Web.Shared.Module.Assignment
|
@using Management.Web.Shared.Module.Assignment
|
||||||
@using LocalModels
|
@using LocalModels
|
||||||
|
@using BlazorMonaco
|
||||||
|
@using BlazorMonaco.Editor
|
||||||
|
|
||||||
@inject CoursePlanner configurationManagement
|
@inject CoursePlanner configurationManagement
|
||||||
@inject CoursePlanner planner
|
@inject CoursePlanner planner
|
||||||
@@ -12,13 +14,44 @@
|
|||||||
[Parameter, EditorRequired]
|
[Parameter, EditorRequired]
|
||||||
public LocalModule Module { get; set; } = default!;
|
public LocalModule Module { get; set; } = default!;
|
||||||
private bool dragging {get; set;} = false;
|
private bool dragging {get; set;} = false;
|
||||||
|
private string _notes { get; set; } = "";
|
||||||
|
private string notes
|
||||||
|
{
|
||||||
|
get => _notes;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if(value != _notes)
|
||||||
|
{
|
||||||
|
_notes = value;
|
||||||
|
if(planner.LocalCourse != null)
|
||||||
|
{
|
||||||
|
var newModule = Module with { Notes = _notes };
|
||||||
|
var newModules = planner.LocalCourse.Modules.Select(
|
||||||
|
m => m.Name == newModule.Name
|
||||||
|
? newModule
|
||||||
|
: m
|
||||||
|
);
|
||||||
|
planner.LocalCourse = planner.LocalCourse with
|
||||||
|
{
|
||||||
|
Modules = newModules
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
|
if(_notes == string.Empty)
|
||||||
|
{
|
||||||
|
_notes = Module.Notes;
|
||||||
|
}
|
||||||
planner.StateHasChanged += reload;
|
planner.StateHasChanged += reload;
|
||||||
}
|
}
|
||||||
private void reload()
|
private void reload()
|
||||||
{
|
{
|
||||||
|
|
||||||
this.InvokeAsync(this.StateHasChanged);
|
this.InvokeAsync(this.StateHasChanged);
|
||||||
}
|
}
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
@@ -89,9 +122,14 @@
|
|||||||
id="@accordionId"
|
id="@accordionId"
|
||||||
class="accordion-collapse collapse"
|
class="accordion-collapse collapse"
|
||||||
>
|
>
|
||||||
@* data-bs-parent="#modulesAccordion" include to limit expanded sections *@
|
|
||||||
<div class="accordion-body pt-1">
|
<div class="accordion-body pt-1">
|
||||||
|
@* <textarea
|
||||||
|
class="form-control"
|
||||||
|
@bind="notes"
|
||||||
|
@bind:event="oninput"
|
||||||
|
placeholder="notes for the module"
|
||||||
|
rows="6"
|
||||||
|
/> *@
|
||||||
<div class="row m-1">
|
<div class="row m-1">
|
||||||
<div class="col my-auto">
|
<div class="col my-auto">
|
||||||
<h5>Assignments</h5>
|
<h5>Assignments</h5>
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');
|
@import url("open-iconic/font/css/open-iconic-bootstrap.min.css");
|
||||||
|
|
||||||
html, body {
|
html,
|
||||||
font-family: 'DM Sans', sans-serif;
|
body {
|
||||||
|
font-family: "DM Sans", sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1:focus {
|
h1:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
a, .btn-link {
|
a,
|
||||||
|
.btn-link {
|
||||||
color: #0071c1;
|
color: #0071c1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,7 +20,11 @@ a, .btn-link {
|
|||||||
border-color: #1861ac;
|
border-color: #1861ac;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
|
.btn:focus,
|
||||||
|
.btn:active:focus,
|
||||||
|
.btn-link.nav-link:focus,
|
||||||
|
.form-control:focus,
|
||||||
|
.form-check-input:focus {
|
||||||
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
|
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,7 +32,7 @@ a, .btn-link {
|
|||||||
padding-top: 1.1rem;
|
padding-top: 1.1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.valid.modified:not([type=checkbox]) {
|
.valid.modified:not([type="checkbox"]) {
|
||||||
outline: 1px solid #26b050;
|
outline: 1px solid #26b050;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,19 +56,36 @@ a, .btn-link {
|
|||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
#blazor-error-ui .dismiss {
|
#blazor-error-ui .dismiss {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0.75rem;
|
right: 0.75rem;
|
||||||
top: 0.5rem;
|
top: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blazor-error-boundary {
|
.blazor-error-boundary {
|
||||||
background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
|
background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=)
|
||||||
|
no-repeat 1rem/1.8rem,
|
||||||
|
#b32121;
|
||||||
padding: 1rem 1rem 1rem 3.7rem;
|
padding: 1rem 1rem 1rem 3.7rem;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blazor-error-boundary::after {
|
.blazor-error-boundary::after {
|
||||||
content: "An error has occurred."
|
content: "An error has occurred.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.monaco-editor-container {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
/* .minimap {
|
||||||
|
display: none;
|
||||||
|
} */
|
||||||
|
|
||||||
|
/* .decorationGlyphMarginClass {
|
||||||
|
background: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.decorationContentClass {
|
||||||
|
background: lightblue;
|
||||||
|
} */
|
||||||
|
|||||||
@@ -26,9 +26,7 @@ public class QuizEditorContext
|
|||||||
{
|
{
|
||||||
if (planner.LocalCourse != null)
|
if (planner.LocalCourse != null)
|
||||||
{
|
{
|
||||||
var currentModule =
|
var currentModule = getCurrentModule(newQuiz, planner.LocalCourse);
|
||||||
planner.LocalCourse.Modules.First(m => m.Quizzes.Select(q => q.Id).Contains(newQuiz.Id))
|
|
||||||
?? throw new Exception("could not find current module in quiz editor context");
|
|
||||||
|
|
||||||
var updatedModules = planner.LocalCourse.Modules
|
var updatedModules = planner.LocalCourse.Modules
|
||||||
.Select(
|
.Select(
|
||||||
@@ -48,4 +46,25 @@ public class QuizEditorContext
|
|||||||
Quiz = newQuiz;
|
Quiz = newQuiz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void DeleteQuiz()
|
||||||
|
{
|
||||||
|
if (planner.LocalCourse != null && Quiz != null)
|
||||||
|
{
|
||||||
|
var currentModule = getCurrentModule(Quiz, planner.LocalCourse);
|
||||||
|
|
||||||
|
var updatedModules = planner.LocalCourse.Modules
|
||||||
|
.Where(m => m.Name != currentModule.Name)
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
planner.LocalCourse = planner.LocalCourse with { Modules = updatedModules };
|
||||||
|
Quiz = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LocalModule getCurrentModule(LocalQuiz newQuiz, LocalCourse course)
|
||||||
|
{
|
||||||
|
return course.Modules.First(m => m.Quizzes.Select(q => q.Id).Contains(newQuiz.Id))
|
||||||
|
?? throw new Exception("could not find current module in quiz editor context");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,4 +9,5 @@ public record LocalModule
|
|||||||
public IEnumerable<LocalQuiz> Quizzes { get; init; } = Enumerable.Empty<LocalQuiz>();
|
public IEnumerable<LocalQuiz> Quizzes { get; init; } = Enumerable.Empty<LocalQuiz>();
|
||||||
|
|
||||||
public ulong? CanvasId { get; set; } = null;
|
public ulong? CanvasId { get; set; } = null;
|
||||||
|
public string Notes { get; set; } = string.Empty;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user