adding buttons to manage assignments from canvas

This commit is contained in:
2023-10-24 16:32:12 -06:00
parent 860c387c8d
commit b831d47d91
12 changed files with 215 additions and 107 deletions

View File

@@ -165,8 +165,12 @@
{ {
<div class="row justify-content-end"> <div class="row justify-content-end">
<div class="col-auto"> <div class="col-auto">
<ConfirmationModal Label="Delete" Class="btn btn-danger" OnConfirm="deleteQuiz" <ConfirmationModal
Disabled="@addingQuizToCanvas" /> Label="Delete"
Class="btn btn-danger"
OnConfirm="deleteQuiz"
Disabled="@addingQuizToCanvas"
/>
<button class="btn btn-outline-secondary me-1" @onclick="addToCanvas" disabled="@addingQuizToCanvas"> <button class="btn btn-outline-secondary me-1" @onclick="addToCanvas" disabled="@addingQuizToCanvas">
Add to Canvas Add to Canvas
</button> </button>

View File

@@ -1,6 +1,7 @@
@using Management.Web.Shared.Components @using Management.Web.Shared.Components
@using Management.Web.Shared.Components.AssignmentForm @using Management.Web.Shared.Components.AssignmentForm
@using Management.Web.Shared.Components.Forms @using Management.Web.Shared.Components.Forms
@using CanvasModel.Assignments
@inject CoursePlanner planner @inject CoursePlanner planner
@inject CanvasService canvas @inject CanvasService canvas
@@ -36,6 +37,9 @@
private string name { get; set; } = String.Empty; private string name { get; set; } = String.Empty;
private bool lockAtDueDate { get; set; } private bool lockAtDueDate { get; set; }
private bool addingAssignmentToCanvas = false;
private bool deletingAssignmentFromCanvas = false;
private void submitHandler() private void submitHandler()
{ {
if (assignmentContext.Assignment != null) if (assignmentContext.Assignment != null)
@@ -71,16 +75,18 @@
Assignments = m.Assignments.Where(a => a != assignment).ToArray() Assignments = m.Assignments.Where(a => a != assignment).ToArray()
} }
: m : m
).ToArray(); )
.ToArray();
planner.LocalCourse = planner.LocalCourse with planner.LocalCourse = planner.LocalCourse with
{ {
Modules = newModules Modules = newModules
}; };
if (assignment.CanvasId != null && planner.LocalCourse.Settings.CanvasId != null)
if (assignmentInCanvas != null && planner.LocalCourse.Settings.CanvasId != null)
{ {
ulong courseId = planner.LocalCourse.Settings.CanvasId ?? throw new Exception("cannot delete if no course id"); ulong courseId = planner.LocalCourse.Settings.CanvasId ?? throw new Exception("cannot delete if no course id");
await canvas.Assignments.Delete(courseId, assignment); await canvas.Assignments.Delete(courseId, assignmentInCanvas.Id, assignment.Name);
} }
} }
} }
@@ -102,7 +108,8 @@
var lockAtDate = lockAtDueDate var lockAtDate = lockAtDueDate
? assignmentContext.Assignment.DueAt ? assignmentContext.Assignment.DueAt
: assignmentContext.Assignment.LockAt; : assignmentContext.Assignment.LockAt;
var newAssignment = assignmentContext.Assignment with { var newAssignment = assignmentContext.Assignment with
{
LockAtDueDate = lockAtDueDate, LockAtDueDate = lockAtDueDate,
LockAt = lockAtDate, LockAt = lockAtDate,
}; };
@@ -112,7 +119,7 @@
private void setAssignmentGroup(LocalAssignmentGroup? group) private void setAssignmentGroup(LocalAssignmentGroup? group)
{ {
if(assignmentContext.Assignment == null) if (assignmentContext.Assignment == null)
return; return;
var newAssignment = assignmentContext.Assignment with var newAssignment = assignmentContext.Assignment with
@@ -129,6 +136,34 @@
.Settings .Settings
.AssignmentGroups .AssignmentGroups
.FirstOrDefault(g => g.Id == assignmentContext.Assignment?.LocalAssignmentGroupId); .FirstOrDefault(g => g.Id == assignmentContext.Assignment?.LocalAssignmentGroupId);
private async Task addToCanvas()
{
addingAssignmentToCanvas = true;
await assignmentContext.AddAssignmentToCanvas();
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();
StateHasChanged();
deletingAssignmentFromCanvas = false;
}
} }
@assignmentContext.Assignment?.Name @assignmentContext.Assignment?.Name
@@ -139,12 +174,8 @@
<label class="form-label"> <label class="form-label">
Name Name
</label> </label>
<input <input class="form-control" @bind="name" @oninput="handleNameChange" />
class="form-control" </div>
@bind="name"
@oninput="handleNameChange"
/>
</div>
<ButtonSelect <ButtonSelect
Label="Assignment Group" Label="Assignment Group"
Options="planner.LocalCourse?.Settings.AssignmentGroups" Options="planner.LocalCourse?.Settings.AssignmentGroups"
@@ -157,17 +188,9 @@
</div> </div>
<div class="form-check m-1"> <div class="form-check m-1">
<input <input class="form-check-input" id="lockAtDueDate" type="checkbox" @bind="lockAtDueDate"
class="form-check-input" @oninput="handleLockAtDueDateChange" />
id="lockAtDueDate" <label class="form-check-label" for="lockAtDueDate">
type="checkbox"
@bind="lockAtDueDate"
@oninput="handleLockAtDueDateChange"
/>
<label
class="form-check-label"
for="lockAtDueDate"
>
Lock At Due Date Lock At Due Date
</label> </label>
</div> </div>
@@ -185,16 +208,41 @@
<ConfirmationModal Label="Delete" Class="btn btn-danger" OnConfirmAsync="HandleDelete" /> <ConfirmationModal Label="Delete" Class="btn btn-danger" OnConfirmAsync="HandleDelete" />
<button <button
class="btn btn-primary mx-2" class="btn btn-outline-secondary mx-3"
@onclick="@(() => { 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>
<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; assignmentContext.Assignment = null;
Navigation.NavigateTo("/course/" + planner.LocalCourse?.Settings.Name); Navigation.NavigateTo("/course/" + planner.LocalCourse?.Settings.Name);
})" })">
>
Done Done
</button> </button>
</div> </div>
@if (addingAssignmentToCanvas || deletingAssignmentFromCanvas)
{
<Spinner />
}
<br> <br>
<br> <br>
<br> <br>

