Phase 6B Plot Line Forms
This commit is contained in:
parent
fb5352ab8f
commit
023ca1404e
@ -32,7 +32,8 @@ public sealed class PlotLinesController(IPlotService plots) : Controller
|
|||||||
{
|
{
|
||||||
if (!ModelState.IsValid)
|
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);
|
await plots.SavePlotLineAsync(model);
|
||||||
|
|||||||
@ -113,6 +113,7 @@ public interface IPlotService
|
|||||||
Task<PlotLineListViewModel?> GetPlotLinesAsync(int projectId);
|
Task<PlotLineListViewModel?> GetPlotLinesAsync(int projectId);
|
||||||
Task<PlotLineEditViewModel?> GetCreatePlotLineAsync(int projectId);
|
Task<PlotLineEditViewModel?> GetCreatePlotLineAsync(int projectId);
|
||||||
Task<PlotLineEditViewModel?> GetEditPlotLineAsync(int plotLineId);
|
Task<PlotLineEditViewModel?> GetEditPlotLineAsync(int plotLineId);
|
||||||
|
Task<PlotLineEditViewModel?> PopulatePlotLineFormAsync(PlotLineEditViewModel model);
|
||||||
Task<int> SavePlotLineAsync(PlotLineEditViewModel model);
|
Task<int> SavePlotLineAsync(PlotLineEditViewModel model);
|
||||||
Task ArchivePlotLineAsync(int plotLineId);
|
Task ArchivePlotLineAsync(int plotLineId);
|
||||||
Task<PlotThreadListViewModel?> GetPlotThreadsAsync(int projectId);
|
Task<PlotThreadListViewModel?> GetPlotThreadsAsync(int projectId);
|
||||||
@ -2099,6 +2100,27 @@ public sealed class PlotService(IProjectRepository projects, IBookRepository boo
|
|||||||
}, lookupData, plotLines.Where(x => x.PlotLineID != plotLine.PlotLineID));
|
}, lookupData, plotLines.Where(x => x.PlotLineID != plotLine.PlotLineID));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<PlotLineEditViewModel?> 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<int> SavePlotLineAsync(PlotLineEditViewModel model)
|
public async Task<int> SavePlotLineAsync(PlotLineEditViewModel model)
|
||||||
{
|
{
|
||||||
var isNew = model.PlotLineID == 0;
|
var isNew = model.PlotLineID == 0;
|
||||||
@ -2301,7 +2323,6 @@ public sealed class PlotService(IProjectRepository projects, IBookRepository boo
|
|||||||
|
|
||||||
private async Task<PlotLineEditViewModel> PopulatePlotLineListsAsync(PlotLineEditViewModel model, PlotLookupData lookupData, IEnumerable<PlotLineItem> parentCandidates)
|
private async Task<PlotLineEditViewModel> PopulatePlotLineListsAsync(PlotLineEditViewModel model, PlotLookupData lookupData, IEnumerable<PlotLineItem> 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.PlotImportance = ChapterService.ToSelectList(lookupData.PlotImportance, x => x.PlotImportanceID, x => x.ImportanceName);
|
||||||
model.BookOptions = (await books.ListByProjectAsync(model.ProjectID))
|
model.BookOptions = (await books.ListByProjectAsync(model.ProjectID))
|
||||||
.Select(x => new SelectListItem($"Book {x.BookNumber}: {x.BookTitle}", x.BookID.ToString()))
|
.Select(x => new SelectListItem($"Book {x.BookNumber}: {x.BookTitle}", x.BookID.ToString()))
|
||||||
|
|||||||
@ -692,7 +692,7 @@ public sealed class MetricGraphPointViewModel
|
|||||||
public int Percent { get; set; }
|
public int Percent { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class PlotLineEditViewModel
|
public sealed class PlotLineEditViewModel : IValidatableObject
|
||||||
{
|
{
|
||||||
public int PlotLineID { get; set; }
|
public int PlotLineID { get; set; }
|
||||||
public int ProjectID { get; set; }
|
public int ProjectID { get; set; }
|
||||||
@ -704,6 +704,7 @@ public sealed class PlotLineEditViewModel
|
|||||||
[Display(Name = "Type")]
|
[Display(Name = "Type")]
|
||||||
public int PlotLineTypeID { get; set; }
|
public int PlotLineTypeID { get; set; }
|
||||||
|
|
||||||
|
[Range(1, int.MaxValue, ErrorMessage = "Choose a plot importance.")]
|
||||||
[Display(Name = "Importance")]
|
[Display(Name = "Importance")]
|
||||||
public int PlotImportanceID { get; set; } = 2;
|
public int PlotImportanceID { get; set; } = 2;
|
||||||
|
|
||||||
@ -726,10 +727,19 @@ public sealed class PlotLineEditViewModel
|
|||||||
public bool IsVisibleOnTimeline { get; set; } = true;
|
public bool IsVisibleOnTimeline { get; set; } = true;
|
||||||
|
|
||||||
public Project? Project { get; set; }
|
public Project? Project { get; set; }
|
||||||
public IReadOnlyList<SelectListItem> PlotLineTypes { get; set; } = [];
|
|
||||||
public IReadOnlyList<SelectListItem> PlotImportance { get; set; } = [];
|
public IReadOnlyList<SelectListItem> PlotImportance { get; set; } = [];
|
||||||
public IReadOnlyList<SelectListItem> BookOptions { get; set; } = [];
|
public IReadOnlyList<SelectListItem> BookOptions { get; set; } = [];
|
||||||
public IReadOnlyList<SelectListItem> ParentPlotLineOptions { get; set; } = [];
|
public IReadOnlyList<SelectListItem> ParentPlotLineOptions { get; set; } = [];
|
||||||
|
|
||||||
|
public IEnumerable<ValidationResult> 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
|
public sealed class PlotLineListViewModel
|
||||||
|
|||||||
@ -37,6 +37,7 @@
|
|||||||
<form asp-action="Save" method="post" class="edit-panel">
|
<form asp-action="Save" method="post" class="edit-panel">
|
||||||
<input asp-for="PlotLineID" type="hidden" />
|
<input asp-for="PlotLineID" type="hidden" />
|
||||||
<input asp-for="ProjectID" type="hidden" />
|
<input asp-for="ProjectID" type="hidden" />
|
||||||
|
<input asp-for="PlotLineTypeID" type="hidden" />
|
||||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||||
<div class="row g-3">
|
<div class="row g-3">
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
@ -44,13 +45,12 @@
|
|||||||
<input asp-for="PlotLineName" class="form-control" />
|
<input asp-for="PlotLineName" class="form-control" />
|
||||||
<span asp-validation-for="PlotLineName" class="text-danger"></span>
|
<span asp-validation-for="PlotLineName" class="text-danger"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
|
||||||
<label asp-for="PlotLineTypeID" class="form-label">Type <help-icon key="plotLines.fields.type" mode="inline" /></label>
|
|
||||||
<select asp-for="PlotLineTypeID" asp-items="Model.PlotLineTypes" class="form-select"></select>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label asp-for="PlotImportanceID" class="form-label">Importance</label>
|
<label asp-for="PlotImportanceID" class="form-label">Importance</label>
|
||||||
<select asp-for="PlotImportanceID" asp-items="Model.PlotImportance" class="form-select"></select>
|
<select asp-for="PlotImportanceID" asp-items="Model.PlotImportance" class="form-select">
|
||||||
|
<option value="">Choose importance</option>
|
||||||
|
</select>
|
||||||
|
<span asp-validation-for="PlotImportanceID" class="text-danger"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label asp-for="BookID" class="form-label">Book / scope <help-icon key="plotLines.fields.scope" mode="inline" /></label>
|
<label asp-for="BookID" class="form-label">Book / scope <help-icon key="plotLines.fields.scope" mode="inline" /></label>
|
||||||
@ -69,6 +69,7 @@
|
|||||||
<select asp-for="EmergesFromPlotLineID" asp-items="Model.ParentPlotLineOptions" class="form-select">
|
<select asp-for="EmergesFromPlotLineID" asp-items="Model.ParentPlotLineOptions" class="form-select">
|
||||||
<option value="">None</option>
|
<option value="">None</option>
|
||||||
</select>
|
</select>
|
||||||
|
<span asp-validation-for="EmergesFromPlotLineID" class="text-danger"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-2">
|
<div class="col-md-2">
|
||||||
<label asp-for="SortOrder" class="form-label"></label>
|
<label asp-for="SortOrder" class="form-label"></label>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user