started creating module ui, workign on assignments

This commit is contained in:
2023-01-23 20:42:12 -07:00
parent 4da93ca348
commit fae06907be
11 changed files with 256 additions and 1 deletions

View File

@@ -0,0 +1,40 @@
public class ModuleTests
{
[Test]
public void CanAddModule()
{
var manager = new ModuleManager();
var module = new CourseModule("First Module", new LocalAssignment[] { });
manager.AddModule(module);
manager.Modules.Count().Should().Be(1);
manager.Modules.First().Should().Be(module);
}
[Test]
public void CanAddAssignmentToCorrectModule()
{
var manager = new ModuleManager();
manager.AddModule(new CourseModule("First Module", new LocalAssignment[] { }));
manager.AddModule(new CourseModule("Second Module", new LocalAssignment[] { }));
manager.AddModule(new CourseModule("Third Module", new LocalAssignment[] { }));
manager.AddModule(new CourseModule("Fourth Module", new LocalAssignment[] { }));
var assignment = new LocalAssignment
{
name = "testname",
description = "testDescription",
published = false,
lock_at_due_date = true,
rubric = new RubricItem[] { },
lock_at = null,
due_at = DateTime.Now,
points_possible = 10,
submission_types = new SubmissionType[] { SubmissionType.online_text_entry }
};
manager.AddAssignment(3, assignment);
manager.Modules.Count().Should().Be(4);
manager.Modules.ElementAt(3).Assignments.Count().Should().Be(1);
}
}

View File

@@ -1,3 +1,31 @@
@page "/modules"
@using Management.Web.Shared.Module
@using System.Linq
@inject IModuleManager moduleManager
@code {
private bool showNewModule { get; set; } = false;
}
<PageTitle>Weather forecast</PageTitle>
@if (!showNewModule)
{
<button class="btn btn-secondary" @onclick="() => showNewModule = true">New Module</button>
}
else
{
<button class="btn btn-secondary" @onclick="() => showNewModule = false">Hide New Module</button>
}
@if (showNewModule)
{
<NewModule OnSubmit="() => showNewModule = false" />
}
@foreach (var i in moduleManager.Modules.Select((_value, i) => i))
{
<hr>
<ModuleDetail ModuleIndex="i" />
}

View File

@@ -1,5 +1,6 @@
global using System.Text.Json.Serialization;
global using System.Text.Json;
global using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
@@ -15,6 +16,7 @@ builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<IWebRequestor, WebRequestor>();
builder.Services.AddSingleton<ICanvasService, CanvasService>();
builder.Services.AddSingleton<IConfigurationManagement, ConfigurationManagement>();
builder.Services.AddSingleton<IModuleManager, ModuleManager>();
var app = builder.Build();

View File

@@ -0,0 +1,38 @@
@inject IModuleManager moduleManager
@code {
[Parameter, EditorRequired]
public int ModuleIndex { get; set; }
[Parameter]
public EventCallback OnSubmit { get; set; }
[Required]
[StringLength(50, ErrorMessage = "Name too long (50 character limit).")]
private string Name { get; set; } = "";
private async Task submitHandler()
{
var newAssignment = new LocalAssignment
{
name = Name,
description = "testDescription",
published = false,
lock_at_due_date = true,
rubric = new RubricItem[] { },
lock_at = null,
due_at = DateTime.Now,
points_possible = 10,
submission_types = new SubmissionType[] { SubmissionType.online_text_entry }
};
moduleManager.AddAssignment(ModuleIndex, newAssignment);
await OnSubmit.InvokeAsync();
}
}
<form @onsubmit:preventDefault="true" @onsubmit="submitHandler">
<label for="Assignment Name">Name</label>
<input id="moduleName" class="form-control" @bind="Name" />
<button class="btn btn-primary">Save</button>
</form>

View File

