feat(ui): hide management controls for system collections

System collections (Not Started, Continue Reading, etc.) compute
their contents dynamically from reading_progress, so manual
add/remove has no effect. Hide the search bar, Remove Selected
button, Add Books button, per-card checkboxes, and Remove buttons
when the collection is system, making the page visually read-only.

- Add IsSystem bool to CollectionData, populated from the database
  is_system_collection flag.
- Add data-is-system to #collection-data so the JS renderer can
  also conditionally omit controls on library switch.
- Wrap toolbar controls, book picker modal, card checkboxes, and
  remove buttons in if !collection.IsSystem in the template.
This commit is contained in:
2026-08-06 11:08:29 -04:00
parent ef3c05714a
commit 40dabfd788
5 changed files with 343 additions and 275 deletions
+8 -4
View File
@@ -127,6 +127,9 @@ function renderCollectionBooks(books: BookInfo[]): void {
const container = document.getElementById("books-container");
if (!container) return;
const dataEl = document.getElementById("collection-data");
const isSystem = dataEl?.dataset.isSystem === "true";
if (books.length === 0) {
container.innerHTML = `<div id="empty-state" class="col-span-full text-center py-16" style="color: var(--text-secondary)">No books in this collection yet.</div>`;
return;
@@ -137,13 +140,14 @@ function renderCollectionBooks(books: BookInfo[]): void {
(book) => `
<div class="card p-4 rounded-2xl collection-book-card" data-title="${book.title}" data-author="${book.author || ""}" data-media-id="${book.media_item_id}">
<div class="flex gap-4">
${isSystem ? "" : `
<div class="flex-shrink-0 pt-1">
<label class="flex items-center cursor-pointer p-2 -m-2">
<input type="checkbox" class="w-5 h-5"
:checked="selectedBooks.includes('${book.media_item_id}')"
@change="toggleSelection('${book.media_item_id}')"/>
</label>
</div>
</div>`}
<div class="flex-1 min-w-0">
<a href="/media/${book.media_item_id}">
<h3 class="font-semibold text-lg mb-1 line-clamp-2 hover:underline" style="color: var(--text-primary)">${book.title}</h3>
@@ -158,12 +162,12 @@ function renderCollectionBooks(books: BookInfo[]): void {
</a>
</div>
</div>
${isSystem ? "" : `
<div class="mt-3 pt-3 border-t" style="border-color: var(--border);">
<button @click="requestRemoveBook('${book.media_item_id}')" class="btn btn-secondary w-full">
<svg class="h-4 w-4 inline" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6l-2 14a2 2 0 0 1-2 2H9a2 2 0 0 1-2-2L5 6"></path><path d="M10 11v6"></path><path d="M14 11v6"></path></svg>
Remove from Collection
🗑️ Remove from Collection
</button>
</div>
</div>`}
</div>
`,
)