mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-25 23:28:33 -06:00
got assignment template variables and replacement working
This commit is contained in:
@@ -11,13 +11,11 @@
|
|||||||
|
|
||||||
@inject CanvasService canvas
|
@inject CanvasService canvas
|
||||||
@inject CoursePlanner planner
|
@inject CoursePlanner planner
|
||||||
@inject ICanvasTokenManagement tokenManagement
|
|
||||||
|
|
||||||
|
|
||||||
@code
|
@code
|
||||||
{
|
{
|
||||||
private bool showNewFile { get; set; } = false;
|
private bool showNewFile { get; set; } = false;
|
||||||
private bool hasCanvasToken { get; set; } = false;
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
planner.StateHasChanged += reload;
|
planner.StateHasChanged += reload;
|
||||||
@@ -32,29 +30,10 @@
|
|||||||
{
|
{
|
||||||
planner.StateHasChanged -= reload;
|
planner.StateHasChanged -= reload;
|
||||||
}
|
}
|
||||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
||||||
{
|
|
||||||
if(firstRender)
|
|
||||||
{
|
|
||||||
hasCanvasToken = await tokenManagement.GetCanvasToken() != null;
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SetToken(string newToken)
|
|
||||||
{
|
|
||||||
await tokenManagement.SaveCanvasToken(newToken);
|
|
||||||
hasCanvasToken = true;
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
<PageTitle>Index</PageTitle>
|
<PageTitle>Index</PageTitle>
|
||||||
|
|
||||||
@if(!hasCanvasToken)
|
|
||||||
{
|
|
||||||
<ValidateCanvasToken SetToken="SetToken" />
|
|
||||||
}
|
|
||||||
|
|
||||||
@if(planner.LocalCourse == null)
|
@if(planner.LocalCourse == null)
|
||||||
{
|
{
|
||||||
<CurrentFiles />
|
<CurrentFiles />
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ var builder = WebApplication.CreateBuilder(args);
|
|||||||
// Add services to the container.
|
// Add services to the container.
|
||||||
builder.Services.AddRazorPages();
|
builder.Services.AddRazorPages();
|
||||||
builder.Services.AddServerSideBlazor();
|
builder.Services.AddServerSideBlazor();
|
||||||
builder.Services.AddScoped<ICanvasTokenManagement, BrowserStorageManagement>();
|
|
||||||
builder.Services.AddScoped<IWebRequestor, WebRequestor>();
|
builder.Services.AddScoped<IWebRequestor, WebRequestor>();
|
||||||
builder.Services.AddScoped<CanvasService, CanvasService>();
|
builder.Services.AddScoped<CanvasService, CanvasService>();
|
||||||
builder.Services.AddSingleton<YamlManager>();
|
builder.Services.AddSingleton<YamlManager>();
|
||||||
|
|||||||
@@ -134,7 +134,23 @@
|
|||||||
<div class="card-text">
|
<div class="card-text">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
@Assignment.description
|
@if(Assignment.use_template)
|
||||||
|
{
|
||||||
|
var template = planner.LocalCourse?.AssignmentTemplates.First((t) => t.Id == Assignment.template_id);
|
||||||
|
if(template == null)
|
||||||
|
{
|
||||||
|
System.Console.WriteLine($"Could not find template fof assignment, {Assignment.template_id}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var html = AssignmentTemplate.GetHtml(template, Assignment);
|
||||||
|
@((MarkupString) html)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@Assignment.description
|
||||||
|
}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
public bool UseTemplate { get; set; }
|
public bool UseTemplate { get; set; }
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string? TemplateId { get; set; }
|
public string? TemplateId { get; set; }
|
||||||
|
[Parameter]
|
||||||
|
public Dictionary<string, string> VariableValues { get; set; } = new Dictionary<string, string>();
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public EventCallback<string> DescriptionChanged { get; set; }
|
public EventCallback<string> DescriptionChanged { get; set; }
|
||||||
@@ -19,12 +21,14 @@
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public EventCallback<string?> TemplateIdChanged { get; set; }
|
public EventCallback<string?> TemplateIdChanged { get; set; }
|
||||||
|
|
||||||
private string selectedTemplateId { get; set; }
|
[Parameter]
|
||||||
|
public EventCallback<Dictionary<string, string>> VariableValuesChanged { get; set; }
|
||||||
|
|
||||||
private AssignmentTemplate? selectedTemplate =>
|
private AssignmentTemplate? selectedTemplate =>
|
||||||
planner
|
planner
|
||||||
.LocalCourse?
|
.LocalCourse?
|
||||||
.AssignmentTemplates
|
.AssignmentTemplates
|
||||||
.FirstOrDefault(t => t.Id == selectedTemplateId);
|
.FirstOrDefault(t => t.Id == TemplateId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,8 +59,14 @@
|
|||||||
<div class="col-auto text-center">
|
<div class="col-auto text-center">
|
||||||
<form @onsubmit:preventDefault="true">
|
<form @onsubmit:preventDefault="true">
|
||||||
<label for="templateSelect">Templates</label>
|
<label for="templateSelect">Templates</label>
|
||||||
<select id="templateSelect" class="form-select" @bind="selectedTemplateId">
|
<select
|
||||||
<option></option>
|
id="templateSelect"
|
||||||
|
class="form-select"
|
||||||
|
value="@TemplateId"
|
||||||
|
@onchange="async (e) =>
|
||||||
|
await TemplateIdChanged.InvokeAsync(e.Value?.ToString())"
|
||||||
|
>
|
||||||
|
<option value=""></option>
|
||||||
@foreach (var template in planner.LocalCourse.AssignmentTemplates)
|
@foreach (var template in planner.LocalCourse.AssignmentTemplates)
|
||||||
{
|
{
|
||||||
<option value="@template.Id">@template.Name</option>
|
<option value="@template.Id">@template.Name</option>
|
||||||
@@ -79,6 +89,16 @@
|
|||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
class="form-control"
|
class="form-control"
|
||||||
|
value="@VariableValues.GetValueOrDefault(variable, String.Empty)"
|
||||||
|
@oninput="async (e) =>
|
||||||
|
{
|
||||||
|
var newValue = e.Value?.ToString() ?? String.Empty;
|
||||||
|
var newDictionary = new Dictionary<string, string>(VariableValues);
|
||||||
|
newDictionary[variable] = newValue;
|
||||||
|
|
||||||
|
await VariableValuesChanged.InvokeAsync(newDictionary);
|
||||||
|
}
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,7 @@
|
|||||||
.Where(r => !r.Label.Contains(RubricItem.extraCredit))
|
.Where(r => !r.Label.Contains(RubricItem.extraCredit))
|
||||||
.Select(s => s.Points)
|
.Select(s => s.Points)
|
||||||
.Sum();
|
.Sum();
|
||||||
|
|
||||||
var newAssignment = Assignment with
|
var newAssignment = Assignment with
|
||||||
{
|
{
|
||||||
name=name,
|
name=name,
|
||||||
@@ -117,6 +118,7 @@
|
|||||||
@bind-Description="description"
|
@bind-Description="description"
|
||||||
@bind-UseTemplate="useTemplate"
|
@bind-UseTemplate="useTemplate"
|
||||||
@bind-TemplateId="templateId"
|
@bind-TemplateId="templateId"
|
||||||
|
@bind-VariableValues="templateVariables"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
|
|
||||||
|
|
||||||
public class BrowserStorageManagement : ICanvasTokenManagement
|
|
||||||
{
|
|
||||||
// private string moduleStorageKey = "module storage key";
|
|
||||||
// private string assignmentStorageKey = "assignment storage key";
|
|
||||||
private string canvasKey = "canvas key";
|
|
||||||
|
|
||||||
private ProtectedLocalStorage storage { get; }
|
|
||||||
|
|
||||||
public BrowserStorageManagement(ProtectedLocalStorage BrowserStorage)
|
|
||||||
{
|
|
||||||
storage = BrowserStorage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<string?> GetCanvasToken()
|
|
||||||
{
|
|
||||||
var result = await storage.GetAsync<string>(canvasKey);
|
|
||||||
if (!result.Success)
|
|
||||||
return null;
|
|
||||||
return result.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task SaveCanvasToken(string token)
|
|
||||||
{
|
|
||||||
await storage.SetAsync(canvasKey, token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Markdig" Version="0.31.0" />
|
||||||
<PackageReference Include="RestSharp" Version="108.0.3" />
|
<PackageReference Include="RestSharp" Version="108.0.3" />
|
||||||
<PackageReference Include="YamlDotNet" Version="13.1.1" />
|
<PackageReference Include="YamlDotNet" Version="13.1.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -15,4 +15,16 @@ public record AssignmentTemplate
|
|||||||
|
|
||||||
return matches.Select(match => match.Groups[1].Value);
|
return matches.Select(match => match.Groups[1].Value);
|
||||||
}
|
}
|
||||||
|
public static string GetHtml(AssignmentTemplate template, LocalAssignment assignment)
|
||||||
|
{
|
||||||
|
|
||||||
|
var html = Markdig.Markdown.ToHtml(template.Markdown);
|
||||||
|
|
||||||
|
foreach (KeyValuePair<string, string> entry in assignment.template_variables)
|
||||||
|
{
|
||||||
|
html = html.Replace($"%7B%7B{entry.Key}%7D%7D", entry.Value);
|
||||||
|
}
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
public interface ICanvasTokenManagement
|
|
||||||
{
|
|
||||||
Task<string?> GetCanvasToken();
|
|
||||||
Task SaveCanvasToken(string token);
|
|
||||||
}
|
|
||||||
@@ -3,46 +3,33 @@ using RestSharp;
|
|||||||
public class WebRequestor : IWebRequestor
|
public class WebRequestor : IWebRequestor
|
||||||
{
|
{
|
||||||
private const string BaseUrl = "https://snow.instructure.com/api/v1/";
|
private const string BaseUrl = "https://snow.instructure.com/api/v1/";
|
||||||
private bool tokenSet = false;
|
private string token;
|
||||||
private RestClient client;
|
private RestClient client;
|
||||||
|
|
||||||
private ICanvasTokenManagement tokenManagement { get; }
|
public WebRequestor()
|
||||||
|
|
||||||
public WebRequestor(ICanvasTokenManagement tokenManagement)
|
|
||||||
{
|
{
|
||||||
|
token =
|
||||||
|
Environment.GetEnvironmentVariable("CANVAS_TOKEN")
|
||||||
|
?? throw new Exception("CANVAS_TOKEN not in environment");
|
||||||
client = new RestClient(BaseUrl);
|
client = new RestClient(BaseUrl);
|
||||||
this.tokenManagement = tokenManagement;
|
client.AddDefaultHeader("Authorization", $"Bearer {token}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task EnsureCanvasTokenSet()
|
|
||||||
{
|
|
||||||
if (tokenSet)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var newToken = await tokenManagement.GetCanvasToken();
|
|
||||||
if(newToken == null)
|
|
||||||
throw new Exception("cannot request canvas, no token in storage");
|
|
||||||
|
|
||||||
client.AddDefaultHeader("Authorization", $"Bearer {newToken}");
|
|
||||||
tokenSet = true;
|
|
||||||
}
|
|
||||||
public async Task<(T[]?, RestResponse)> GetManyAsync<T>(RestRequest request)
|
public async Task<(T[]?, RestResponse)> GetManyAsync<T>(RestRequest request)
|
||||||
{
|
{
|
||||||
await EnsureCanvasTokenSet();
|
|
||||||
var response = await client.ExecuteGetAsync(request);
|
var response = await client.ExecuteGetAsync(request);
|
||||||
return (Deserialize<T[]>(response), response);
|
return (Deserialize<T[]>(response), response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<(T?, RestResponse)> GetAsync<T>(RestRequest request)
|
public async Task<(T?, RestResponse)> GetAsync<T>(RestRequest request)
|
||||||
{
|
{
|
||||||
await EnsureCanvasTokenSet();
|
|
||||||
var response = await client.ExecuteGetAsync(request);
|
var response = await client.ExecuteGetAsync(request);
|
||||||
return (Deserialize<T>(response), response);
|
return (Deserialize<T>(response), response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RestResponse> PostAsync(RestRequest request)
|
public async Task<RestResponse> PostAsync(RestRequest request)
|
||||||
{
|
{
|
||||||
await EnsureCanvasTokenSet();
|
|
||||||
var response = await client.ExecutePostAsync(request);
|
var response = await client.ExecutePostAsync(request);
|
||||||
if (!response.IsSuccessful)
|
if (!response.IsSuccessful)
|
||||||
{
|
{
|
||||||
@@ -56,7 +43,6 @@ public class WebRequestor : IWebRequestor
|
|||||||
|
|
||||||
public async Task<(T?, RestResponse)> PostAsync<T>(RestRequest request)
|
public async Task<(T?, RestResponse)> PostAsync<T>(RestRequest request)
|
||||||
{
|
{
|
||||||
await EnsureCanvasTokenSet();
|
|
||||||
var response = await client.ExecutePostAsync(request);
|
var response = await client.ExecutePostAsync(request);
|
||||||
return (Deserialize<T>(response), response);
|
return (Deserialize<T>(response), response);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user