mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-25 23:28:33 -06:00
restructured components so that there are more components in the pages
This commit is contained in:
@@ -1,229 +0,0 @@
|
||||
@using Management.Web.Shared.Components
|
||||
@using Management.Web.Shared.Components.Forms
|
||||
@using CanvasModel.Assignments
|
||||
|
||||
@inject CoursePlanner planner
|
||||
@inject CanvasService canvas
|
||||
@inject NavigationManager Navigation
|
||||
@inject AssignmentEditorContext assignmentContext
|
||||
|
||||
@code {
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
assignmentContext.StateHasChanged += reload;
|
||||
reload();
|
||||
}
|
||||
private void reload()
|
||||
{
|
||||
if (assignmentContext.Assignment != null)
|
||||
{
|
||||
name = assignmentContext.Assignment.Name;
|
||||
}
|
||||
this.InvokeAsync(this.StateHasChanged);
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
assignmentContext.StateHasChanged -= reload;
|
||||
}
|
||||
|
||||
private void OnHide()
|
||||
{
|
||||
assignmentContext.Assignment = null;
|
||||
name = "";
|
||||
}
|
||||
private string name { get; set; } = String.Empty;
|
||||
private bool addingAssignmentToCanvas = false;
|
||||
private bool deletingAssignmentFromCanvas = false;
|
||||
private bool showHelp = false;
|
||||
|
||||
private void toggleHelp() => showHelp = !showHelp;
|
||||
|
||||
private void submitHandler()
|
||||
{
|
||||
if (assignmentContext.Assignment != null)
|
||||
{
|
||||
var newAssignment = assignmentContext.Assignment with
|
||||
{
|
||||
Name = name,
|
||||
};
|
||||
|
||||
assignmentContext.SaveAssignment(newAssignment);
|
||||
}
|
||||
assignmentContext.Assignment = null;
|
||||
}
|
||||
|
||||
private async Task HandleDelete()
|
||||
{
|
||||
if (planner.LocalCourse != null && assignmentContext.Assignment != null)
|
||||
{
|
||||
var assignment = assignmentContext.Assignment;
|
||||
|
||||
var currentModule = planner
|
||||
.LocalCourse
|
||||
.Modules
|
||||
.First(m =>
|
||||
m.Assignments.Contains(assignment)
|
||||
) ?? throw new Exception("handling assignment delete, could not find module");
|
||||
|
||||
var newModules = planner.LocalCourse.Modules.Select(m =>
|
||||
m.Name == currentModule.Name
|
||||
? m with
|
||||
{
|
||||
Assignments = m.Assignments.Where(a => a != assignment).ToArray()
|
||||
}
|
||||
: m
|
||||
)
|
||||
.ToArray();
|
||||
|
||||
planner.LocalCourse = planner.LocalCourse with
|
||||
{
|
||||
Modules = newModules
|
||||
};
|
||||
|
||||
if (assignmentInCanvas != null && planner.LocalCourse.Settings.CanvasId != null)
|
||||
{
|
||||
ulong courseId = planner.LocalCourse.Settings.CanvasId ?? throw new Exception("cannot delete if no course id");
|
||||
await canvas.Assignments.Delete(courseId, assignmentInCanvas.Id, assignment.Name);
|
||||
}
|
||||
Navigation.NavigateTo("/course/" + planner.LocalCourse?.Settings.Name);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleNameChange(ChangeEventArgs e)
|
||||
{
|
||||
if (assignmentContext.Assignment != null)
|
||||
{
|
||||
var newAssignment = assignmentContext.Assignment with { Name = e.Value?.ToString() ?? "" };
|
||||
assignmentContext.SaveAssignment(newAssignment);
|
||||
}
|
||||
}
|
||||
|
||||
private void setAssignmentGroup(LocalAssignmentGroup? group)
|
||||
{
|
||||
if (assignmentContext.Assignment == null)
|
||||
return;
|
||||
|
||||
var newAssignment = assignmentContext.Assignment with
|
||||
{
|
||||
LocalAssignmentGroupName = group?.Name
|
||||
};
|
||||
|
||||
assignmentContext.SaveAssignment(newAssignment);
|
||||
}
|
||||
|
||||
private LocalAssignmentGroup? selectedAssignmentGroup =>
|
||||
planner
|
||||
.LocalCourse?
|
||||
.Settings
|
||||
.AssignmentGroups
|
||||
.FirstOrDefault(g => g.Name == assignmentContext.Assignment?.LocalAssignmentGroupName);
|
||||
|
||||
private async Task addToCanvas()
|
||||
{
|
||||
addingAssignmentToCanvas = true;
|
||||
await assignmentContext.AddAssignmentToCanvas();
|
||||
await planner.LoadCanvasData();
|
||||
addingAssignmentToCanvas = false;
|
||||
}
|
||||
private async Task updateInCanvas()
|
||||
{
|
||||
if(assignmentInCanvas != null)
|
||||
{
|
||||
addingAssignmentToCanvas = true;
|
||||
await assignmentContext.UpdateInCanvas(assignmentInCanvas.Id);
|
||||
await planner.LoadCanvasData();
|
||||
addingAssignmentToCanvas = false;
|
||||
}
|
||||
}
|
||||
|
||||
private CanvasAssignment? assignmentInCanvas =>
|
||||
planner.CanvasAssignments?.FirstOrDefault(a => a.Name == assignmentContext.Assignment?.Name);
|
||||
|
||||
private string canvasAssignmentUrl =>
|
||||
$"https://snow.instructure.com/courses/{planner.LocalCourse?.Settings.CanvasId}/assignments/{assignmentInCanvas?.Id}";
|
||||
|
||||
private async Task deleteFromCanvas()
|
||||
{
|
||||
if (assignmentInCanvas == null
|
||||
|| planner?.LocalCourse?.Settings.CanvasId == null
|
||||
|| assignmentContext.Assignment == null
|
||||
)
|
||||
return;
|
||||
|
||||
deletingAssignmentFromCanvas = true;
|
||||
await canvas.Assignments.Delete(
|
||||
(ulong)planner.LocalCourse.Settings.CanvasId,
|
||||
assignmentInCanvas.Id,
|
||||
assignmentContext.Assignment.Name
|
||||
);
|
||||
await planner.LoadCanvasData();
|
||||
deletingAssignmentFromCanvas = false;
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
<div class="d-flex flex-column p-2 h-100 w-100" style="height: 100%;" >
|
||||
<div>
|
||||
@assignmentContext.Assignment?.Name
|
||||
</div>
|
||||
|
||||
<section class="flex-grow-1 p-1 border rounded-4 bg-dark-subtle" style="min-height: 0;">
|
||||
@if (assignmentContext.Assignment != null)
|
||||
{
|
||||
<AssignmentMarkdownEditor ShowHelp=@showHelp />
|
||||
}
|
||||
</section>
|
||||
|
||||
<div class="d-flex justify-content-end p-3">
|
||||
@if (addingAssignmentToCanvas || deletingAssignmentFromCanvas)
|
||||
{
|
||||
<div>
|
||||
<Spinner />
|
||||
</div>
|
||||
}
|
||||
|
||||
<button class="btn btn-outline-secondary mx-3" @onclick=toggleHelp>
|
||||
Toggle Help
|
||||
</button>
|
||||
<ConfirmationModal Label="Delete" Class="btn btn-danger" OnConfirmAsync="HandleDelete" />
|
||||
<button
|
||||
class="btn btn-outline-secondary mx-3"
|
||||
disabled="@(addingAssignmentToCanvas || deletingAssignmentFromCanvas)"
|
||||
@onclick="addToCanvas"
|
||||
>
|
||||
Add To Canvas
|
||||
</button>
|
||||
@if (assignmentInCanvas != null)
|
||||
{
|
||||
<a
|
||||
class="btn btn-outline-secondary me-1"
|
||||
href="@canvasAssignmentUrl"
|
||||
target="_blank"
|
||||
disabled="@(addingAssignmentToCanvas || deletingAssignmentFromCanvas)"
|
||||
>
|
||||
View in Canvas
|
||||
</a>
|
||||
<button
|
||||
class="btn btn-outline-secondary mx-3"
|
||||
disabled="@(addingAssignmentToCanvas || deletingAssignmentFromCanvas)"
|
||||
@onclick="updateInCanvas"
|
||||
>
|
||||
Update In Canvas
|
||||
</button>
|
||||
<ConfirmationModal
|
||||
Disabled="@(addingAssignmentToCanvas || deletingAssignmentFromCanvas)"
|
||||
Label="Delete from Canvas"
|
||||
Class="btn btn-outline-danger mx-3"
|
||||
OnConfirmAsync="deleteFromCanvas"
|
||||
/>
|
||||
}
|
||||
<button class="btn btn-primary mx-2" @onclick="@(() => {
|
||||
assignmentContext.Assignment = null;
|
||||
Navigation.NavigateTo("/course/" + planner.LocalCourse?.Settings.Name);
|
||||
})">
|
||||
Done
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
@@ -1,124 +0,0 @@
|
||||
@using Markdig
|
||||
@using Shared.Components.AssignmentForm
|
||||
|
||||
@inject CoursePlanner planner
|
||||
@inject AssignmentEditorContext assignmentContext
|
||||
|
||||
@code
|
||||
{
|
||||
[Parameter, EditorRequired]
|
||||
public bool ShowHelp { get; set; } = false;
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
assignmentContext.StateHasChanged += reload;
|
||||
reload();
|
||||
}
|
||||
private void reload()
|
||||
{
|
||||
if (assignmentContext.Assignment != null)
|
||||
{
|
||||
if(rawText == string.Empty)
|
||||
{
|
||||
rawText = assignmentContext.Assignment.ToMarkdown();
|
||||
this.InvokeAsync(this.StateHasChanged);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
assignmentContext.StateHasChanged -= reload;
|
||||
}
|
||||
|
||||
private string rawText { get; set; } = string.Empty;
|
||||
private string? error = null;
|
||||
public bool? UseTemplate { get; set; } = null;
|
||||
|
||||
public string? TemplateId { get; set; }
|
||||
|
||||
private void handleChange(string newRawAssignment)
|
||||
{
|
||||
rawText = newRawAssignment;
|
||||
if (newRawAssignment != string.Empty)
|
||||
{
|
||||
try
|
||||
{
|
||||
var parsed = LocalAssignment.ParseMarkdown(newRawAssignment);
|
||||
error = null;
|
||||
assignmentContext.SaveAssignment(parsed);
|
||||
}
|
||||
catch(AssignmentMarkdownParseException e)
|
||||
{
|
||||
error = e.Message;
|
||||
}
|
||||
catch(RubricMarkdownParseException e)
|
||||
{
|
||||
error = e.Message;
|
||||
}
|
||||
finally
|
||||
{
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private MarkupString preview { get => (MarkupString)Markdown.ToHtml(assignmentContext?.Assignment?.Description ?? ""); }
|
||||
private string HelpText()
|
||||
{
|
||||
var groupNames = string.Join("\n- " , planner.LocalCourse?.Settings.AssignmentGroups.Select(g => g.Name) ?? []);
|
||||
return $@"
|
||||
SubmissionTypes:
|
||||
- {AssignmentSubmissionType.ONLINE_TEXT_ENTRY}
|
||||
- {AssignmentSubmissionType.ONLINE_UPLOAD}
|
||||
- {AssignmentSubmissionType.DISCUSSION_TOPIC}
|
||||
|
||||
Assignment Group Names:
|
||||
- {groupNames}
|
||||
";
|
||||
}
|
||||
}
|
||||
|
||||
<div class="d-flex w-100 h-100 flex-row">
|
||||
@if(ShowHelp)
|
||||
{
|
||||
<div class=" rounded rounded-3 bg-black" >
|
||||
<pre class=" me-3 pe-5 ps-3 rounded rounded-3">
|
||||
@HelpText()
|
||||
</pre>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if(assignmentContext.Assignment != null && planner.LocalCourse != null)
|
||||
{
|
||||
<div class="row h-100 w-100">
|
||||
<div class="col-6">
|
||||
|
||||
<MonacoTextArea Value=@rawText OnChange=@handleChange />
|
||||
</div>
|
||||
<div class="col-6 overflow-y-auto h-100" >
|
||||
@if (error != null)
|
||||
{
|
||||
<p class="text-danger text-truncate">Error: @error</p>
|
||||
}
|
||||
|
||||
|
||||
<div>Due At: @assignmentContext.Assignment.DueAt</div>
|
||||
<div>Lock At: @assignmentContext.Assignment.LockAt</div>
|
||||
<div>Assignment Group Name @assignmentContext.Assignment.LocalAssignmentGroupName</div>
|
||||
<div>Submission Types</div>
|
||||
<ul>
|
||||
@foreach(var t in assignmentContext.Assignment.SubmissionTypes)
|
||||
{
|
||||
<li>@t</li>
|
||||
}
|
||||
</ul>
|
||||
<hr>
|
||||
<div>
|
||||
@(preview)
|
||||
</div>
|
||||
<hr>
|
||||
<RubricDisplay />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@@ -1,61 +0,0 @@
|
||||
@using Management.Web.Shared.Components
|
||||
|
||||
@inject CoursePlanner planner
|
||||
@inject AssignmentEditorContext assignmentContext
|
||||
|
||||
@code
|
||||
{
|
||||
private string? error { get; set; } = null;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
assignmentContext.StateHasChanged += reload;
|
||||
reload();
|
||||
}
|
||||
private void reload()
|
||||
{
|
||||
this.InvokeAsync(this.StateHasChanged);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
assignmentContext.StateHasChanged -= reload;
|
||||
}
|
||||
|
||||
private int requiredPoints => assignmentContext?.Assignment?.Rubric.Where(r => !r.IsExtraCredit).Select(r => r.Points).Sum() ?? 0;
|
||||
private int extraCreditPoints => assignmentContext?.Assignment?.Rubric.Where(r => r.IsExtraCredit).Select(r => r.Points).Sum() ?? 0;
|
||||
}
|
||||
|
||||
@if(assignmentContext != null)
|
||||
{
|
||||
<div class="row">
|
||||
<h4 class="text-center">Rubric</h4>
|
||||
</div>
|
||||
|
||||
@if (error != null)
|
||||
{
|
||||
<p class="text-danger text-truncate">Error: @error</p>
|
||||
}
|
||||
|
||||
<div class="row border-bottom">
|
||||
<div class="col-6 text-end">Label</div>
|
||||
<div class="col-3 text-center">Points</div>
|
||||
<div class="col-3 text-center">Extra Credit</div>
|
||||
</div>
|
||||
@foreach (var item in assignmentContext?.Assignment?.Rubric ?? [])
|
||||
{
|
||||
<div class="row border-bottom">
|
||||
<div class="col-6 text-end">@item.Label</div>
|
||||
<div class="col-3 text-center">@item.Points</div>
|
||||
<div class="col-3 text-center">@item.IsExtraCredit</div>
|
||||
</div>
|
||||
}
|
||||
<div class="text-end">
|
||||
<div>
|
||||
Required Points: @requiredPoints
|
||||
</div>
|
||||
<div>
|
||||
Extra Credit Points @extraCreditPoints
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
@using System.Reflection
|
||||
@inject AssignmentEditorContext assignmentContext
|
||||
|
||||
@code
|
||||
{
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
assignmentContext.StateHasChanged += reload;
|
||||
reload();
|
||||
}
|
||||
private void reload()
|
||||
{
|
||||
if (assignmentContext.Assignment != null)
|
||||
{
|
||||
types = assignmentContext.Assignment.SubmissionTypes;
|
||||
|
||||
}
|
||||
this.InvokeAsync(this.StateHasChanged);
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
assignmentContext.StateHasChanged -= reload;
|
||||
}
|
||||
private IEnumerable<string> types { get; set; } = Enumerable.Empty<string>();
|
||||
|
||||
private string getLabel(string type)
|
||||
{
|
||||
return type.ToString().Replace("_", "") + "switch";
|
||||
}
|
||||
|
||||
private bool discussionIsSelected
|
||||
{
|
||||
get => types.FirstOrDefault(
|
||||
t => t == AssignmentSubmissionType.DISCUSSION_TOPIC
|
||||
) != null;
|
||||
}
|
||||
private void saveTypes(IEnumerable<string> newTypes)
|
||||
{
|
||||
if(assignmentContext.Assignment != null)
|
||||
{
|
||||
types = newTypes;
|
||||
assignmentContext.SaveAssignment(assignmentContext.Assignment with
|
||||
{
|
||||
SubmissionTypes = types
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
<h5>Submission Types</h5>
|
||||
<div class="row" @key="types">
|
||||
|
||||
@foreach (var submissionType in AssignmentSubmissionType.AllTypes)
|
||||
{
|
||||
var isDiscussion = submissionType == AssignmentSubmissionType.DISCUSSION_TOPIC;
|
||||
var allowedToBeChecked = !discussionIsSelected || isDiscussion;
|
||||
|
||||
<div class="col-3">
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
role="switch"
|
||||
id="@getLabel(submissionType)"
|
||||
checked="@(types.Contains(submissionType) && allowedToBeChecked)"
|
||||
@onchange="(e) => {
|
||||
var isChecked = (bool)(e.Value ?? false);
|
||||
if(isChecked)
|
||||
saveTypes(types.Append(submissionType));
|
||||
else
|
||||
saveTypes(types.Where(t => t != submissionType));
|
||||
}"
|
||||
disabled="@(discussionIsSelected && !isDiscussion)"
|
||||
>
|
||||
<label
|
||||
class="form-check-label"
|
||||
for="@getLabel(submissionType)"
|
||||
>
|
||||
@submissionType
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@@ -1,82 +0,0 @@
|
||||
@using Markdig
|
||||
|
||||
@code {
|
||||
[Parameter, EditorRequired]
|
||||
public LocalQuizQuestion Question { get; set; } = default!;
|
||||
|
||||
}
|
||||
|
||||
<div class="row justify-content-between text-secondary">
|
||||
<div class="col">
|
||||
points: @Question.Points
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
@Question.QuestionType
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@((MarkupString)Question.HtmlText)
|
||||
|
||||
@if(Question.QuestionType == QuestionType.MATCHING)
|
||||
{
|
||||
@foreach(var answer in Question.Answers)
|
||||
{
|
||||
<div class="mx-3 mb-1 bg-dark px-2 rounded rounded-2 border row">
|
||||
<div
|
||||
class="col text-end my-auto p-1"
|
||||
>
|
||||
@answer.Text
|
||||
</div>
|
||||
<div
|
||||
class="col my-auto"
|
||||
>
|
||||
@answer.MatchedText
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@foreach(var answer in Question.Answers)
|
||||
{
|
||||
string answerPreview = answer.HtmlText.StartsWith("<p>")
|
||||
? answer.HtmlText.Replace("<p>", "<p class='m-0'>")
|
||||
: answer.HtmlText;
|
||||
|
||||
<div class="mx-3 mb-1 bg-dark px-2 rounded rounded-2 d-flex flex-row border">
|
||||
@if(answer.Correct)
|
||||
{
|
||||
<svg
|
||||
style="width: 1em;"
|
||||
class="me-1 my-auto"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M4 12.6111L8.92308 17.5L20 6.5"
|
||||
stroke="var(--bs-success)"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div
|
||||
class="me-1 my-auto"
|
||||
style="width: 1em;"
|
||||
>
|
||||
@if(Question.QuestionType == QuestionType.MULTIPLE_ANSWERS)
|
||||
{
|
||||
<span>[ ]</span>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<div class="markdownQuizAnswerPreview p-1">
|
||||
@((MarkupString)answerPreview)
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
@using Management.Web.Shared.Components
|
||||
|
||||
@inject QuizEditorContext quizContext
|
||||
|
||||
@code {
|
||||
private Modal? modal { get; set; }
|
||||
|
||||
private LocalQuiz? testQuiz;
|
||||
|
||||
private string? error { get; set; } = null;
|
||||
private string _quizMarkdownInput { get; set; } = "";
|
||||
private string quizMarkdownInput
|
||||
{
|
||||
get => _quizMarkdownInput;
|
||||
set
|
||||
{
|
||||
_quizMarkdownInput = value;
|
||||
|
||||
try
|
||||
{
|
||||
var newQuiz = LocalQuiz.ParseMarkdown(_quizMarkdownInput);
|
||||
error = null;
|
||||
testQuiz = newQuiz;
|
||||
quizContext.SaveQuiz(newQuiz);
|
||||
}
|
||||
catch (QuizMarkdownParseException e)
|
||||
{
|
||||
error = e.Message;
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
reload();
|
||||
quizContext.StateHasChanged += reload;
|
||||
}
|
||||
private void reload()
|
||||
{
|
||||
if (quizContext.Quiz != null)
|
||||
{
|
||||
if (quizMarkdownInput == "")
|
||||
{
|
||||
quizMarkdownInput = quizContext.Quiz.ToMarkdown();
|
||||
}
|
||||
this.InvokeAsync(this.StateHasChanged);
|
||||
}
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
quizContext.StateHasChanged -= reload;
|
||||
}
|
||||
}
|
||||
|
||||
<div class="d-flex flex-column h-100">
|
||||
<div class="d-flex flex-row h-100 p-2">
|
||||
<div class="row flex-grow-1">
|
||||
<div class="col-6">
|
||||
<MonacoTextArea
|
||||
Value="@quizMarkdownInput"
|
||||
OnChange="@((v) => quizMarkdownInput = v)"
|
||||
/>
|
||||
|
||||
</div>
|
||||
<div class="col-6 h-100 overflow-y-auto">
|
||||
@if (error != null)
|
||||
{
|
||||
<p class="text-danger text-truncate">Error: @error</p>
|
||||
}
|
||||
@if(testQuiz != null)
|
||||
{
|
||||
<QuizPreview Quiz="testQuiz" />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -1,72 +0,0 @@
|
||||
@using Management.Web.Shared.Components
|
||||
|
||||
@inject QuizEditorContext quizContext
|
||||
|
||||
|
||||
@code {
|
||||
|
||||
[Parameter, EditorRequired]
|
||||
public LocalQuiz Quiz { get; set; } = default!;
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
quizContext.StateHasChanged += reload;
|
||||
}
|
||||
private void reload()
|
||||
{
|
||||
this.InvokeAsync(this.StateHasChanged);
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
quizContext.StateHasChanged -= reload;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@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>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6 text-end">Due At: </div>
|
||||
<div class="col-6">@Quiz.DueAt</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6 text-end">Lock At: </div>
|
||||
<div class="col-6">@Quiz.LockAt</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6 text-end">Shuffle Answers: </div>
|
||||
<div class="col-6">@Quiz.ShuffleAnswers</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6 text-end">Allowed Attempts: </div>
|
||||
<div class="col-6">@Quiz.AllowedAttempts</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6 text-end">One question at a time: </div>
|
||||
<div class="col-6">@Quiz.OneQuestionAtATime</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<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>
|
||||
|
||||
@foreach(var question in Quiz.Questions)
|
||||
{
|
||||
|
||||
<div class="bg-dark-subtle mt-1 p-1 ps-2 rounded rounded-2">
|
||||
<MarkdownQuestionPreview
|
||||
Question="question"
|
||||
@key="question"
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user