View File

@@ -29,14 +29,9 @@
{ {
if (assignmentContext.Assignment != null) if (assignmentContext.Assignment != null)
{ {
var totalRubricPoints = rubric
.Where(r => !r.Label.Contains(RubricItem.extraCredit))
.Select(s => s.Points)
.Sum();
var newAssignment = assignmentContext.Assignment with var newAssignment = assignmentContext.Assignment with
{ {
Rubric = rubric, Rubric = rubric,
PointsPossible = totalRubricPoints,
}; };
assignmentContext.SaveAssignment(newAssignment); assignmentContext.SaveAssignment(newAssignment);
StateHasChanged(); StateHasChanged();

View File

@@ -49,7 +49,7 @@
} }
<button <button
class="btn btn-danger" class="@(Class != "" ? Class : "btn btn-danger ")"
@onclick="() => modal?.Show()" @onclick="() => modal?.Show()"
disabled="@Disabled" disabled="@Disabled"
> >

View File

@@ -27,7 +27,6 @@
Rubric = new RubricItem[] { }, Rubric = new RubricItem[] { },
LockAt = null, LockAt = null,
DueAt = DateTime.Now, DueAt = DateTime.Now,
PointsPossible = 10,
SubmissionTypes = new string[] { SubmissionType.ONLINE_TEXT_ENTRY }, SubmissionTypes = new string[] { SubmissionType.ONLINE_TEXT_ENTRY },
LocalAssignmentGroupId = selectedAssignmentGroup?.Id, LocalAssignmentGroupId = selectedAssignmentGroup?.Id,
}; };

View File

