Implemented the Word Companion book display update.

This commit is contained in:
Nick Beckley 2026-06-16 20:41:55 +01:00
parent baf4d7066b
commit 59881a31df
3 changed files with 31 additions and 7 deletions

View File

@ -36,9 +36,23 @@ public sealed class WordCompanionRepository(ISqlConnectionFactory connectionFact
{ {
using var connection = connectionFactory.CreateConnection(); using var connection = connectionFactory.CreateConnection();
var rows = await connection.QueryAsync<WordCompanionBookDto>( var rows = await connection.QueryAsync<WordCompanionBookDto>(
"dbo.WordCompanion_Book_ListByProject", """
SELECT b.BookID AS BookId,
b.BookTitle AS Title,
b.Subtitle,
b.SortOrder
FROM dbo.Books b
INNER JOIN dbo.ProjectUserAccess pua ON pua.ProjectID = b.ProjectID
INNER JOIN dbo.Projects p ON p.ProjectID = b.ProjectID
WHERE b.ProjectID = @ProjectID
AND pua.UserID = @UserID
AND pua.IsActive = 1
AND p.IsArchived = 0
AND b.IsArchived = 0
ORDER BY b.SortOrder, b.BookNumber, b.BookTitle, b.BookID;
""",
new { ProjectID = projectId, UserID = userId }, new { ProjectID = projectId, UserID = userId },
commandType: CommandType.StoredProcedure); commandType: CommandType.Text);
return rows.ToList(); return rows.ToList();
} }

View File

@ -15,6 +15,7 @@ public sealed class WordCompanionBookDto
{ {
public int BookId { get; set; } public int BookId { get; set; }
public string Title { get; set; } = string.Empty; public string Title { get; set; } = string.Empty;
public string? Subtitle { get; set; }
public int SortOrder { get; set; } public int SortOrder { get; set; }
} }

View File

@ -917,6 +917,12 @@
select.disabled = rows.length === 0; select.disabled = rows.length === 0;
}; };
const bookDisplayTitle = (book) => {
const title = String(book?.title || "").trim();
const subtitle = String(book?.subtitle || "").trim();
return subtitle ? `${title}: ${subtitle}` : title;
};
const selectedProject = () => { const selectedProject = () => {
const projectId = Number.parseInt(projectSelect?.value || "", 10); const projectId = Number.parseInt(projectSelect?.value || "", 10);
return projects.find((project) => project.projectId === projectId) || null; return projects.find((project) => project.projectId === projectId) || null;
@ -935,7 +941,7 @@
summaryProject.textContent = project?.title || "(Not connected)"; summaryProject.textContent = project?.title || "(Not connected)";
} }
if (summaryBook) { if (summaryBook) {
summaryBook.textContent = book?.title || "(Not connected)"; summaryBook.textContent = book ? bookDisplayTitle(book) : "(Not connected)";
} }
if (syncNote) { if (syncNote) {
syncNote.textContent = book ? "" : "Select a PlotDirector book before refreshing."; syncNote.textContent = book ? "" : "Select a PlotDirector book before refreshing.";
@ -2203,7 +2209,7 @@
} }
const chapterTitle = normalizeWhitespace(detectedChapterTitle); const chapterTitle = normalizeWhitespace(detectedChapterTitle);
const confirmed = await confirmCreateChapter(chapterTitle, book.title || "selected book"); const confirmed = await confirmCreateChapter(chapterTitle, bookDisplayTitle(book) || "selected book");
if (!confirmed) { if (!confirmed) {
return; return;
} }
@ -2649,7 +2655,7 @@
projectId: project?.projectId, projectId: project?.projectId,
projectTitle: project?.title, projectTitle: project?.title,
bookId: book?.bookId, bookId: book?.bookId,
bookTitle: book?.title, bookTitle: book ? bookDisplayTitle(book) : undefined,
detectedChapter: detectedChapterTitle, detectedChapter: detectedChapterTitle,
detectedScene: detectedSceneTitle, detectedScene: detectedSceneTitle,
requestChapter: requestChapterTitle, requestChapter: requestChapterTitle,
@ -2725,7 +2731,7 @@
projectId: project?.projectId, projectId: project?.projectId,
projectTitle: project?.title, projectTitle: project?.title,
bookId: book?.bookId, bookId: book?.bookId,
bookTitle: book?.title, bookTitle: book ? bookDisplayTitle(book) : undefined,
detectedChapter: detectedChapterTitle, detectedChapter: detectedChapterTitle,
detectedScene: detectedSceneTitle, detectedScene: detectedSceneTitle,
requestChapter: requestChapterTitle, requestChapter: requestChapterTitle,
@ -3098,7 +3104,10 @@
return; return;
} }
addOptions(bookSelect, "Choose a book", books, "bookId", "title"); addOptions(bookSelect, "Choose a book", books.map((book) => ({
...book,
displayTitle: bookDisplayTitle(book)
})), "bookId", "displayTitle");
const validBook = books.find((book) => book.bookId === preferredBookId); const validBook = books.find((book) => book.bookId === preferredBookId);
if (validBook && bookSelect) { if (validBook && bookSelect) {
bookSelect.value = String(validBook.bookId); bookSelect.value = String(validBook.bookId);