Scene inspector character attribute fix

This commit is contained in:
Nick Beckley 2026-06-19 14:08:46 +01:00
parent daeba6ee8a
commit 7363d0c128
5 changed files with 56 additions and 0 deletions

View File

@ -286,6 +286,29 @@ public sealed class ScenesController(
[ValidateAntiForgeryToken]
public async Task<IActionResult> AddCharacterAttributeEvent(CharacterAttributeEventCreateViewModel model)
{
if (model.SceneID <= 0)
{
return BadRequest();
}
if (model.CharacterID <= 0)
{
TempData["CharacterAttributeAddError"] = "Choose a character before adding an attribute.";
return RedirectForScene(model.SceneID, model.ReturnProjectID, model.ReturnBookID);
}
if (model.CharacterAttributeTypeID <= 0)
{
TempData["CharacterAttributeAddError"] = "Choose an attribute type before saving.";
return RedirectForScene(model.SceneID, model.ReturnProjectID, model.ReturnBookID);
}
if (string.IsNullOrWhiteSpace(model.AttributeValue))
{
TempData["CharacterAttributeAddError"] = "Enter an attribute value before saving.";
return RedirectForScene(model.SceneID, model.ReturnProjectID, model.ReturnBookID);
}
await characters.AddAttributeEventAsync(model);
return RedirectForScene(model.SceneID, model.ReturnProjectID, model.ReturnBookID);
}

View File

@ -174,6 +174,7 @@ public interface ICharacterRepository
Task<IReadOnlyList<SceneCharacter>> ListSceneCharactersAsync(int sceneId);
Task<int> SaveSceneCharacterAsync(SceneCharacter sceneCharacter);
Task DeleteSceneCharacterAsync(int sceneCharacterId);
Task<IReadOnlyList<CharacterAttributeEvent>> ListAttributeEventsBySceneAsync(int sceneId);
Task<IReadOnlyList<CharacterAttributeEvent>> ListAttributeEventsByCharacterAsync(int characterId);
Task<int> SaveAttributeEventAsync(CharacterAttributeEvent attributeEvent);
Task<IReadOnlyList<CharacterKnowledgeItem>> ListKnowledgeBySceneAsync(int sceneId);
@ -3254,6 +3255,13 @@ public sealed class CharacterRepository(ISqlConnectionFactory connectionFactory)
return rows.ToList();
}
public async Task<IReadOnlyList<CharacterAttributeEvent>> ListAttributeEventsBySceneAsync(int sceneId)
{
using var connection = connectionFactory.CreateConnection();
var rows = await connection.QueryAsync<CharacterAttributeEvent>("dbo.CharacterAttributeEvent_ListByScene", new { SceneID = sceneId }, commandType: CommandType.StoredProcedure);
return rows.ToList();
}
public async Task<int> SaveAttributeEventAsync(CharacterAttributeEvent attributeEvent)
{
using var connection = connectionFactory.CreateConnection();

View File

@ -1540,6 +1540,7 @@ public sealed class SceneService(
model.AssetCustodyEvents = model.SceneID == 0 ? [] : await assets.ListCustodyBySceneAsync(model.SceneID);
model.SceneAssetLocations = model.SceneID == 0 ? [] : await locations.ListSceneAssetLocationsAsync(model.SceneID);
model.SceneCharacters = model.SceneID == 0 ? [] : await characters.ListSceneCharactersAsync(model.SceneID);
model.CharacterAttributeEvents = model.SceneID == 0 ? [] : await characters.ListAttributeEventsBySceneAsync(model.SceneID);
model.Warnings = model.SceneID == 0 ? [] : await warnings.ListBySceneAsync(model.SceneID);
model.AgeContinuityWarnings = await BuildAgeContinuityWarningsAsync(model);
var sceneDependencyRows = model.SceneID == 0 ? [] : await sceneDependencies.ListBySceneAsync(model.SceneID);

View File

@ -0,0 +1,19 @@
CREATE OR ALTER PROCEDURE dbo.CharacterAttributeEvent_ListByScene
@SceneID int
AS
BEGIN
SET NOCOUNT ON;
SELECT cae.CharacterAttributeEventID, cae.CharacterID, ch.CharacterName, cae.CharacterAttributeTypeID,
cat.AttributeName, cae.SceneID, s.SceneNumber, s.SceneTitle, c.ChapterNumber, b.BookTitle, b.Subtitle AS BookSubtitle,
cae.AttributeValue, cae.Description, cae.CreatedDate, cae.UpdatedDate
FROM dbo.CharacterAttributeEvents cae
INNER JOIN dbo.Characters ch ON ch.CharacterID = cae.CharacterID
INNER JOIN dbo.CharacterAttributeTypes cat ON cat.CharacterAttributeTypeID = cae.CharacterAttributeTypeID
INNER JOIN dbo.Scenes s ON s.SceneID = cae.SceneID
INNER JOIN dbo.Chapters c ON c.ChapterID = s.ChapterID
INNER JOIN dbo.Books b ON b.BookID = c.BookID
WHERE cae.SceneID = @SceneID
ORDER BY ch.CharacterName, cat.SortOrder, cae.CreatedDate;
END;
GO

View File

@ -566,6 +566,11 @@
<input type="hidden" name="SceneID" value="@Model.SceneID" />
<input type="hidden" name="ReturnProjectID" value="@Model.ReturnProjectID" />
<input type="hidden" name="ReturnBookID" value="@Model.ReturnBookID" />
<input type="hidden" name="ReturnUrl" value="@(Context.Request.Path + Context.Request.QueryString)" />
@if (TempData["CharacterAttributeAddError"] is string addCharacterAttributeError)
{
<p class="text-danger form-helper-message">@addCharacterAttributeError</p>
}
<div class="row g-2">
<div class="col-12">
<select class="form-select form-select-sm" name="CharacterID" asp-items="Model.CharacterOptions"></select>