From e53222e35df5d2b50094b7a95cbd5b6535cadb27 Mon Sep 17 00:00:00 2001 From: Alex Mickelson Date: Fri, 22 Sep 2023 12:40:40 -0600 Subject: [PATCH] halfway through localcourse transition --- Management.Web/Pages/AssignmentFormPage.razor | 4 +- Management.Web/Pages/Course.razor | 6 +-- Management.Web/Pages/Index.razor | 2 +- .../AssignmentForm/AssignmentForm.razor | 6 +-- .../Shared/Course/CourseDetails.razor | 4 +- .../Shared/Course/CourseSettings.razor | 11 ++-- Management.Web/Shared/CurrentFiles.razor | 6 +-- .../Shared/InitializeYamlFromCanvas.razor | 12 +++-- .../Module/Assignment/AssignmentDetails.razor | 4 +- .../Shared/Semester/Day/AssignmentInDay.razor | 2 +- Management.Web/Shared/Semester/Day/Day.razor | 4 +- .../Features/Calendar/SemesterPlanner.cs | 2 + .../Features/Configuration/CoursePlanner.cs | 31 ++++++++--- .../CoursePlannerValidationExtensions.cs | 19 ++++--- Management/Models/Local/LocalAssignment.cs | 10 ++++ Management/Models/Local/LocalCourse.cs | 17 +++++- Management/Models/Local/LocalQuiz.cs | 9 ++++ Management/Services/YamlManager.cs | 53 +++++++++++++++++-- 18 files changed, 152 insertions(+), 50 deletions(-) diff --git a/Management.Web/Pages/AssignmentFormPage.razor b/Management.Web/Pages/AssignmentFormPage.razor index 57531fb..eee966f 100644 --- a/Management.Web/Pages/AssignmentFormPage.razor +++ b/Management.Web/Pages/AssignmentFormPage.razor @@ -34,8 +34,8 @@ if(planner.LocalCourse == null) { var courses = await yamlManager.LoadSavedCourses(); - planner.LocalCourse = courses.First(c => c.Name == CourseName); - logger.LogInformation($"set course to '{planner.LocalCourse?.Name}'"); + planner.LocalCourse = courses.First(c => c.Settings.Name == CourseName); + logger.LogInformation($"set course to '{planner.LocalCourse?.Settings.Name}'"); } if(assignmentContext.Assignment == null) diff --git a/Management.Web/Pages/Course.razor b/Management.Web/Pages/Course.razor index 3014d4c..c760a1f 100644 --- a/Management.Web/Pages/Course.razor +++ b/Management.Web/Pages/Course.razor @@ -25,7 +25,7 @@ if(planner.LocalCourse == null) { var courses = await yamlManager.LoadSavedCourses(); - planner.LocalCourse = courses.First(c => c.Name == CourseName); + planner.LocalCourse = courses.First(c => c.Settings.Name == CourseName); } base.OnInitialized(); loading = false; @@ -66,12 +66,12 @@ View In Canvas
- @planner.LocalCourse.Name + @planner.LocalCourse.Settings.Name
diff --git a/Management.Web/Pages/Index.razor b/Management.Web/Pages/Index.razor index 3110642..736bd73 100644 --- a/Management.Web/Pages/Index.razor +++ b/Management.Web/Pages/Index.razor @@ -104,7 +104,7 @@ View In Canvas
- @planner.LocalCourse.Name + @planner.LocalCourse.Settings.Name
diff --git a/Management.Web/Shared/Components/AssignmentForm/AssignmentForm.razor b/Management.Web/Shared/Components/AssignmentForm/AssignmentForm.razor index 6ec4cce..2a5e250 100644 --- a/Management.Web/Shared/Components/AssignmentForm/AssignmentForm.razor +++ b/Management.Web/Shared/Components/AssignmentForm/AssignmentForm.razor @@ -79,9 +79,9 @@ { Modules = newModules }; - if (assignment.CanvasId != null && planner.LocalCourse.CanvasId != null) + if (assignment.CanvasId != null && planner.LocalCourse.Settings.CanvasId != null) { - ulong courseId = planner.LocalCourse.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); } } @@ -190,7 +190,7 @@ class="btn btn-primary mx-2" @onclick="@(() => { assignmentContext.Assignment = null; - Navigation.NavigateTo("/course/" + planner.LocalCourse?.Name); + Navigation.NavigateTo("/course/" + planner.LocalCourse?.Settings.Name); })" > Done diff --git a/Management.Web/Shared/Course/CourseDetails.razor b/Management.Web/Shared/Course/CourseDetails.razor index 4b155a0..21c47f2 100644 --- a/Management.Web/Shared/Course/CourseDetails.razor +++ b/Management.Web/Shared/Course/CourseDetails.razor @@ -21,7 +21,7 @@ if( planner.CanvasAssignments == null && planner.LocalCourse != null - && planner.LocalCourse.CanvasId != null + && planner.LocalCourse.Settings.CanvasId != null ) { await planner.LoadCanvasData(); @@ -48,7 +48,7 @@ {
- @foreach (var month in SemesterPlanner.GetMonthsBetweenDates(planner.LocalCourse.StartDate, planner.LocalCourse.EndDate)) + @foreach (var month in SemesterPlanner.GetMonthsBetweenDates(planner.LocalCourse.Settings.StartDate, planner.LocalCourse.Settings.EndDate)) {
diff --git a/Management.Web/Shared/Course/CourseSettings.razor b/Management.Web/Shared/Course/CourseSettings.razor index b67670e..964aae9 100644 --- a/Management.Web/Shared/Course/CourseSettings.razor +++ b/Management.Web/Shared/Course/CourseSettings.razor @@ -28,8 +28,11 @@ { planner.LocalCourse = planner.LocalCourse with { - StartDate=selectedTerm.StartAt ?? new DateTime(), - EndDate=selectedTerm.EndAt ?? new DateTime(), + Settings = planner.LocalCourse.Settings with + { + StartDate=selectedTerm.StartAt ?? new DateTime(), + EndDate=selectedTerm.EndAt ?? new DateTime(), + } }; } } @@ -43,10 +46,10 @@ { if (firstRender) { - if(planner.LocalCourse != null && planner.LocalCourse.CanvasId != null) + if(planner.LocalCourse != null && planner.LocalCourse.Settings.CanvasId != null) { loading = true; - ulong id = planner.LocalCourse?.CanvasId ?? throw new Exception("wtf how did i get here"); + ulong id = planner.LocalCourse?.Settings.CanvasId ?? throw new Exception("wtf how did i get here"); var canvasCourse = await canvas.GetCourse(id); terms = await canvas.GetCurrentTermsFor(canvasCourse.StartAt); loading = false; diff --git a/Management.Web/Shared/CurrentFiles.razor b/Management.Web/Shared/CurrentFiles.razor index 0aeeb49..6c7519d 100644 --- a/Management.Web/Shared/CurrentFiles.razor +++ b/Management.Web/Shared/CurrentFiles.razor @@ -19,7 +19,7 @@ { @* logger.LogInformation("here"); *@ planner.LocalCourse = course; - Navigation.NavigateTo("/course/" + course.Name); + Navigation.NavigateTo("/course/" + course.Settings.Name); Console.WriteLine("navigated to course detail"); } } @@ -30,10 +30,10 @@

Stored Courses

@foreach (var course in localCourses) { - var location = "/course/" + course.Name; + var location = "/course/" + course.Settings.Name;

- @course.Name + @course.Settings.Name

diff --git a/Management.Web/Shared/InitializeYamlFromCanvas.razor b/Management.Web/Shared/InitializeYamlFromCanvas.razor index be27889..e51f702 100644 --- a/Management.Web/Shared/InitializeYamlFromCanvas.razor +++ b/Management.Web/Shared/InitializeYamlFromCanvas.razor @@ -61,11 +61,13 @@ var course = new LocalCourse { Modules = new LocalModule[] {}, - Name = selectedCourse.Name, - CanvasId = selectedCourse.Id, DaysOfWeek = days, - StartDate = selectedTerm?.StartAt ?? new DateTime(), - EndDate = selectedTerm?.EndAt ?? new DateTime(), + Settings = new LocalCourseSettings() { + Name = selectedCourse.Name, + CanvasId = selectedCourse.Id, + StartDate = selectedTerm?.StartAt ?? new DateTime(), + EndDate = selectedTerm?.EndAt ?? new DateTime(), + } }; await yamlManager.SaveCourseAsync(course); NewFileCreated(); @@ -80,7 +82,7 @@ loadingCourses = true; localCourses = await yamlManager.LoadSavedCourses(); - var storedCourseIds = localCourses.Select(c => c.CanvasId); + var storedCourseIds = localCourses.Select(c => c.Settings.CanvasId); var allCourses = await canvas.GetCourses((ulong)selectedTermId); courses = allCourses.Where(c => !storedCourseIds.Contains(c.Id)); loadingCourses = false; diff --git a/Management.Web/Shared/Module/Assignment/AssignmentDetails.razor b/Management.Web/Shared/Module/Assignment/AssignmentDetails.razor index 8ee91d7..73585a5 100644 --- a/Management.Web/Shared/Module/Assignment/AssignmentDetails.razor +++ b/Management.Web/Shared/Module/Assignment/AssignmentDetails.razor @@ -48,7 +48,7 @@ private void OnClick() { assignmentContext.Assignment = Assignment; - Navigation.NavigateTo("/course/" + planner.LocalCourse.Name + "/assignment/" + Assignment.Id); + Navigation.NavigateTo("/course/" + planner.LocalCourse?.Settings.Name + "/assignment/" + Assignment.Id); } } @@ -73,7 +73,7 @@ @if(isSyncedWithCanvas) { @if(planner.LocalCourse != null - && planner.LocalCourse.CanvasId != null + && planner.LocalCourse.Settings.CanvasId != null && planner.CanvasAssignments != null && planner.CanvasModules != null && Assignment.NeedsUpdates( diff --git a/Management.Web/Shared/Semester/Day/AssignmentInDay.razor b/Management.Web/Shared/Semester/Day/AssignmentInDay.razor index 90c4a9c..a29c629 100644 --- a/Management.Web/Shared/Semester/Day/AssignmentInDay.razor +++ b/Management.Web/Shared/Semester/Day/AssignmentInDay.razor @@ -37,7 +37,7 @@ if(planner.LocalCourse != null) { assignmentContext.Assignment = Assignment; - Navigation.NavigateTo("/course/" + planner.LocalCourse.Name + "/assignment/" + Assignment.Id); + Navigation.NavigateTo("/course/" + planner.LocalCourse.Settings.Name + "/assignment/" + Assignment.Id); logger.LogInformation("navigating to assignment page"); } } diff --git a/Management.Web/Shared/Semester/Day/Day.razor b/Management.Web/Shared/Semester/Day/Day.razor index adb3924..342bc37 100644 --- a/Management.Web/Shared/Semester/Day/Day.razor +++ b/Management.Web/Shared/Semester/Day/Day.razor @@ -70,8 +70,8 @@ var isClassDay = planner.LocalCourse?.DaysOfWeek.Contains(notNullDay) ?? false; var dayInSemester = isClassDay - && date <= planner.LocalCourse?.EndDate - && date >= planner.LocalCourse?.StartDate; + && date <= planner.LocalCourse?.Settings.EndDate + && date >= planner.LocalCourse?.Settings.StartDate; var totalClasses = dayInSemester ? "bg-light-subtle text-light " + baseClasses diff --git a/Management/Features/Calendar/SemesterPlanner.cs b/Management/Features/Calendar/SemesterPlanner.cs index 2be03b8..3769236 100644 --- a/Management/Features/Calendar/SemesterPlanner.cs +++ b/Management/Features/Calendar/SemesterPlanner.cs @@ -9,6 +9,8 @@ public class SemesterPlanner { var monthsInTerm = 1 + ((endDate.Year - startDate.Year) * 12) + endDate.Month - startDate.Month; + Console.WriteLine(monthsInTerm); + return Enumerable .Range(0, monthsInTerm) .Select(monthDiff => diff --git a/Management/Features/Configuration/CoursePlanner.cs b/Management/Features/Configuration/CoursePlanner.cs index e1dc7a3..ddff7d0 100644 --- a/Management/Features/Configuration/CoursePlanner.cs +++ b/Management/Features/Configuration/CoursePlanner.cs @@ -30,18 +30,33 @@ public class CoursePlanner get => _localCourse; set { + if (value == null) { _localCourse = null; StateHasChanged?.Invoke(); return; } + + var courseWithSettings = value with + { + Settings = value.Settings with + { + AssignmentGroups = value.AssignmentGroups, + Name = value.Settings.Name, + DaysOfWeek = value.DaysOfWeek, + CanvasId = value.Settings.CanvasId, + StartDate = value.Settings.StartDate, + DefaultDueTime = value.DefaultDueTime, + AssignmentTemplates = value.AssignmentTemplates, + } + }; - var verifiedCourse = value.GeneralCourseCleanup(); + var verifiedCourse = courseWithSettings.GeneralCourseCleanup(); _debounceTimer?.Dispose(); _debounceTimer = new Timer( - (_) => saveCourseToFile(value), + async (_) => await saveCourseToFile(courseWithSettings), null, _debounceInterval, Timeout.Infinite @@ -52,7 +67,7 @@ public class CoursePlanner } } - private void saveCourseToFile(LocalCourse courseAsOfDebounce) + private async Task saveCourseToFile(LocalCourse courseAsOfDebounce) { _debounceTimer?.Dispose(); @@ -60,12 +75,12 @@ public class CoursePlanner if (LocalCourse == null) { Console.WriteLine("saving course as of debounce call time"); - yamlManager.SaveCourse(courseAsOfDebounce); + await yamlManager.SaveCourseAsync(courseAsOfDebounce); } else { Console.WriteLine("Saving latest version of file"); - yamlManager.SaveCourse(LocalCourse); + await yamlManager.SaveCourseAsync(LocalCourse); } } @@ -89,7 +104,7 @@ public class CoursePlanner StateHasChanged?.Invoke(); var canvasId = - LocalCourse?.CanvasId ?? throw new Exception("no canvas id found for selected course"); + LocalCourse?.Settings.CanvasId ?? throw new Exception("no canvas id found for selected course"); var assignmentsTask = canvas.Assignments.GetAll(canvasId); var quizzesTask = canvas.Quizzes.GetAll(canvasId); @@ -112,7 +127,7 @@ public class CoursePlanner { if ( LocalCourse == null - || LocalCourse.CanvasId == null + || LocalCourse.Settings.CanvasId == null || CanvasAssignments == null || CanvasModules == null || CanvasQuizzes == null @@ -141,7 +156,7 @@ public class CoursePlanner ); var canvasId = - LocalCourse.CanvasId ?? throw new Exception("no course canvas id to sync with canvas"); + LocalCourse.Settings.CanvasId ?? throw new Exception("no course canvas id to sync with canvas"); var newAssignmentGroups = await LocalCourse.EnsureAllAssignmentGroupsExistInCanvas( canvasId, canvasAssignmentGroups, canvas); diff --git a/Management/Features/Configuration/CoursePlannerValidationExtensions.cs b/Management/Features/Configuration/CoursePlannerValidationExtensions.cs index 2850b91..56972e2 100644 --- a/Management/Features/Configuration/CoursePlannerValidationExtensions.cs +++ b/Management/Features/Configuration/CoursePlannerValidationExtensions.cs @@ -25,21 +25,24 @@ public static class CoursePlannerExtensions .ToArray(); var cleanStartDay = new DateTime( - incomingCourse.StartDate.Year, - incomingCourse.StartDate.Month, - incomingCourse.StartDate.Day + incomingCourse.Settings.StartDate.Year, + incomingCourse.Settings.StartDate.Month, + incomingCourse.Settings.StartDate.Day ); var cleanEndDay = new DateTime( - incomingCourse.EndDate.Year, - incomingCourse.EndDate.Month, - incomingCourse.EndDate.Day + incomingCourse.Settings.EndDate.Year, + incomingCourse.Settings.EndDate.Month, + incomingCourse.Settings.EndDate.Day ); return incomingCourse with { Modules = cleanModules, - StartDate = cleanStartDay, - EndDate = cleanEndDay, + Settings = incomingCourse.Settings with + { + StartDate = cleanStartDay, + EndDate = cleanEndDay, + } }; } diff --git a/Management/Models/Local/LocalAssignment.cs b/Management/Models/Local/LocalAssignment.cs index f54e88c..a03aa9c 100644 --- a/Management/Models/Local/LocalAssignment.cs +++ b/Management/Models/Local/LocalAssignment.cs @@ -1,3 +1,5 @@ +using YamlDotNet.Serialization; + namespace LocalModels; public record RubricItem @@ -95,4 +97,12 @@ public record LocalAssignment assignmentGroups .FirstOrDefault(g => g.Id == LocalAssignmentGroupId)? .CanvasId; + + + public string ToYaml() + { + var serializer = new SerializerBuilder().DisableAliases().Build(); + var yaml = serializer.Serialize(this); + return yaml; + } } diff --git a/Management/Models/Local/LocalCourse.cs b/Management/Models/Local/LocalCourse.cs index 2e779fc..7e3e5f4 100644 --- a/Management/Models/Local/LocalCourse.cs +++ b/Management/Models/Local/LocalCourse.cs @@ -3,6 +3,21 @@ namespace LocalModels; public record LocalCourse { public IEnumerable Modules { get; init; } = Enumerable.Empty(); + + public IEnumerable AssignmentGroups { get; init; } = + Enumerable.Empty(); + public IEnumerable DaysOfWeek { get; init; } = Enumerable.Empty(); + public SimpleTimeOnly DefaultDueTime { get; init; } = new SimpleTimeOnly(); + public IEnumerable AssignmentTemplates { get; init; } = + Enumerable.Empty(); + + public LocalCourseSettings Settings { get; set; } +} + +public record LocalCourseSettings +{ + public IEnumerable AssignmentGroups { get; init; } = + Enumerable.Empty(); public string Name { get; init; } = string.Empty; public IEnumerable DaysOfWeek { get; init; } = Enumerable.Empty(); public ulong? CanvasId { get; init; } @@ -11,8 +26,6 @@ public record LocalCourse public SimpleTimeOnly DefaultDueTime { get; init; } = new SimpleTimeOnly(); public IEnumerable AssignmentTemplates { get; init; } = Enumerable.Empty(); - public IEnumerable AssignmentGroups { get; init; } = - Enumerable.Empty(); } public record SimpleTimeOnly diff --git a/Management/Models/Local/LocalQuiz.cs b/Management/Models/Local/LocalQuiz.cs index f3ba5bb..3d222d5 100644 --- a/Management/Models/Local/LocalQuiz.cs +++ b/Management/Models/Local/LocalQuiz.cs @@ -1,3 +1,5 @@ +using YamlDotNet.Serialization; + namespace LocalModels; public record LocalQuiz @@ -25,4 +27,11 @@ public record LocalQuiz assignmentGroups .FirstOrDefault(g => g.Id == LocalAssignmentGroupId)? .CanvasId; + + public string ToYaml() + { + var serializer = new SerializerBuilder().DisableAliases().Build(); + var yaml = serializer.Serialize(this); + return yaml; + } } diff --git a/Management/Services/YamlManager.cs b/Management/Services/YamlManager.cs index b43c8ca..11bb7f3 100644 --- a/Management/Services/YamlManager.cs +++ b/Management/Services/YamlManager.cs @@ -7,6 +7,7 @@ public class YamlManager public string CourseToYaml(LocalCourse course) { var serializer = new SerializerBuilder().DisableAliases().Build(); + var yaml = serializer.Serialize(course); return yaml; @@ -24,16 +25,60 @@ public class YamlManager { var courseString = CourseToYaml(course); - await File.WriteAllTextAsync($"../storage/{course.Name}.yml", courseString); + var courseDirectory = $"../storage/{course.Settings.Name}"; + if (!Directory.Exists(courseDirectory)) + Directory.CreateDirectory(courseDirectory); + + await SaveModules(course); + + await File.WriteAllTextAsync($"../storage/{course.Settings.Name}.yml", courseString); } - public void SaveCourse(LocalCourse course) + public async Task SaveModules(LocalCourse course) { - var courseString = CourseToYaml(course); + var courseDirectory = $"../storage/{course.Settings.Name}"; + + foreach (var module in course.Modules) + { + var moduleDirectory = courseDirectory + "/" + module.Name; + if (!Directory.Exists(moduleDirectory)) + Directory.CreateDirectory(moduleDirectory); + + await SaveQuizzes(course, module); + await SaveAssignments(course, module); + } - File.WriteAllText($"../storage/{course.Name}.yml", courseString); } + public async Task SaveQuizzes(LocalCourse course, LocalModule module) + { + var quizzesDirectory = $"../storage/{course.Settings.Name}/{module.Name}/quizzes"; + if (!Directory.Exists(quizzesDirectory)) + Directory.CreateDirectory(quizzesDirectory); + + foreach(var quiz in module.Quizzes) + { + var filePath = quizzesDirectory + "/" + quiz.Name+ ".yml"; ; + var quizYaml = quiz.ToYaml(); + await File.WriteAllTextAsync(filePath, quizYaml); + } + } + + public async Task SaveAssignments(LocalCourse course, LocalModule module) + { + var assignmentsDirectory = $"../storage/{course.Settings.Name}/{module.Name}/assignments"; + if (!Directory.Exists(assignmentsDirectory)) + Directory.CreateDirectory(assignmentsDirectory); + + foreach (var assignment in module.Assignments) + { + var filePath = assignmentsDirectory + "/" + assignment.Name + ".yml"; + var assignmentYaml = assignment.ToYaml(); + await File.WriteAllTextAsync(filePath, assignmentYaml); + } + } + + public async Task> LoadSavedCourses() { string path = "../storage/";