@@ -1,17 +1,29 @@
using LocalModels; using LocalModels;
using Management.Planner; using Management.Planner;
using Management.Services;
using Management.Services.Canvas;
public class AssignmentEditorContext public class AssignmentEditorContext
{ {
public event Action? StateHasChanged; public event Action? StateHasChanged;
public CanvasService canvas { get; }
private CoursePlanner planner { get; } private CoursePlanner planner { get; }
public AssignmentEditorContext(CoursePlanner planner) public AssignmentEditorContext(
MyLogger<AssignmentEditorContext> logger,
CanvasService canvas,
CoursePlanner planner
)
{ {
this.logger = logger;
this.canvas = canvas;
this.planner = planner; this.planner = planner;
} }
private LocalAssignment? _assignment; private LocalAssignment? _assignment;
private readonly MyLogger<AssignmentEditorContext> logger;
public LocalAssignment? Assignment public LocalAssignment? Assignment
{ {
get => _assignment; get => _assignment;
@@ -50,4 +62,72 @@ public class AssignmentEditorContext
planner.LocalCourse = planner.LocalCourse with { Modules = updatedModules }; planner.LocalCourse = planner.LocalCourse with { Modules = updatedModules };
} }
} }
public async Task AddAssignmentToCanvas()
{
logger.Log("started to add assignment to canvas");
if (Assignment == null)
{
logger.Log("cannot add null assignment to canvas");
return;
}
await planner.LoadCanvasData();
if (planner.CanvasAssignments == null)
{
logger.Log("cannot add assignment to canvas, failed to retrieve current assignments");
return;
}
if (planner.LocalCourse == null)
{
logger.Log("cannot add assignment to canvas, no course stored in planner");
return;
}
var courseCanvasId = planner.LocalCourse.Settings.CanvasId;
if (courseCanvasId == null)
{
logger.Log("cannot add assignment to canvas if there is no course canvas id");
return;
}
var createdAssignment = await planner.LocalCourse.SyncAssignmentToCanvas(
canvasCourseId: (ulong)courseCanvasId,
localAssignment: Assignment,
canvasAssignments: planner.CanvasAssignments,
canvas: canvas
);
var currentModule = getCurrentModule(Assignment, planner.LocalCourse);
if (currentModule.CanvasId == null)
{
logger.Log("was able to add assignment to canvas, but errored while making module item. module canvasId is null");
return;
}
await canvas.CreateModuleItem(
(ulong)courseCanvasId,
(ulong)currentModule.CanvasId,
Assignment.Name,
"Assignment",
(ulong)createdAssignment.CanvasId
);
await planner.LocalCourse.Modules.First().SortModuleItems(
(ulong)courseCanvasId,
(ulong)currentModule.CanvasId,
canvas
);
logger.Log($"finished adding assignment {Assignment.Name} to canvas");
}
private static LocalModule getCurrentModule(LocalAssignment assignment, LocalCourse course)
{
return course.Modules.FirstOrDefault(
m => m.Assignments.Contains(assignment)
)
?? throw new Exception("could not find current module in assignment editor context");
}
} }

View File