@@ -0,0 +1,40 @@
@using Management.Web.Shared.Module.Assignment
@inject IModuleManager moduleManager
@code {
[Parameter, EditorRequired]
public int ModuleIndex { get; set; }
private bool showAddAssignment { get; set; } = false;
private CourseModule? module
{
get
{
return moduleManager.Modules.ElementAtOrDefault(ModuleIndex);
}
}
}
@if (module != null)
{
<h3 class="text-center">@module.Name</h3>
<button class="btn btn-primary" @onclick="() => showAddAssignment = true">Add Assignment</button>
@if (showAddAssignment)
{
<div class="ms-5 ">
<div class="bg-light border rounded m-3 p-3">
<NewAssignment ModuleIndex="ModuleIndex" OnSubmit="() => showAddAssignment = false" />
</div>
</div>
}
<h5>Assignments</h5>
@foreach (var assignment in module.Assignments)
{
<div>@assignment.name</div>
}
}

View File

@@ -0,0 +1,27 @@
@inject IModuleManager moduleManager
@code {
[Required]
[StringLength(50, ErrorMessage = "Name too long (50 character limit).")]
private string Name { get; set; } = "";
[Parameter]
public EventCallback OnSubmit { get; set; }
private async Task submitHandler()
{
var module = new CourseModule(Name: Name, Assignments: new LocalAssignment[] { });
moduleManager.AddModule(module);
Name = "";
await OnSubmit.InvokeAsync();
}
}
<h1>New Module</h1>
<form @onsubmit:preventDefault="true" @onsubmit="submitHandler">
<label for="moduleName">Name:</label>
<input id="moduleName" class="form-control" @bind="Name" />
<button class="btn btn-primary">Save</button>
</form>

View File

@@ -0,0 +1,6 @@
public interface IModuleManager
{
IEnumerable<CourseModule> Modules { get; }
public void AddModule(CourseModule newModule);
public void AddAssignment(int moduleIndex, LocalAssignment assignment);
}

View File

@@ -0,0 +1,22 @@
public class ModuleManager : IModuleManager
{
public IEnumerable<CourseModule> Modules { get; internal set; } = new CourseModule[] { };
public void AddAssignment(int moduleIndex, LocalAssignment assignment)
{
var newAssignments = Modules.ElementAt(moduleIndex).Assignments.Append(assignment);
var newModule = Modules.ElementAt(moduleIndex) with { Assignments = newAssignments };
if (newModule == null)
throw new Exception($"cannot get module at index {moduleIndex}");
Modules = Modules
.Take(moduleIndex)
.Append(newModule)
.Concat(Modules.Skip(moduleIndex + 1));
}
public void AddModule(CourseModule newModule)
{
Modules = Modules.Append(newModule);
}
}

View File

@@ -0,0 +1,11 @@
using System.ComponentModel.DataAnnotations;
public record CourseModule(
[property: Required]
[property: StringLength(50, ErrorMessage = "Name too long (50 character limit).")]
string Name,
IEnumerable<LocalAssignment>? Assignments
)
{
public IEnumerable<LocalAssignment> Assignments = Assignments ?? new LocalAssignment[] { };
}

View File

@@ -0,0 +1,31 @@
public record RubricItem(
int Points,
string Label
);
public enum SubmissionType
{
online_quiz,
none,
on_paper,
discussion_topic,
external_tool,
online_upload,
online_text_entry,
online_url,
media_recording,
student_annotation,
}
public record LocalAssignment
{
public string name { get; init; } = "";
public string description { get; init; } = "";
public bool published { get; init; }
public bool lock_at_due_date { get; init; }
public IEnumerable<RubricItem> rubric { get; init; } = new RubricItem[] { };
public DateTime? lock_at { get; init; }
public DateTime due_at { get; init; }
public int points_possible { get; init; }
public IEnumerable<SubmissionType> submission_types { get; init; } = new SubmissionType[] { };
}

View File

@@ -6,3 +6,13 @@ install specflow template `dotnet new install Specflow.Templates.DotNet`
view templates with `dotnet new -l`
find outdated packages `dotnet list package --outdated`
Development command: `dotnet watch --project Management.Web/`
# Razor Hack
Apparently the VSCode razor extension was compiled with a preview of dotnet 6... and only uses openssl 1.1. After installing openssl1.1 you can tell vscode to provide it with `export CLR_OPENSSL_VERSION_OVERRIDE=1.1; code ~/projects/canvasManagement`.
The issue can be tracked [here](https://github.com/dotnet/razor/issues/6241)