Implement a small display fix caused by Phase 13A book subtitles.
This commit is contained in:
parent
2b145731e3
commit
dca5b0a847
@ -592,6 +592,7 @@ public sealed class WarningRepository(ISqlConnectionFactory connectionFactory) :
|
||||
cw.ProjectID,
|
||||
cw.BookID,
|
||||
b.BookTitle,
|
||||
b.Subtitle AS BookSubtitle,
|
||||
cw.ChapterID,
|
||||
c.ChapterNumber,
|
||||
c.ChapterTitle,
|
||||
@ -1148,6 +1149,7 @@ public sealed class WritingScheduleRepository(ISqlConnectionFactory connectionFa
|
||||
p.ProjectName,
|
||||
wp.BookID,
|
||||
b.BookTitle,
|
||||
b.Subtitle AS BookSubtitle,
|
||||
wp.PlanName,
|
||||
wp.GoalType,
|
||||
wp.StartDate,
|
||||
@ -1168,6 +1170,7 @@ public sealed class WritingScheduleRepository(ISqlConnectionFactory connectionFa
|
||||
p.ProjectName,
|
||||
wp.BookID,
|
||||
b.BookTitle,
|
||||
b.Subtitle,
|
||||
wp.PlanName,
|
||||
wp.GoalType,
|
||||
wp.StartDate,
|
||||
@ -1274,6 +1277,7 @@ public sealed class WritingScheduleRepository(ISqlConnectionFactory connectionFa
|
||||
p.ProjectName,
|
||||
wp.BookID,
|
||||
b.BookTitle,
|
||||
b.Subtitle AS BookSubtitle,
|
||||
wp.PlanName,
|
||||
wp.DeadlineDate,
|
||||
wp.IsActive
|
||||
@ -1299,6 +1303,7 @@ public sealed class WritingScheduleRepository(ISqlConnectionFactory connectionFa
|
||||
wsi.ScheduledDate,
|
||||
wsi.TaskType,
|
||||
b.BookTitle,
|
||||
b.Subtitle AS BookSubtitle,
|
||||
c.ChapterNumber,
|
||||
c.ChapterTitle,
|
||||
s.SceneNumber,
|
||||
@ -1341,6 +1346,7 @@ public sealed class WritingScheduleRepository(ISqlConnectionFactory connectionFa
|
||||
wsi.ScheduledDate,
|
||||
wsi.TaskType,
|
||||
b.BookTitle,
|
||||
b.Subtitle AS BookSubtitle,
|
||||
c.ChapterNumber,
|
||||
c.ChapterTitle,
|
||||
c.SortOrder AS ChapterSortOrder,
|
||||
@ -1403,6 +1409,7 @@ public sealed class WritingScheduleRepository(ISqlConnectionFactory connectionFa
|
||||
p.ProjectName,
|
||||
wp.BookID,
|
||||
b.BookTitle,
|
||||
b.Subtitle AS BookSubtitle,
|
||||
wp.PlanName,
|
||||
wp.DeadlineDate,
|
||||
wp.IsActive
|
||||
|
||||
@ -1,5 +1,20 @@
|
||||
namespace PlotLine.Models;
|
||||
|
||||
public static class BookTitleFormatter
|
||||
{
|
||||
public static string DisplayTitle(string? title, string? subtitle)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(title))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return string.IsNullOrWhiteSpace(subtitle)
|
||||
? title
|
||||
: $"{title}: {subtitle}";
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class Project
|
||||
{
|
||||
public int ProjectID { get; set; }
|
||||
@ -213,6 +228,7 @@ public sealed class Book
|
||||
public int ProjectID { get; set; }
|
||||
public string BookTitle { get; set; } = string.Empty;
|
||||
public string? Subtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, Subtitle);
|
||||
public string? Tagline { get; set; }
|
||||
public string? ShortDescription { get; set; }
|
||||
public string Status { get; set; } = BookStatuses.Planning;
|
||||
@ -596,6 +612,8 @@ public sealed class SceneOption
|
||||
{
|
||||
public int SceneID { get; set; }
|
||||
public string BookTitle { get; set; } = string.Empty;
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public decimal ChapterNumber { get; set; }
|
||||
public string ChapterTitle { get; set; } = string.Empty;
|
||||
public decimal SceneNumber { get; set; }
|
||||
@ -684,6 +702,8 @@ public sealed class AssetEvent
|
||||
public string EventTitle { get; set; } = string.Empty;
|
||||
public string? EventDescription { get; set; }
|
||||
public string? BookTitle { get; set; }
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public decimal ChapterNumber { get; set; }
|
||||
public decimal SceneNumber { get; set; }
|
||||
public string SceneTitle { get; set; } = string.Empty;
|
||||
@ -749,6 +769,8 @@ public sealed class AssetCustodyEvent
|
||||
public string? Description { get; set; }
|
||||
public string? CustodianSummary { get; set; }
|
||||
public string? BookTitle { get; set; }
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public decimal ChapterNumber { get; set; }
|
||||
public decimal SceneNumber { get; set; }
|
||||
public string SceneTitle { get; set; } = string.Empty;
|
||||
@ -857,6 +879,8 @@ public sealed class SceneCharacter
|
||||
public string SceneTitle { get; set; } = string.Empty;
|
||||
public decimal ChapterNumber { get; set; }
|
||||
public string BookTitle { get; set; } = string.Empty;
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public DateTime CreatedDate { get; set; }
|
||||
public DateTime UpdatedDate { get; set; }
|
||||
}
|
||||
@ -884,6 +908,8 @@ public sealed class CharacterAttributeEvent
|
||||
public string SceneTitle { get; set; } = string.Empty;
|
||||
public decimal ChapterNumber { get; set; }
|
||||
public string BookTitle { get; set; } = string.Empty;
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public string AttributeValue { get; set; } = string.Empty;
|
||||
public string? Description { get; set; }
|
||||
public DateTime CreatedDate { get; set; }
|
||||
@ -912,6 +938,8 @@ public sealed class CharacterKnowledgeItem
|
||||
public string SceneTitle { get; set; } = string.Empty;
|
||||
public decimal ChapterNumber { get; set; }
|
||||
public string BookTitle { get; set; } = string.Empty;
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public int KnowledgeStateID { get; set; }
|
||||
public string KnowledgeStateName { get; set; } = string.Empty;
|
||||
public int? SourceEventID { get; set; }
|
||||
@ -970,6 +998,8 @@ public sealed class CharacterRelationship
|
||||
public bool IsInitialRelationship { get; set; }
|
||||
public int? InitialBookID { get; set; }
|
||||
public string? InitialBookTitle { get; set; }
|
||||
public string? InitialBookSubtitle { get; set; }
|
||||
public string InitialBookDisplayTitle => BookTitleFormatter.DisplayTitle(InitialBookTitle, InitialBookSubtitle);
|
||||
public bool ReaderInitiallyKnows { get; set; }
|
||||
public int? InitialRelationshipStateID { get; set; }
|
||||
public string? InitialRelationshipStateName { get; set; }
|
||||
@ -1002,6 +1032,8 @@ public sealed class RelationshipEvent
|
||||
public string SceneTitle { get; set; } = string.Empty;
|
||||
public decimal ChapterNumber { get; set; }
|
||||
public string BookTitle { get; set; } = string.Empty;
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public int RelationshipStateID { get; set; }
|
||||
public string RelationshipStateName { get; set; } = string.Empty;
|
||||
public int? Intensity { get; set; }
|
||||
@ -1135,6 +1167,8 @@ public sealed class ContinuityWarning
|
||||
public int ProjectID { get; set; }
|
||||
public int? BookID { get; set; }
|
||||
public string? BookTitle { get; set; }
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public int? ChapterID { get; set; }
|
||||
public decimal? ChapterNumber { get; set; }
|
||||
public string? ChapterTitle { get; set; }
|
||||
@ -1210,12 +1244,16 @@ public sealed class SceneDependency
|
||||
public string? DependencyDirection { get; set; }
|
||||
public int SourceBookID { get; set; }
|
||||
public string SourceBookTitle { get; set; } = string.Empty;
|
||||
public string? SourceBookSubtitle { get; set; }
|
||||
public string SourceBookDisplayTitle => BookTitleFormatter.DisplayTitle(SourceBookTitle, SourceBookSubtitle);
|
||||
public int SourceChapterID { get; set; }
|
||||
public decimal SourceChapterNumber { get; set; }
|
||||
public decimal SourceSceneNumber { get; set; }
|
||||
public string SourceSceneTitle { get; set; } = string.Empty;
|
||||
public int TargetBookID { get; set; }
|
||||
public string TargetBookTitle { get; set; } = string.Empty;
|
||||
public string? TargetBookSubtitle { get; set; }
|
||||
public string TargetBookDisplayTitle => BookTitleFormatter.DisplayTitle(TargetBookTitle, TargetBookSubtitle);
|
||||
public int TargetChapterID { get; set; }
|
||||
public decimal TargetChapterNumber { get; set; }
|
||||
public decimal TargetSceneNumber { get; set; }
|
||||
@ -1241,6 +1279,8 @@ public sealed class ChapterOption
|
||||
public int ChapterID { get; set; }
|
||||
public int BookID { get; set; }
|
||||
public string BookTitle { get; set; } = string.Empty;
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public int BookNumber { get; set; }
|
||||
public decimal ChapterNumber { get; set; }
|
||||
public string ChapterTitle { get; set; } = string.Empty;
|
||||
@ -1256,11 +1296,15 @@ public sealed class SceneMovePreview
|
||||
public string SourceChapterTitle { get; set; } = string.Empty;
|
||||
public int SourceBookID { get; set; }
|
||||
public string SourceBookTitle { get; set; } = string.Empty;
|
||||
public string? SourceBookSubtitle { get; set; }
|
||||
public string SourceBookDisplayTitle => BookTitleFormatter.DisplayTitle(SourceBookTitle, SourceBookSubtitle);
|
||||
public int TargetChapterID { get; set; }
|
||||
public decimal TargetChapterNumber { get; set; }
|
||||
public string TargetChapterTitle { get; set; } = string.Empty;
|
||||
public int TargetBookID { get; set; }
|
||||
public string TargetBookTitle { get; set; } = string.Empty;
|
||||
public string? TargetBookSubtitle { get; set; }
|
||||
public string TargetBookDisplayTitle => BookTitleFormatter.DisplayTitle(TargetBookTitle, TargetBookSubtitle);
|
||||
public string Position { get; set; } = "End";
|
||||
public int DependencyCount { get; set; }
|
||||
public int ActiveWarningCount { get; set; }
|
||||
@ -1271,6 +1315,8 @@ public sealed class AnalyticsMetricPoint
|
||||
public int SceneID { get; set; }
|
||||
public int BookID { get; set; }
|
||||
public string BookTitle { get; set; } = string.Empty;
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public int ChapterID { get; set; }
|
||||
public decimal ChapterNumber { get; set; }
|
||||
public string ChapterTitle { get; set; } = string.Empty;
|
||||
@ -1299,6 +1345,8 @@ public sealed class AnalyticsRevisionScene
|
||||
public int SceneID { get; set; }
|
||||
public int BookID { get; set; }
|
||||
public string BookTitle { get; set; } = string.Empty;
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public int ChapterID { get; set; }
|
||||
public decimal ChapterNumber { get; set; }
|
||||
public decimal SceneNumber { get; set; }
|
||||
@ -1319,6 +1367,8 @@ public sealed class AnalyticsSceneGap
|
||||
public int SceneID { get; set; }
|
||||
public int BookID { get; set; }
|
||||
public string BookTitle { get; set; } = string.Empty;
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public int ChapterID { get; set; }
|
||||
public decimal ChapterNumber { get; set; }
|
||||
public decimal SceneNumber { get; set; }
|
||||
@ -1384,6 +1434,8 @@ public sealed class AnalyticsWarningHotspot
|
||||
public string SceneTitle { get; set; } = string.Empty;
|
||||
public decimal ChapterNumber { get; set; }
|
||||
public string BookTitle { get; set; } = string.Empty;
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public int WarningCount { get; set; }
|
||||
public int HighestSeveritySort { get; set; }
|
||||
}
|
||||
@ -1510,6 +1562,8 @@ public sealed class StoryBibleTimelineSummary
|
||||
{
|
||||
public int BookID { get; set; }
|
||||
public string BookTitle { get; set; } = string.Empty;
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public int ChapterID { get; set; }
|
||||
public decimal ChapterNumber { get; set; }
|
||||
public string ChapterTitle { get; set; } = string.Empty;
|
||||
@ -1645,6 +1699,8 @@ public sealed class WriterDashboardScene
|
||||
public string ProjectName { get; set; } = string.Empty;
|
||||
public int BookID { get; set; }
|
||||
public string BookTitle { get; set; } = string.Empty;
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public int ChapterID { get; set; }
|
||||
public decimal ChapterNumber { get; set; }
|
||||
public string ChapterTitle { get; set; } = string.Empty;
|
||||
@ -1720,6 +1776,8 @@ public sealed class WritingPlanSummary
|
||||
public string ProjectName { get; set; } = string.Empty;
|
||||
public int? BookID { get; set; }
|
||||
public string? BookTitle { get; set; }
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public string PlanName { get; set; } = string.Empty;
|
||||
public DateTime DeadlineDate { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
@ -1733,6 +1791,8 @@ public sealed class WritingPlanManagementItem
|
||||
public string ProjectName { get; set; } = string.Empty;
|
||||
public int? BookID { get; set; }
|
||||
public string? BookTitle { get; set; }
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public string PlanName { get; set; } = string.Empty;
|
||||
public string GoalType { get; set; } = string.Empty;
|
||||
public DateTime StartDate { get; set; }
|
||||
@ -1753,6 +1813,8 @@ public sealed class WritingSchedulePreviewItem
|
||||
public DateTime ScheduledDate { get; set; }
|
||||
public string TaskType { get; set; } = string.Empty;
|
||||
public string BookTitle { get; set; } = string.Empty;
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public decimal ChapterNumber { get; set; }
|
||||
public string ChapterTitle { get; set; } = string.Empty;
|
||||
public decimal SceneNumber { get; set; }
|
||||
@ -1774,6 +1836,8 @@ public sealed class WritingScheduleDashboardItem
|
||||
public DateTime ScheduledDate { get; set; }
|
||||
public string TaskType { get; set; } = string.Empty;
|
||||
public string BookTitle { get; set; } = string.Empty;
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public decimal ChapterNumber { get; set; }
|
||||
public string ChapterTitle { get; set; } = string.Empty;
|
||||
public int ChapterSortOrder { get; set; }
|
||||
@ -1818,6 +1882,8 @@ public sealed class ExportSceneBriefHeader
|
||||
public string ProjectName { get; set; } = string.Empty;
|
||||
public int BookID { get; set; }
|
||||
public string BookTitle { get; set; } = string.Empty;
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public int ChapterID { get; set; }
|
||||
public decimal ChapterNumber { get; set; }
|
||||
public string ChapterTitle { get; set; } = string.Empty;
|
||||
@ -1852,6 +1918,8 @@ public sealed class ExportChapterBriefHeader
|
||||
public string ProjectName { get; set; } = string.Empty;
|
||||
public int BookID { get; set; }
|
||||
public string BookTitle { get; set; } = string.Empty;
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public int ChapterID { get; set; }
|
||||
public decimal ChapterNumber { get; set; }
|
||||
public string ChapterTitle { get; set; } = string.Empty;
|
||||
@ -1867,6 +1935,8 @@ public sealed class ExportChapterBriefHeader
|
||||
public sealed class ExportResearchItem
|
||||
{
|
||||
public string BookTitle { get; set; } = string.Empty;
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public decimal ChapterNumber { get; set; }
|
||||
public string ChapterTitle { get; set; } = string.Empty;
|
||||
public int SceneID { get; set; }
|
||||
@ -1905,6 +1975,8 @@ public sealed class CharacterArcPoint
|
||||
{
|
||||
public int SceneID { get; set; }
|
||||
public string BookTitle { get; set; } = string.Empty;
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public decimal ChapterNumber { get; set; }
|
||||
public decimal SceneNumber { get; set; }
|
||||
public string SceneTitle { get; set; } = string.Empty;
|
||||
@ -1930,6 +2002,8 @@ public sealed class RelationshipProgressionPoint
|
||||
public int CharacterRelationshipID { get; set; }
|
||||
public int SceneID { get; set; }
|
||||
public string BookTitle { get; set; } = string.Empty;
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public decimal ChapterNumber { get; set; }
|
||||
public decimal SceneNumber { get; set; }
|
||||
public string SceneTitle { get; set; } = string.Empty;
|
||||
@ -1976,6 +2050,8 @@ public sealed class Scenario
|
||||
public DateTime UpdatedDate { get; set; }
|
||||
public string ProjectName { get; set; } = string.Empty;
|
||||
public string? BookTitle { get; set; }
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public int SceneCount { get; set; }
|
||||
public int WarningCount { get; set; }
|
||||
}
|
||||
@ -2038,6 +2114,8 @@ public sealed class ArchivedItem
|
||||
public string? ProjectName { get; set; }
|
||||
public int? BookID { get; set; }
|
||||
public string? BookTitle { get; set; }
|
||||
public string? BookSubtitle { get; set; }
|
||||
public string BookDisplayTitle => BookTitleFormatter.DisplayTitle(BookTitle, BookSubtitle);
|
||||
public DateTime? ArchivedDate { get; set; }
|
||||
public string? ArchivedReason { get; set; }
|
||||
public DateTime UpdatedDate { get; set; }
|
||||
|
||||
@ -646,7 +646,7 @@ public sealed class ProjectService(
|
||||
: $"Chapter {warning.ChapterNumber.Value:g}: {warning.ChapterTitle}";
|
||||
}
|
||||
|
||||
return warning.BookTitle ?? warning.EntityType;
|
||||
return string.IsNullOrWhiteSpace(warning.BookDisplayTitle) ? warning.EntityType : warning.BookDisplayTitle;
|
||||
}
|
||||
|
||||
private static string RelativeTimeLabel(DateTime createdDateUtc)
|
||||
@ -1577,8 +1577,8 @@ public sealed class SceneService(
|
||||
model.RelationshipTypeOptions = ToRelationshipTypeSelectList(characterLookups.RelationshipTypes);
|
||||
model.RelationshipStateOptions = ChapterService.ToSelectList(characterLookups.RelationshipStates, x => x.RelationshipStateID, x => x.StateName);
|
||||
model.LocationOptions = ToOptionalSelectList(projectLocations, x => x.LocationID, x => new string(' ', x.Depth * 2) + x.LocationName);
|
||||
model.SceneOptions = ToOptionalSelectList(allSceneOptions.Where(x => x.SceneID != model.SceneID), x => x.SceneID, x => $"{x.BookTitle} / Ch {x.ChapterNumber} / Scene {x.SceneNumber}: {x.SceneTitle}");
|
||||
model.ChapterOptions = ChapterService.ToSelectList(chapterOptions, x => x.ChapterID, x => $"{x.BookTitle} / Chapter {x.ChapterNumber}: {x.ChapterTitle}");
|
||||
model.SceneOptions = ToOptionalSelectList(allSceneOptions.Where(x => x.SceneID != model.SceneID), x => x.SceneID, x => $"{x.BookDisplayTitle} / Ch {x.ChapterNumber} / Scene {x.SceneNumber}: {x.SceneTitle}");
|
||||
model.ChapterOptions = ChapterService.ToSelectList(chapterOptions, x => x.ChapterID, x => $"{x.BookDisplayTitle} / Chapter {x.ChapterNumber}: {x.ChapterTitle}");
|
||||
model.SceneDependencyTypeOptions = ChapterService.ToSelectList(dependencyLookups.DependencyTypes, x => x.SceneDependencyTypeID, x => x.TypeName);
|
||||
model.NewThreadEvent = new ThreadEventCreateViewModel
|
||||
{
|
||||
@ -1971,7 +1971,7 @@ public sealed class TimelineService(
|
||||
SelectedSceneID = selectedScene?.SceneID,
|
||||
SelectedScene = selectedScene,
|
||||
Filter = filter,
|
||||
BookOptions = allBooks.Select(x => new SelectListItem($"Book {x.BookNumber}: {x.BookTitle}", x.BookID.ToString(), x.BookID == bookId)).ToList(),
|
||||
BookOptions = allBooks.Select(x => new SelectListItem($"Book {x.BookNumber}: {x.BookDisplayTitle}", x.BookID.ToString(), x.BookID == bookId)).ToList(),
|
||||
ChapterOptions = timeline.Chapters.Select(x => new SelectListItem($"Ch {x.ChapterNumber}: {x.ChapterTitle}", x.ChapterID.ToString())).ToList(),
|
||||
ChapterFromOptions = timeline.Chapters.Select(x => new SelectListItem($"Ch {x.ChapterNumber}: {x.ChapterTitle}", x.ChapterID.ToString(), x.ChapterID == filter.ChapterFromID)).ToList(),
|
||||
ChapterToOptions = timeline.Chapters.Select(x => new SelectListItem($"Ch {x.ChapterNumber}: {x.ChapterTitle}", x.ChapterID.ToString(), x.ChapterID == filter.ChapterToID)).ToList(),
|
||||
@ -2631,7 +2631,7 @@ public sealed class StoryStateService(
|
||||
Filter = filter,
|
||||
ShowBookContext = ShouldShowBookContext(filter, scopedScenes, timeline.Chapters),
|
||||
ShowChapterContext = ShouldShowChapterContext(filter, scopedScenes, timeline.Chapters),
|
||||
BookOptions = timeline.Books.Select(x => new SelectListItem($"Book {x.BookNumber}: {x.BookTitle}", x.BookID.ToString(), x.BookID == filter.BookID)).ToList(),
|
||||
BookOptions = timeline.Books.Select(x => new SelectListItem($"Book {x.BookNumber}: {x.BookDisplayTitle}", x.BookID.ToString(), x.BookID == filter.BookID)).ToList(),
|
||||
ChapterOptions = timeline.Chapters.Select(x => new SelectListItem($"Ch {x.ChapterNumber}: {x.ChapterTitle}", x.ChapterID.ToString(), x.ChapterID == filter.ChapterID)).ToList(),
|
||||
SceneOptions = orderedScenes.Select(x => new SelectListItem($"Scene {x.SceneNumber:g}: {x.SceneTitle}", x.SceneID.ToString(), x.SceneID == filter.SelectedSceneID)).ToList(),
|
||||
CharacterOptions = allCharacters.Select(x => new SelectListItem(x.CharacterName, x.CharacterID.ToString(), filter.CharacterIDs.Contains(x.CharacterID))).ToList(),
|
||||
@ -3732,7 +3732,7 @@ public sealed class StoryStateService(
|
||||
|
||||
return new SceneContext(
|
||||
book?.BookID ?? 0,
|
||||
book is null ? string.Empty : $"Book {book.BookNumber}: {book.BookTitle}",
|
||||
book is null ? string.Empty : $"Book {book.BookNumber}: {book.BookDisplayTitle}",
|
||||
chapter?.ChapterID ?? 0,
|
||||
chapter is null ? string.Empty : $"Ch {chapter.ChapterNumber:g}: {chapter.ChapterTitle}",
|
||||
scene.SceneID,
|
||||
@ -4289,7 +4289,7 @@ public sealed class PlotService(IProjectRepository projects, IBookRepository boo
|
||||
{
|
||||
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()))
|
||||
.Select(x => new SelectListItem($"Book {x.BookNumber}: {x.BookDisplayTitle}", x.BookID.ToString()))
|
||||
.ToList();
|
||||
model.ParentPlotLineOptions = parentCandidates
|
||||
.Select(x => new SelectListItem(x.PlotLineName, x.PlotLineID.ToString()))
|
||||
@ -4304,7 +4304,7 @@ public sealed class PlotService(IProjectRepository projects, IBookRepository boo
|
||||
model.ThreadTypeOptions = ChapterService.ToSelectList(lookupData.ThreadTypes, x => x.ThreadTypeID, x => x.TypeName);
|
||||
model.ThreadStatusOptions = ChapterService.ToSelectList(lookupData.ThreadStatuses, x => x.ThreadStatusID, x => x.StatusName);
|
||||
model.SceneOptions = (await plots.ListSceneOptionsAsync(model.ProjectID))
|
||||
.Select(x => new SelectListItem($"{x.BookTitle} / Ch {x.ChapterNumber} / Scene {x.SceneNumber}: {x.SceneTitle}", x.SceneID.ToString()))
|
||||
.Select(x => new SelectListItem($"{x.BookDisplayTitle} / Ch {x.ChapterNumber} / Scene {x.SceneNumber}: {x.SceneTitle}", x.SceneID.ToString()))
|
||||
.ToList();
|
||||
return model;
|
||||
}
|
||||
@ -4393,7 +4393,7 @@ public sealed class ContinuityValidationService(
|
||||
Warnings = rows,
|
||||
ProjectWarnings = dashboardWarnings,
|
||||
WarningGroups = BuildWarningSeverityGroups(dashboardWarnings),
|
||||
BookOptions = projectBooks.Select(x => new SelectListItem($"Book {x.BookNumber}: {x.BookTitle}", x.BookID.ToString(), x.BookID == bookId)).ToList(),
|
||||
BookOptions = projectBooks.Select(x => new SelectListItem($"Book {x.BookNumber}: {x.BookDisplayTitle}", x.BookID.ToString(), x.BookID == bookId)).ToList(),
|
||||
ChapterOptions = projectChapters.Select(x => new SelectListItem($"Ch {x.ChapterNumber:g}: {x.ChapterTitle}", x.ChapterID.ToString(), x.ChapterID == chapterId)).ToList(),
|
||||
WarningTypeOptions = lookupData.WarningTypes.Select(x => new SelectListItem(x.TypeName, x.WarningTypeID.ToString(), x.WarningTypeID == warningTypeId)).ToList(),
|
||||
SeverityOptions = lookupData.Severities.Select(x => new SelectListItem(x.SeverityName, x.WarningSeverityID.ToString(), x.WarningSeverityID == warningSeverityId)).ToList(),
|
||||
@ -4441,8 +4441,8 @@ public sealed class ContinuityValidationService(
|
||||
IReadOnlyDictionary<int, Chapter> chaptersById)
|
||||
{
|
||||
var bookDisplayName = warning.BookID.HasValue && booksById.TryGetValue(warning.BookID.Value, out var book)
|
||||
? $"Book {book.BookNumber:g}: {book.BookTitle}"
|
||||
: warning.BookTitle ?? string.Empty;
|
||||
? $"Book {book.BookNumber:g}: {book.BookDisplayTitle}"
|
||||
: warning.BookDisplayTitle;
|
||||
var chapterDisplayName = warning.ChapterID.HasValue && chaptersById.TryGetValue(warning.ChapterID.Value, out var chapter)
|
||||
? $"Chapter {chapter.ChapterNumber:g}: {chapter.ChapterTitle}"
|
||||
: warning.ChapterNumber.HasValue
|
||||
@ -4587,7 +4587,7 @@ public sealed class ContinuityValidationService(
|
||||
|
||||
if (string.IsNullOrWhiteSpace(bookDisplayName) && bookId.HasValue && booksById.TryGetValue(bookId.Value, out var book))
|
||||
{
|
||||
bookDisplayName = $"Book {book.BookNumber:g}: {book.BookTitle}";
|
||||
bookDisplayName = $"Book {book.BookNumber:g}: {book.BookDisplayTitle}";
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(chapterDisplayName) && chapterId.HasValue && chaptersById.TryGetValue(chapterId.Value, out var chapter))
|
||||
@ -4918,7 +4918,7 @@ public sealed class AnalyticsService(IProjectRepository projects, IBookRepositor
|
||||
EndChapterNumber = endChapterNumber,
|
||||
StartSceneNumber = startSceneNumber,
|
||||
EndSceneNumber = endSceneNumber,
|
||||
BookOptions = (await books.ListByProjectAsync(projectId)).Select(x => new SelectListItem($"Book {x.BookNumber}: {x.BookTitle}", x.BookID.ToString(), x.BookID == bookId)).ToList(),
|
||||
BookOptions = (await books.ListByProjectAsync(projectId)).Select(x => new SelectListItem($"Book {x.BookNumber}: {x.BookDisplayTitle}", x.BookID.ToString(), x.BookID == bookId)).ToList(),
|
||||
MetricGraphs = data.MetricPoints
|
||||
.GroupBy(x => x.MetricName)
|
||||
.Select(x => new AnalyticsMetricGraphViewModel { MetricName = x.Key, Points = x.OrderBy(p => p.GlobalSceneIndex).ToList() })
|
||||
@ -5091,7 +5091,7 @@ public sealed class RelationshipMapService(IProjectRepository projects, ICharact
|
||||
FocusCharacterID = focusCharacterId,
|
||||
ShowFullNetwork = showFullNetwork,
|
||||
StoryPointLabel = point.Label,
|
||||
BookOptions = data.Books.OrderBy(x => x.SortOrder).ThenBy(x => x.BookNumber).Select(x => new SelectListItem($"Book {x.BookNumber}: {x.BookTitle}", x.BookID.ToString(), x.BookID == point.BookID)).ToList(),
|
||||
BookOptions = data.Books.OrderBy(x => x.SortOrder).ThenBy(x => x.BookNumber).Select(x => new SelectListItem($"Book {x.BookNumber}: {x.BookDisplayTitle}", x.BookID.ToString(), x.BookID == point.BookID)).ToList(),
|
||||
ChapterOptions = data.Chapters.OrderBy(x => BookSort(data, x.BookID)).ThenBy(x => x.SortOrder).Select(x => new SelectListItem($"Ch {x.ChapterNumber}: {x.ChapterTitle}", x.ChapterID.ToString(), x.ChapterID == point.ChapterID)).ToList(),
|
||||
SceneOptions = data.Scenes.OrderBy(x => SceneIndex(sceneOrder, x.SceneID)).Select(x => new SelectListItem($"Ch {ChapterNumber(data, x.ChapterID)} / Scene {x.SceneNumber}: {x.SceneTitle}", x.SceneID.ToString(), x.SceneID == point.SceneID)).ToList(),
|
||||
CharacterOptions = data.Characters.OrderBy(x => x.CharacterName).Select(x => new SelectListItem(x.CharacterName, x.CharacterID.ToString(), x.CharacterID == focusCharacterId)).ToList(),
|
||||
@ -5148,7 +5148,7 @@ public sealed class RelationshipMapService(IProjectRepository projects, ICharact
|
||||
};
|
||||
history.AddRange(visibleEvents.Select(x => new RelationshipMapHistoryItemViewModel
|
||||
{
|
||||
Label = $"{x.BookTitle} / Ch {x.ChapterNumber} / Scene {x.SceneNumber}: {x.SceneTitle}",
|
||||
Label = $"{x.BookDisplayTitle} / Ch {x.ChapterNumber} / Scene {x.SceneNumber}: {x.SceneTitle}",
|
||||
StateName = x.RelationshipStateName,
|
||||
Intensity = x.Intensity,
|
||||
Notes = x.Description,
|
||||
@ -5195,7 +5195,7 @@ public sealed class RelationshipMapService(IProjectRepository projects, ICharact
|
||||
var scene = data.Scenes.First(x => x.SceneID == sceneId.Value);
|
||||
var chapter = data.Chapters.FirstOrDefault(x => x.ChapterID == scene.ChapterID);
|
||||
var book = chapter is null ? null : data.Books.FirstOrDefault(x => x.BookID == chapter.BookID);
|
||||
return (book?.BookID, chapter?.ChapterID, scene.SceneID, sceneOrder[scene.SceneID], $"{book?.BookTitle ?? "Book"} / Ch {chapter?.ChapterNumber} / Scene {scene.SceneNumber}");
|
||||
return (book?.BookID, chapter?.ChapterID, scene.SceneID, sceneOrder[scene.SceneID], $"{book?.BookDisplayTitle ?? "Book"} / Ch {chapter?.ChapterNumber} / Scene {scene.SceneNumber}");
|
||||
}
|
||||
|
||||
if (chapterId.HasValue)
|
||||
@ -5205,7 +5205,7 @@ public sealed class RelationshipMapService(IProjectRepository projects, ICharact
|
||||
{
|
||||
var chapter = data.Chapters.FirstOrDefault(x => x.ChapterID == chapterId.Value);
|
||||
var book = chapter is null ? null : data.Books.FirstOrDefault(x => x.BookID == chapter.BookID);
|
||||
return (book?.BookID, chapter?.ChapterID, null, chapterScenes.Max(x => sceneOrder[x.SceneID]), $"End of {book?.BookTitle ?? "Book"} / Ch {chapter?.ChapterNumber}");
|
||||
return (book?.BookID, chapter?.ChapterID, null, chapterScenes.Max(x => sceneOrder[x.SceneID]), $"End of {book?.BookDisplayTitle ?? "Book"} / Ch {chapter?.ChapterNumber}");
|
||||
}
|
||||
}
|
||||
|
||||
@ -5216,7 +5216,7 @@ public sealed class RelationshipMapService(IProjectRepository projects, ICharact
|
||||
if (bookScenes.Count > 0)
|
||||
{
|
||||
var book = data.Books.FirstOrDefault(x => x.BookID == bookId.Value);
|
||||
return (book?.BookID, null, null, bookScenes.Max(x => sceneOrder[x.SceneID]), $"End of {book?.BookTitle ?? "Book"}");
|
||||
return (book?.BookID, null, null, bookScenes.Max(x => sceneOrder[x.SceneID]), $"End of {book?.BookDisplayTitle ?? "Book"}");
|
||||
}
|
||||
}
|
||||
|
||||
@ -5580,7 +5580,7 @@ public sealed class WritingScheduleService(
|
||||
WritingPlanID = plan.WritingPlanID,
|
||||
PlanName = plan.PlanName,
|
||||
ProjectName = project?.ProjectName ?? string.Empty,
|
||||
BookName = book?.BookTitle ?? "All Books",
|
||||
BookName = book?.BookDisplayTitle ?? "All Books",
|
||||
GoalType = plan.GoalType,
|
||||
StartDate = plan.StartDate.Date,
|
||||
DeadlineDate = plan.DeadlineDate.Date,
|
||||
@ -5683,7 +5683,7 @@ public sealed class WritingScheduleService(
|
||||
.Select(x => new SelectListItem(x.ProjectName, x.ProjectID.ToString(), x.ProjectID == model.ProjectID))
|
||||
.ToList();
|
||||
model.BookOptions = bookRows
|
||||
.Select(x => new SelectListItem(x.BookTitle, x.BookID.ToString(), x.BookID == model.BookID))
|
||||
.Select(x => new SelectListItem(x.BookDisplayTitle, x.BookID.ToString(), x.BookID == model.BookID))
|
||||
.ToList();
|
||||
model.GoalTypeOptions = ScheduleOptionList(["FirstDraft", "Revision", "BetaReady", "Custom"], model.GoalType);
|
||||
model.RebalanceModeOptions = ScheduleOptionList(["Ask", "Automatic", "Never"], model.RebalanceMode);
|
||||
@ -6484,7 +6484,7 @@ public sealed class ExportService(IExportRepository exports) : IExportService
|
||||
|
||||
private static void AppendSceneHeader(StringBuilder builder, ExportSceneBriefHeader scene, bool markdown)
|
||||
{
|
||||
Heading(builder, $"{scene.BookTitle} / Chapter {scene.ChapterNumber} / Scene {scene.SceneNumber}: {scene.SceneTitle}", markdown);
|
||||
Heading(builder, $"{scene.BookDisplayTitle} / Chapter {scene.ChapterNumber} / Scene {scene.SceneNumber}: {scene.SceneTitle}", markdown);
|
||||
builder.AppendLine($"- POV: {scene.PovCharacterName ?? "Not set"}");
|
||||
builder.AppendLine($"- Location: {scene.LocationPath ?? "Not set"}");
|
||||
builder.AppendLine($"- Time: {scene.TimeLabel}");
|
||||
@ -6499,7 +6499,7 @@ public sealed class ExportService(IExportRepository exports) : IExportService
|
||||
|
||||
private static void AppendChapterHeader(StringBuilder builder, ExportChapterBriefHeader chapter, bool markdown)
|
||||
{
|
||||
Heading(builder, $"{chapter.BookTitle} / Chapter {chapter.ChapterNumber}: {chapter.ChapterTitle}", markdown);
|
||||
Heading(builder, $"{chapter.BookDisplayTitle} / Chapter {chapter.ChapterNumber}: {chapter.ChapterTitle}", markdown);
|
||||
builder.AppendLine($"- Revision: {chapter.RevisionStatusName}");
|
||||
AppendBlock(builder, "Summary", chapter.Summary, markdown);
|
||||
AppendBlock(builder, "Goal", chapter.GoalSummary, markdown);
|
||||
@ -6519,9 +6519,9 @@ public sealed class ExportService(IExportRepository exports) : IExportService
|
||||
{
|
||||
if (!rows.Any()) return;
|
||||
Heading(builder, "Timeline Summary", markdown);
|
||||
foreach (var book in rows.GroupBy(x => new { x.BookID, x.BookTitle }))
|
||||
foreach (var book in rows.GroupBy(x => new { x.BookID, x.BookDisplayTitle }))
|
||||
{
|
||||
builder.AppendLine(markdown ? $"### {book.Key.BookTitle}" : book.Key.BookTitle);
|
||||
builder.AppendLine(markdown ? $"### {book.Key.BookDisplayTitle}" : book.Key.BookDisplayTitle);
|
||||
foreach (var scene in book)
|
||||
{
|
||||
builder.AppendLine($"- Chapter {scene.ChapterNumber}, Scene {scene.SceneNumber}: {scene.SceneTitle}");
|
||||
@ -6590,7 +6590,7 @@ public sealed class ExportService(IExportRepository exports) : IExportService
|
||||
builder.AppendLine($"- Height: {c.Height}");
|
||||
builder.AppendLine($"- Eye colour: {c.EyeColour}");
|
||||
if (!string.IsNullOrWhiteSpace(c.DefaultDescription)) builder.AppendLine().AppendLine(c.DefaultDescription).AppendLine();
|
||||
foreach (var app in packet.CharacterAppearances) builder.AppendLine($"- Appearance: {app.BookTitle} / Ch {app.ChapterNumber} / Scene {app.SceneNumber}: {app.SceneTitle} ({app.RoleInSceneTypeName})");
|
||||
foreach (var app in packet.CharacterAppearances) builder.AppendLine($"- Appearance: {app.BookDisplayTitle} / Ch {app.ChapterNumber} / Scene {app.SceneNumber}: {app.SceneTitle} ({app.RoleInSceneTypeName})");
|
||||
foreach (var rel in packet.CharacterRelationships) builder.AppendLine($"- Relationship: {rel.CharacterAName} / {rel.CharacterBName}: {rel.RelationshipTypeName}");
|
||||
foreach (var item in packet.CharacterKnowledge) builder.AppendLine($"- Knowledge: {item.KnowledgeStateName} - {item.AssetName ?? item.ThreadTitle}: {item.Description}");
|
||||
builder.AppendLine();
|
||||
@ -6614,7 +6614,7 @@ public sealed class ExportService(IExportRepository exports) : IExportService
|
||||
Heading(builder, "Research Pack", markdown);
|
||||
foreach (var item in rows)
|
||||
{
|
||||
builder.AppendLine($"- {item.BookTitle} / Ch {item.ChapterNumber} / Scene {item.SceneNumber}: {item.Topic} - {item.Title}");
|
||||
builder.AppendLine($"- {item.BookDisplayTitle} / Ch {item.ChapterNumber} / Scene {item.SceneNumber}: {item.Topic} - {item.Title}");
|
||||
if (!string.IsNullOrWhiteSpace(item.Detail)) builder.AppendLine($" {item.Detail}");
|
||||
if (!string.IsNullOrWhiteSpace(item.Reference)) builder.AppendLine($" {item.Reference}");
|
||||
}
|
||||
@ -6753,7 +6753,7 @@ public sealed class ScenarioService(IProjectRepository projects, IBookRepository
|
||||
ProjectID = projectId,
|
||||
BookID = bookId,
|
||||
BookOptions = (await books.ListByProjectAsync(projectId))
|
||||
.Select(x => new SelectListItem($"Book {x.BookNumber}: {x.BookTitle}", x.BookID.ToString(), x.BookID == bookId))
|
||||
.Select(x => new SelectListItem($"Book {x.BookNumber}: {x.BookDisplayTitle}", x.BookID.ToString(), x.BookID == bookId))
|
||||
.ToList()
|
||||
};
|
||||
}
|
||||
@ -7515,7 +7515,7 @@ public sealed class CharacterService(
|
||||
CharacterOptions = projectCharacters.Select(x => new SelectListItem(x.CharacterName, x.CharacterID.ToString())).ToList(),
|
||||
RelationshipTypeOptions = ToRelationshipTypeSelectList(relationshipLookups.RelationshipTypes),
|
||||
RelationshipStateOptions = relationshipLookups.RelationshipStates.Select(x => new SelectListItem(x.StateName, x.RelationshipStateID.ToString())).ToList(),
|
||||
BookOptions = projectBooks.Select(x => new SelectListItem($"Book {x.BookNumber}: {x.BookTitle}", x.BookID.ToString())).ToList()
|
||||
BookOptions = projectBooks.Select(x => new SelectListItem($"Book {x.BookNumber}: {x.BookDisplayTitle}", x.BookID.ToString())).ToList()
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
1109
PlotLine/Sql/068_BookDisplayTitles.sql
Normal file
1109
PlotLine/Sql/068_BookDisplayTitles.sql
Normal file
File diff suppressed because it is too large
Load Diff
@ -17,7 +17,7 @@
|
||||
chapterLabel = $"Chapter {point.ChapterNumber:g}",
|
||||
sceneNumber = point.SceneNumber.ToString("g"),
|
||||
sceneTitle = point.SceneTitle,
|
||||
bookTitle = point.BookTitle,
|
||||
bookTitle = point.BookDisplayTitle,
|
||||
timelineUrl = Url.Action("Index", "Timeline", new { ProjectID = Model.Project.ProjectID, BookID = point.BookID, SelectedSceneID = point.SceneID, FocusType = "scene", FocusID = point.SceneID })
|
||||
})
|
||||
.ToList();
|
||||
|
||||
@ -97,9 +97,9 @@
|
||||
{
|
||||
<span>@relationship.InitialRelationshipStateName@if (relationship.InitialIntensity.HasValue) { <text> / Intensity @relationship.InitialIntensity</text> }</span>
|
||||
}
|
||||
@if (!string.IsNullOrWhiteSpace(relationship.InitialBookTitle))
|
||||
@if (!string.IsNullOrWhiteSpace(relationship.InitialBookDisplayTitle))
|
||||
{
|
||||
<span>Initial book: @relationship.InitialBookTitle</span>
|
||||
<span>Initial book: @relationship.InitialBookDisplayTitle</span>
|
||||
}
|
||||
@if (!string.IsNullOrWhiteSpace(relationship.Notes))
|
||||
{
|
||||
@ -289,7 +289,7 @@
|
||||
@foreach (var item in current.Events)
|
||||
{
|
||||
<div class="asset-mini-item">
|
||||
<strong>@item.BookTitle / Ch @item.ChapterNumber / Scene @item.SceneNumber: @item.SceneTitle</strong>
|
||||
<strong>@item.BookDisplayTitle / Ch @item.ChapterNumber / Scene @item.SceneNumber: @item.SceneTitle</strong>
|
||||
<span>@item.RelationshipStateName <span class="status-pill">@item.RelationshipCategoryName</span> / Intensity @(item.Intensity?.ToString() ?? "Unknown")</span>
|
||||
<span>Awareness: @(item.IsKnownToOtherCharacter ? "known to other character" : "not known to other character")</span>
|
||||
@if (!string.IsNullOrWhiteSpace(item.Description))
|
||||
@ -324,7 +324,7 @@
|
||||
{
|
||||
<div class="asset-mini-item">
|
||||
<strong>@item.CharacterAName -> @item.CharacterBName: @item.RelationshipStateName</strong>
|
||||
<span>@item.BookTitle / Ch @item.ChapterNumber / Scene @item.SceneNumber: @item.SceneTitle</span>
|
||||
<span>@item.BookDisplayTitle / Ch @item.ChapterNumber / Scene @item.SceneNumber: @item.SceneTitle</span>
|
||||
<span>@item.RelationshipTypeName <span class="status-pill">@item.RelationshipCategoryName</span> / Awareness: @(item.IsKnownToOtherCharacter ? "known to other character" : "not known to other character")</span>
|
||||
<span>Reciprocal: @(item.IsReciprocal ? "Yes" : "No") / Confidence / intensity: @(item.Intensity?.ToString() ?? "Unknown")</span>
|
||||
@if (!string.IsNullOrWhiteSpace(item.Description))
|
||||
@ -351,7 +351,7 @@
|
||||
@foreach (var appearance in Model.Appearances)
|
||||
{
|
||||
<div class="asset-mini-item">
|
||||
<strong>@appearance.BookTitle / Ch @appearance.ChapterNumber / Scene @appearance.SceneNumber: @appearance.SceneTitle</strong>
|
||||
<strong>@appearance.BookDisplayTitle / Ch @appearance.ChapterNumber / Scene @appearance.SceneNumber: @appearance.SceneTitle</strong>
|
||||
<span>@appearance.RoleInSceneTypeName / @appearance.PresenceTypeName</span>
|
||||
<span>@appearance.OutfitDescription @appearance.PhysicalCondition @appearance.EmotionalState</span>
|
||||
<a asp-controller="Timeline" asp-action="Index" asp-route-ProjectID="@Model.Project.ProjectID" asp-route-SelectedSceneID="@appearance.SceneID" asp-route-FocusType="character" asp-route-FocusID="@Model.Character.CharacterID">Open in timeline</a>
|
||||
@ -374,7 +374,7 @@
|
||||
{
|
||||
<div class="asset-mini-item">
|
||||
<strong>@item.AttributeName: @item.AttributeValue</strong>
|
||||
<span>@item.BookTitle / Ch @item.ChapterNumber / Scene @item.SceneNumber: @item.SceneTitle</span>
|
||||
<span>@item.BookDisplayTitle / Ch @item.ChapterNumber / Scene @item.SceneNumber: @item.SceneTitle</span>
|
||||
<span>@item.Description</span>
|
||||
<a asp-controller="Timeline" asp-action="Index" asp-route-ProjectID="@Model.Project.ProjectID" asp-route-SelectedSceneID="@item.SceneID" asp-route-FocusType="character" asp-route-FocusID="@Model.Character.CharacterID">Open in timeline</a>
|
||||
</div>
|
||||
@ -396,7 +396,7 @@
|
||||
{
|
||||
<div class="asset-mini-item">
|
||||
<strong>@item.KnowledgeStateName: @(item.AssetName ?? item.ThreadTitle)</strong>
|
||||
<span>@item.BookTitle / Ch @item.ChapterNumber / Scene @item.SceneNumber: @item.SceneTitle</span>
|
||||
<span>@item.BookDisplayTitle / Ch @item.ChapterNumber / Scene @item.SceneNumber: @item.SceneTitle</span>
|
||||
<span>@item.Description</span>
|
||||
<a asp-controller="Timeline" asp-action="Index" asp-route-ProjectID="@Model.Project.ProjectID" asp-route-SelectedSceneID="@item.SceneID" asp-route-FocusType="character" asp-route-FocusID="@Model.Character.CharacterID">Open in timeline</a>
|
||||
</div>
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
chapterLabel = $"Chapter {point.ChapterNumber:g}",
|
||||
sceneNumber = point.SceneNumber.ToString("g"),
|
||||
sceneTitle = point.SceneTitle,
|
||||
bookTitle = point.BookTitle,
|
||||
bookTitle = point.BookDisplayTitle,
|
||||
characterAppears = true,
|
||||
characterPresence = point.IsPov ? "POV scene" : point.PresenceTypeName ?? "Appears",
|
||||
timelineUrl = Url.Action("Edit", "Scenes", new { id = point.SceneID })
|
||||
@ -112,7 +112,7 @@
|
||||
{
|
||||
<article class="writer-queue-card">
|
||||
<div class="writer-queue-title">
|
||||
<h3>@point.BookTitle / Ch @point.ChapterNumber / Scene @point.SceneNumber: @point.SceneTitle</h3>
|
||||
<h3>@point.BookDisplayTitle / Ch @point.ChapterNumber / Scene @point.SceneNumber: @point.SceneTitle</h3>
|
||||
@if (point.IsPov) { <span class="status-pill">POV</span> }
|
||||
</div>
|
||||
<div class="story-bible-meta">
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
{
|
||||
<article class="writer-queue-card">
|
||||
<div class="writer-queue-title">
|
||||
<h3>@item.BookTitle / Ch @item.ChapterNumber / Scene @item.SceneNumber: @item.SceneTitle</h3>
|
||||
<h3>@item.BookDisplayTitle / Ch @item.ChapterNumber / Scene @item.SceneNumber: @item.SceneTitle</h3>
|
||||
<span class="status-pill">@item.KnowledgeStateName</span>
|
||||
</div>
|
||||
<p><strong>@(item.AssetName ?? item.ThreadTitle ?? "Knowledge")</strong> @item.Description</p>
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
{
|
||||
<article class="writer-queue-card">
|
||||
<div class="writer-queue-title">
|
||||
<h3>@item.BookTitle / Ch @item.ChapterNumber / Scene @item.SceneNumber: @item.SceneTitle</h3>
|
||||
<h3>@item.BookDisplayTitle / Ch @item.ChapterNumber / Scene @item.SceneNumber: @item.SceneTitle</h3>
|
||||
<span class="status-pill">@item.RelationshipStateName</span>
|
||||
</div>
|
||||
<div class="story-bible-meta">
|
||||
|
||||
@ -15,13 +15,13 @@
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<p class="eyebrow">Current position</p>
|
||||
<p><strong>@Model.Preview.SourceBookTitle</strong></p>
|
||||
<p><strong>@Model.Preview.SourceBookDisplayTitle</strong></p>
|
||||
<p>Chapter @Model.Preview.SourceChapterNumber: @Model.Preview.SourceChapterTitle</p>
|
||||
<p>Scene @Model.Preview.SceneNumber: @Model.Preview.SceneTitle</p>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<p class="eyebrow">Proposed position</p>
|
||||
<p><strong>@Model.Preview.TargetBookTitle</strong></p>
|
||||
<p><strong>@Model.Preview.TargetBookDisplayTitle</strong></p>
|
||||
<p>Chapter @Model.Preview.TargetChapterNumber: @Model.Preview.TargetChapterTitle</p>
|
||||
<p>Position: @Model.Preview.Position.ToLowerInvariant()</p>
|
||||
</div>
|
||||
|
||||
@ -119,7 +119,7 @@
|
||||
<span class="asset-event-marker">@assetEvent.MarkerText</span>
|
||||
<div class="story-asset-event-details">
|
||||
<strong>@assetEvent.EventTitle</strong>
|
||||
<span>@assetEvent.BookTitle / Ch @assetEvent.ChapterNumber / Scene @assetEvent.SceneNumber: @assetEvent.SceneTitle</span>
|
||||
<span>@assetEvent.BookDisplayTitle / Ch @assetEvent.ChapterNumber / Scene @assetEvent.SceneNumber: @assetEvent.SceneTitle</span>
|
||||
<span>@assetEvent.FromStateName -> @assetEvent.ToStateName</span>
|
||||
<a asp-controller="Timeline" asp-action="Index" asp-route-ProjectID="@Model.Project.ProjectID" asp-route-SelectedSceneID="@assetEvent.SceneID" asp-route-FocusType="asset" asp-route-FocusID="@Model.Asset.StoryAssetID">Open in timeline</a>
|
||||
</div>
|
||||
@ -143,7 +143,7 @@
|
||||
<div class="asset-mini-item">
|
||||
<strong>@custody.CustodyEventTypeName</strong>
|
||||
<span>@custody.CustodianSummary</span>
|
||||
<span>@custody.BookTitle / Ch @custody.ChapterNumber / Scene @custody.SceneNumber: @custody.SceneTitle</span>
|
||||
<span>@custody.BookDisplayTitle / Ch @custody.ChapterNumber / Scene @custody.SceneNumber: @custody.SceneTitle</span>
|
||||
<a asp-controller="Timeline" asp-action="Index" asp-route-ProjectID="@Model.Project.ProjectID" asp-route-SelectedSceneID="@custody.SceneID" asp-route-FocusType="asset" asp-route-FocusID="@Model.Asset.StoryAssetID">Open in timeline</a>
|
||||
</div>
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
@{
|
||||
ViewData["Title"] = $"Story Bible - {Model.Project.ProjectName}";
|
||||
ViewData["ProjectSection"] = "Story Bible";
|
||||
var timelineByBook = Model.Timeline.GroupBy(x => new { x.BookID, x.BookTitle });
|
||||
var timelineByBook = Model.Timeline.GroupBy(x => new { x.BookID, x.BookDisplayTitle });
|
||||
var relationshipsByCharacter = Model.Relationships.GroupBy(x => new { x.CharacterAID, x.CharacterAName });
|
||||
var revisionByGroup = Model.RevisionItems.GroupBy(x => x.GroupName);
|
||||
}
|
||||
@ -295,7 +295,7 @@
|
||||
@foreach (var book in timelineByBook)
|
||||
{
|
||||
<article class="story-bible-card story-bible-wide-card">
|
||||
<h3>@book.Key.BookTitle</h3>
|
||||
<h3>@book.Key.BookDisplayTitle</h3>
|
||||
@foreach (var chapter in book.GroupBy(x => new { x.ChapterID, x.ChapterNumber, x.ChapterTitle }))
|
||||
{
|
||||
<div class="story-bible-chapter-summary">
|
||||
|
||||
@ -34,10 +34,10 @@
|
||||
sceneId = column.Scene?.SceneID,
|
||||
isPlaceholder = column.Scene is null,
|
||||
axisLabel = column.Scene is null ? string.Empty : $"Ch {column.Chapter?.Chapter.ChapterNumber:g}.{column.Scene.SceneNumber:g}",
|
||||
chapterLabel = column.Chapter is null ? column.Book.Book.BookTitle : $"Chapter {column.Chapter.Chapter.ChapterNumber:g}",
|
||||
chapterLabel = column.Chapter is null ? column.Book.Book.BookDisplayTitle : $"Chapter {column.Chapter.Chapter.ChapterNumber:g}",
|
||||
sceneNumber = column.Scene?.SceneNumber.ToString("g"),
|
||||
sceneTitle = column.Scene?.SceneTitle ?? column.PlaceholderLabel,
|
||||
bookTitle = column.Book.Book.BookTitle,
|
||||
bookTitle = column.Book.Book.BookDisplayTitle,
|
||||
timelineUrl = column.Scene is null ? null : Url.Action("Index", "Timeline", new { projectId = Model.Project.ProjectID, bookId = column.Book.Book.BookID, selectedSceneId = column.Scene.SceneID })
|
||||
}).ToList();
|
||||
var timelineMetricShapePayload = new
|
||||
@ -117,7 +117,7 @@
|
||||
<a asp-controller="Projects" asp-action="Details" asp-route-id="@Model.Project.ProjectID">@Model.Project.ProjectName</a>
|
||||
@if (selectedBook is not null)
|
||||
{
|
||||
<span>@selectedBook.BookTitle</span>
|
||||
<span>@selectedBook.BookDisplayTitle</span>
|
||||
}
|
||||
<span>Timeline</span>
|
||||
</nav>
|
||||
@ -611,7 +611,7 @@ else
|
||||
<div class="timeline-book" style="--book-scene-count:@BookSceneColumns(book)">
|
||||
<div class="timeline-book-title">
|
||||
<span>Book @book.Book.BookNumber</span>
|
||||
<strong>@book.Book.BookTitle</strong>
|
||||
<strong>@book.Book.BookDisplayTitle</strong>
|
||||
</div>
|
||||
<div class="timeline-chapters">
|
||||
@if (!book.Chapters.Any())
|
||||
|
||||
@ -85,7 +85,7 @@
|
||||
{
|
||||
<tr>
|
||||
<td>@item.TaskType</td>
|
||||
<td>@item.BookTitle</td>
|
||||
<td>@item.BookDisplayTitle</td>
|
||||
<td>Chapter @item.ChapterNumber: @item.ChapterTitle</td>
|
||||
<td>
|
||||
<a asp-controller="Scenes" asp-action="Edit" asp-route-id="@item.SceneID">
|
||||
@ -154,7 +154,7 @@
|
||||
<tr>
|
||||
<td>@item.ScheduledDate.ToString("dd MMM yyyy")</td>
|
||||
<td>@item.TaskType</td>
|
||||
<td>@item.BookTitle</td>
|
||||
<td>@item.BookDisplayTitle</td>
|
||||
<td>Chapter @item.ChapterNumber: @item.ChapterTitle</td>
|
||||
<td>
|
||||
<a asp-controller="Scenes" asp-action="Edit" asp-route-id="@item.SceneID">
|
||||
|
||||
@ -58,7 +58,7 @@ else
|
||||
@foreach (var plan in Model.Plans)
|
||||
{
|
||||
<option value="@plan.WritingPlanID" selected="@(plan.WritingPlanID == Model.SelectedWritingPlanID)">
|
||||
@plan.PlanName - @plan.ProjectName / @(plan.BookTitle ?? "All Books") - @plan.DeadlineDate.ToString("dd MMM yyyy") - @(plan.IsActive ? "Active" : "Inactive")
|
||||
@plan.PlanName - @plan.ProjectName / @(string.IsNullOrWhiteSpace(plan.BookDisplayTitle) ? "All Books" : plan.BookDisplayTitle) - @plan.DeadlineDate.ToString("dd MMM yyyy") - @(plan.IsActive ? "Active" : "Inactive")
|
||||
</option>
|
||||
}
|
||||
</select>
|
||||
@ -83,7 +83,7 @@ else
|
||||
<tr>
|
||||
<td>@plan.PlanName</td>
|
||||
<td>@plan.ProjectName</td>
|
||||
<td>@(plan.BookTitle ?? "All Books")</td>
|
||||
<td>@(string.IsNullOrWhiteSpace(plan.BookDisplayTitle) ? "All Books" : plan.BookDisplayTitle)</td>
|
||||
<td>@plan.DeadlineDate.ToString("dd MMM yyyy")</td>
|
||||
<td>@(plan.IsActive ? "Yes" : "No")</td>
|
||||
<td>
|
||||
@ -165,7 +165,7 @@ else
|
||||
<tr>
|
||||
<td>@item.ScheduledDate.ToString("dd MMM yyyy")</td>
|
||||
<td>@item.TaskType</td>
|
||||
<td>@item.BookTitle</td>
|
||||
<td>@item.BookDisplayTitle</td>
|
||||
<td>Chapter @item.ChapterNumber: @item.ChapterTitle</td>
|
||||
<td>Scene @item.SceneNumber: @item.SceneTitle</td>
|
||||
<td>@(item.Priority?.ToString() ?? "-")</td>
|
||||
|
||||
@ -70,7 +70,7 @@
|
||||
<tr>
|
||||
<td>@plan.PlanName</td>
|
||||
<td>@plan.ProjectName</td>
|
||||
<td>@(plan.BookTitle ?? "All Books")</td>
|
||||
<td>@(string.IsNullOrWhiteSpace(plan.BookDisplayTitle) ? "All Books" : plan.BookDisplayTitle)</td>
|
||||
<td>@plan.GoalType</td>
|
||||
<td>@plan.StartDate.ToString("dd MMM yyyy")</td>
|
||||
<td>@plan.DeadlineDate.ToString("dd MMM yyyy")</td>
|
||||
|
||||
@ -12,7 +12,7 @@ else
|
||||
<article class="writer-queue-card">
|
||||
<div class="writer-queue-title">
|
||||
<div>
|
||||
<span class="eyebrow">@scene.BookTitle / Chapter @scene.ChapterNumber</span>
|
||||
<span class="eyebrow">@scene.BookDisplayTitle / Chapter @scene.ChapterNumber</span>
|
||||
<h3>
|
||||
<a asp-controller="Scenes" asp-action="Edit" asp-route-id="@scene.SceneID">
|
||||
Scene @scene.SceneNumber: @scene.SceneTitle
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user