diff --git a/PlotLine/Controllers/PlotLinesController.cs b/PlotLine/Controllers/PlotLinesController.cs index fb2da8c..bf1b28c 100644 --- a/PlotLine/Controllers/PlotLinesController.cs +++ b/PlotLine/Controllers/PlotLinesController.cs @@ -32,7 +32,8 @@ public sealed class PlotLinesController(IPlotService plots) : Controller { if (!ModelState.IsValid) { - return View("Edit", model); + var editModel = await plots.PopulatePlotLineFormAsync(model); + return editModel is null ? NotFound() : View("Edit", editModel); } await plots.SavePlotLineAsync(model); diff --git a/PlotLine/Services/CoreServices.cs b/PlotLine/Services/CoreServices.cs index c8f167b..7875d97 100644 --- a/PlotLine/Services/CoreServices.cs +++ b/PlotLine/Services/CoreServices.cs @@ -113,6 +113,7 @@ public interface IPlotService Task GetPlotLinesAsync(int projectId); Task GetCreatePlotLineAsync(int projectId); Task GetEditPlotLineAsync(int plotLineId); + Task PopulatePlotLineFormAsync(PlotLineEditViewModel model); Task SavePlotLineAsync(PlotLineEditViewModel model); Task ArchivePlotLineAsync(int plotLineId); Task GetPlotThreadsAsync(int projectId); @@ -2099,6 +2100,27 @@ public sealed class PlotService(IProjectRepository projects, IBookRepository boo }, lookupData, plotLines.Where(x => x.PlotLineID != plotLine.PlotLineID)); } + public async Task PopulatePlotLineFormAsync(PlotLineEditViewModel model) + { + var project = await projects.GetAsync(model.ProjectID); + if (project is null) + { + return null; + } + + var lookupData = await plots.GetLookupsAsync(); + var plotLines = await plots.ListPlotLinesAsync(model.ProjectID); + + model.Project = project; + if (model.PlotLineTypeID == 0) + { + model.PlotLineTypeID = lookupData.PlotLineTypes.FirstOrDefault(x => x.TypeName == "Side Plot")?.PlotLineTypeID + ?? lookupData.PlotLineTypes.First().PlotLineTypeID; + } + + return await PopulatePlotLineListsAsync(model, lookupData, plotLines.Where(x => x.PlotLineID != model.PlotLineID)); + } + public async Task SavePlotLineAsync(PlotLineEditViewModel model) { var isNew = model.PlotLineID == 0; @@ -2301,7 +2323,6 @@ public sealed class PlotService(IProjectRepository projects, IBookRepository boo private async Task PopulatePlotLineListsAsync(PlotLineEditViewModel model, PlotLookupData lookupData, IEnumerable parentCandidates) { - model.PlotLineTypes = ChapterService.ToSelectList(lookupData.PlotLineTypes, x => x.PlotLineTypeID, x => x.TypeName); model.PlotImportance = ChapterService.ToSelectList(lookupData.PlotImportance, x => x.PlotImportanceID, x => x.ImportanceName); model.BookOptions = (await books.ListByProjectAsync(model.ProjectID)) .Select(x => new SelectListItem($"Book {x.BookNumber}: {x.BookTitle}", x.BookID.ToString())) diff --git a/PlotLine/ViewModels/CoreViewModels.cs b/PlotLine/ViewModels/CoreViewModels.cs index 6eb537d..1db34ec 100644 --- a/PlotLine/ViewModels/CoreViewModels.cs +++ b/PlotLine/ViewModels/CoreViewModels.cs @@ -692,7 +692,7 @@ public sealed class MetricGraphPointViewModel public int Percent { get; set; } } -public sealed class PlotLineEditViewModel +public sealed class PlotLineEditViewModel : IValidatableObject { public int PlotLineID { get; set; } public int ProjectID { get; set; } @@ -704,6 +704,7 @@ public sealed class PlotLineEditViewModel [Display(Name = "Type")] public int PlotLineTypeID { get; set; } + [Range(1, int.MaxValue, ErrorMessage = "Choose a plot importance.")] [Display(Name = "Importance")] public int PlotImportanceID { get; set; } = 2; @@ -726,10 +727,19 @@ public sealed class PlotLineEditViewModel public bool IsVisibleOnTimeline { get; set; } = true; public Project? Project { get; set; } - public IReadOnlyList PlotLineTypes { get; set; } = []; public IReadOnlyList PlotImportance { get; set; } = []; public IReadOnlyList BookOptions { get; set; } = []; public IReadOnlyList ParentPlotLineOptions { get; set; } = []; + + public IEnumerable Validate(ValidationContext validationContext) + { + if (PlotLineID > 0 && EmergesFromPlotLineID == PlotLineID) + { + yield return new ValidationResult( + "A plot line cannot emerge from itself.", + [nameof(EmergesFromPlotLineID)]); + } + } } public sealed class PlotLineListViewModel diff --git a/PlotLine/Views/PlotLines/Edit.cshtml b/PlotLine/Views/PlotLines/Edit.cshtml index 98edcac..8fea696 100644 --- a/PlotLine/Views/PlotLines/Edit.cshtml +++ b/PlotLine/Views/PlotLines/Edit.cshtml @@ -37,6 +37,7 @@
+
@@ -44,13 +45,12 @@
-
- - -
- + +
@@ -69,6 +69,7 @@ +