@@ -6,7 +6,9 @@ using Management.Services.Canvas;
public class QuizEditorContext public class QuizEditorContext
{ {
public QuizEditorContext(CoursePlanner planner, CanvasService canvas, public QuizEditorContext(
CoursePlanner planner,
CanvasService canvas,
MyLogger<CanvasAssignmentService> logger) MyLogger<CanvasAssignmentService> logger)
{ {
this.planner = planner; this.planner = planner;
@@ -28,7 +30,7 @@ public class QuizEditorContext
get => _quiz; get => _quiz;
set set
{ {
if(_quiz == null && value != null) if (_quiz == null && value != null)
{ {
_module = getCurrentModule(value, planner.LocalCourse); _module = getCurrentModule(value, planner.LocalCourse);
} }
@@ -70,7 +72,8 @@ public class QuizEditorContext
var updatedModules = planner.LocalCourse.Modules var updatedModules = planner.LocalCourse.Modules
.Select(m => m.Name != _module.Name .Select(m => m.Name != _module.Name
? m ? m
: m with { : m with
{
Quizzes = m.Quizzes.Where(q => q.Name + q.Description != Quiz.Name + Quiz.Description).ToArray() Quizzes = m.Quizzes.Where(q => q.Name + q.Description != Quiz.Name + Quiz.Description).ToArray()
} }
) )
@@ -85,18 +88,18 @@ public class QuizEditorContext
public async Task AddQuizToCanvas() public async Task AddQuizToCanvas()
{ {
logger.Log("started to add quiz to canvas"); logger.Log("started to add quiz to canvas");
if(Quiz == null) if (Quiz == null)
{ {
logger.Log("cannot add null quiz to canvas"); logger.Log("cannot add null quiz to canvas");
return; return;
} }
await planner.LoadCanvasData(); await planner.LoadCanvasData();
if(planner.CanvasQuizzes == null) if (planner.CanvasQuizzes == null)
{ {
logger.Log("cannot add quiz to canvas, failed to retrieve current quizzes"); logger.Log("cannot add quiz to canvas, failed to retrieve current quizzes");
return; return;
} }
if(planner.LocalCourse == null) if (planner.LocalCourse == null)
{ {
logger.Log("cannot add quiz to canvas, no course stored in planner"); logger.Log("cannot add quiz to canvas, no course stored in planner");
return; return;
@@ -108,14 +111,14 @@ public class QuizEditorContext
var courseCanvasId = planner.LocalCourse.Settings.CanvasId; var courseCanvasId = planner.LocalCourse.Settings.CanvasId;
if (courseCanvasId == null) if (courseCanvasId == null)
{ {
logger.Log("was able to add course to canvas, but errored while making module item. CourseCanvasId is null"); logger.Log("was able to add quiz to canvas, but errored while making module item. CourseCanvasId is null");
return; return;
} }
var currentModule = getCurrentModule(Quiz, planner.LocalCourse); var currentModule = getCurrentModule(Quiz, planner.LocalCourse);
if (currentModule.CanvasId == null) if (currentModule.CanvasId == null)
{ {
logger.Log("was able to add course to canvas, but errored while making module item. module canvasId is null"); logger.Log("was able to add quiz to canvas, but errored while making module item. module canvasId is null");
return; return;
} }

View File

@@ -1,3 +1,4 @@
using System.Reflection;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using CanvasModel.Assignments; using CanvasModel.Assignments;
using CanvasModel.Modules; using CanvasModel.Modules;
@@ -9,6 +10,8 @@ namespace Management.Planner;
public static partial class AssignmentSyncronizationExtensions public static partial class AssignmentSyncronizationExtensions
{ {
internal static async Task<LocalAssignment> SyncAssignmentToCanvas( internal static async Task<LocalAssignment> SyncAssignmentToCanvas(
this LocalCourse localCourse, this LocalCourse localCourse,
ulong canvasCourseId, ulong canvasCourseId,

View File

@@ -47,13 +47,7 @@ public record LocalAssignment
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? LocalAssignmentGroupId { get; init; }
public int PointsPossible public int PointsPossible => Rubric.Sum(r => r.IsExtraCredit ? 0 : r.Points);
{
get
{
return 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>();
public string GetRubricHtml() public string GetRubricHtml()

View File

@@ -96,10 +96,10 @@ public class CanvasAssignmentService
await CreateRubric(courseId, localAssignment); await CreateRubric(courseId, localAssignment);
} }
public async Task Delete(ulong courseId, LocalAssignment assignment) public async Task Delete(ulong courseId, ulong assignmentCanvasId, string assignmentName)
{ {
log.Log($"deleting assignment from canvas {assignment.Name}"); log.Log($"deleting assignment from canvas {assignmentName}");
var url = $"courses/{courseId}/assignments/{assignment.CanvasId}"; var url = $"courses/{courseId}/assignments/{assignmentCanvasId}";
var request = new RestRequest(url); var request = new RestRequest(url);
var response = await webRequestor.DeleteAsync(request); var response = await webRequestor.DeleteAsync(request);
if (!response.IsSuccessful) if (!response.IsSuccessful)

View File

@@ -100,7 +100,8 @@ public class CanvasQuizService
{ {
await assignments.Delete( await assignments.Delete(
canvasCourseId, canvasCourseId,
new LocalAssignment { Name = a.Name, CanvasId = a.Id } a.Id,
a.Name
); );
} }
); );

View File

@@ -17,22 +17,3 @@ Apparently the VSCode razor extension was compiled with a preview of dotnet 6...
The issue can be tracked [here](https://github.com/dotnet/razor/issues/6241) The issue can be tracked [here](https://github.com/dotnet/razor/issues/6241)
pOpenID Connect is sometimes abbreviated to OIDC. It is not a synonym to Oauth2.0/p
pRead and watch the video in this article a href=https://developer.okta.com/blog/2019/10/21/illustrated-guide-to-oauth-and-oidchttps://developer.okta.com/blog/2019/10/21/illustrated-guide-to-oauth-and-oidc/abr
Read this article: a href=https://curity.io/resources/learn/openid-connect-overview/https://curity.io/resources/learn/openid-connect-overview//abr
Watch this video: a href=https://www.youtube.com/watch?v=rTzlF-U9Y6Yhttps://www.youtube.com/watch?v=rTzlF-U9Y6Y/a/p
pSubmit your answers to these questions:/p
ol
liWhat problem is Oauth 2.0 trying to solve?/li
liWhat is the difference between oauth and openid connect?/li
liWhat problem is OIDC trying to solve?/li
liWhat resources does the client get from the authentication server after a OIDC flow?/li
/ol
hrh1Rubric/h1precode class=language-json[
{label: Answered 4 questions, points: 8}
]/code/pre