[PR #4962] feat: Enable series name editing with duplicate validation #4383

Open
opened 2026-04-25 00:19:32 +02:00 by adam · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/advplyr/audiobookshelf/pull/4962
Author: @H2OKing89
Created: 1/4/2026
Status: 🔄 Open

Base: masterHead: feat/series-name-editing-v2


📝 Commits (1)

  • 5431665 feat: Enable series name editing with duplicate validation

📊 Changes

4 files changed (+49 additions, -7 deletions)

View changed files

📝 client/components/modals/EditSeriesInputInnerModal.vue (+1 -1)
📝 client/components/widgets/SeriesInputWidget.vue (+33 -5)
📝 client/strings/en-us.json (+1 -0)
📝 server/controllers/SeriesController.js (+14 -1)

📄 Description

Brief summary

Enables editing of series names directly from the book/series edit modal with proper duplicate name validation. Previously, the series name field was locked (disabled) when editing existing series, forcing users to use workarounds or third-party tools.

Which issue is fixed?

Addresses user feedback from #4937:

  • @iconoclasthero: "I just want to be able to edit the series name... I have yet to fathom why that's a locked field."
  • @Vito0912: Noted users need external tools for renaming series

Also resolves the long-standing TODO in SeriesController.js:

// TODO: Currently unused in the client, should check for duplicate name

In-depth Description

Why was it locked?

The series name field was disabled in EditSeriesInputInnerModal.vue when editing existing series, likely to prevent accidental renames that affect multiple books. However, this forced users to:

  • Manually delete and recreate series
  • Use third-party tools like abstoolbox
  • Work around the limitation

What this PR does

Backend (SeriesController.js):

  • Implements duplicate name validation (resolves TODO)
  • Checks if another series with the same name exists in the same library before renaming
  • Updates nameIgnorePrefix when series name changes (important for sorting)
  • Returns descriptive error messages for validation failures

Frontend:

  • Removes :disabled lock on series name input
  • Adds originalSeriesName tracking to detect changes
  • Validates duplicate names before submitting
  • Calls PATCH /api/series/:id immediately when renaming existing series
  • Shows backend error messages in toast notifications
  • Prevents accidental overwrites with proper checks

How it works

  1. User edits series → Opens edit modal, name field is now editable
  2. User changes name → Frontend tracks the change
  3. Frontend validation → Checks if new name conflicts with existing series in library
  4. Submit → Sends PATCH request to backend
  5. Backend validation → Double-checks for duplicates, updates nameIgnorePrefix
  6. Success → Series renamed, all books in series automatically see the new name (linked by UUID, not name)
  7. Socket eventseries_updated notifies all clients

Why this is safe

  • Books link to series by UUID, not by name - renaming doesn't break relationships
  • Duplicate validation on both frontend and backend prevents name collisions
  • Same library only - allows same series names across different libraries
  • Immediate PATCH - changes are persisted to database immediately, not deferred

How have you tested this?

Manual Testing

  1. Rename existing series - Changed "Harry Potter" to "Harry Potter Series"

    • All books updated correctly
    • Series list shows new name
    • Sorting still works (nameIgnorePrefix updated)
  2. Duplicate name validation - Tried renaming to an existing series name

    • Frontend: Shows toast error "A series with that name already exists in this library"
    • Backend: Returns 400 with descriptive message
    • Original name preserved
  3. Empty name validation - Tried submitting empty name

    • Shows "Must enter a series" error
    • Form doesn't submit
  4. New series creation - Still works as before

    • Can type new series name
    • If matches existing series, uses that series ID
  5. Cross-library series - Same series name in different libraries

    • Works correctly, only checks within same library

Automated Testing

  • All 315 existing tests pass
  • No regressions introduced

Edge Cases Tested

  • Renaming to same name (no-op, no error)
  • Renaming with different capitalization (allowed)
  • Multiple books in renamed series (all updated)
  • Socket updates propagate to other clients

Screenshots

Screenshots (click to expand)

Before (series name disabled):
image

After (series name editable):
image

Validation in action:
When attempting to rename to existing series name:

  • Toast appears: "A series with that name already exists in this library"
  • Form doesn't submit
  • Original name preserved

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/advplyr/audiobookshelf/pull/4962 **Author:** [@H2OKing89](https://github.com/H2OKing89) **Created:** 1/4/2026 **Status:** 🔄 Open **Base:** `master` ← **Head:** `feat/series-name-editing-v2` --- ### 📝 Commits (1) - [`5431665`](https://github.com/advplyr/audiobookshelf/commit/5431665dfe73727f801cecdd16d86b711eb208c2) feat: Enable series name editing with duplicate validation ### 📊 Changes **4 files changed** (+49 additions, -7 deletions) <details> <summary>View changed files</summary> 📝 `client/components/modals/EditSeriesInputInnerModal.vue` (+1 -1) 📝 `client/components/widgets/SeriesInputWidget.vue` (+33 -5) 📝 `client/strings/en-us.json` (+1 -0) 📝 `server/controllers/SeriesController.js` (+14 -1) </details> ### 📄 Description ## Brief summary Enables editing of series names directly from the book/series edit modal with proper duplicate name validation. Previously, the series name field was locked (disabled) when editing existing series, forcing users to use workarounds or third-party tools. ## Which issue is fixed? Addresses user feedback from #4937: - @iconoclasthero: "I just want to be able to edit the series name... I have yet to fathom why that's a locked field." - @Vito0912: Noted users need external tools for renaming series Also resolves the long-standing TODO in `SeriesController.js`: ```javascript // TODO: Currently unused in the client, should check for duplicate name ``` ## In-depth Description ### Why was it locked? The series name field was disabled in `EditSeriesInputInnerModal.vue` when editing existing series, likely to prevent accidental renames that affect multiple books. However, this forced users to: - Manually delete and recreate series - Use third-party tools like [abstoolbox](https://abstoolbox.vito0912.de/tools) - Work around the limitation ### What this PR does **Backend (`SeriesController.js`):** - ✅ Implements duplicate name validation (resolves TODO) - ✅ Checks if another series with the same name exists in the same library before renaming - ✅ Updates `nameIgnorePrefix` when series name changes (important for sorting) - ✅ Returns descriptive error messages for validation failures **Frontend:** - ✅ Removes `:disabled` lock on series name input - ✅ Adds `originalSeriesName` tracking to detect changes - ✅ Validates duplicate names before submitting - ✅ Calls `PATCH /api/series/:id` immediately when renaming existing series - ✅ Shows backend error messages in toast notifications - ✅ Prevents accidental overwrites with proper checks ### How it works 1. **User edits series** → Opens edit modal, name field is now editable 2. **User changes name** → Frontend tracks the change 3. **Frontend validation** → Checks if new name conflicts with existing series in library 4. **Submit** → Sends PATCH request to backend 5. **Backend validation** → Double-checks for duplicates, updates `nameIgnorePrefix` 6. **Success** → Series renamed, all books in series automatically see the new name (linked by UUID, not name) 7. **Socket event** → `series_updated` notifies all clients ### Why this is safe - **Books link to series by UUID**, not by name - renaming doesn't break relationships - **Duplicate validation** on both frontend and backend prevents name collisions - **Same library only** - allows same series names across different libraries - **Immediate PATCH** - changes are persisted to database immediately, not deferred ## How have you tested this? ### Manual Testing 1. ✅ **Rename existing series** - Changed "Harry Potter" to "Harry Potter Series" - All books updated correctly - Series list shows new name - Sorting still works (nameIgnorePrefix updated) 2. ✅ **Duplicate name validation** - Tried renaming to an existing series name - Frontend: Shows toast error "A series with that name already exists in this library" - Backend: Returns 400 with descriptive message - Original name preserved 3. ✅ **Empty name validation** - Tried submitting empty name - Shows "Must enter a series" error - Form doesn't submit 4. ✅ **New series creation** - Still works as before - Can type new series name - If matches existing series, uses that series ID 5. ✅ **Cross-library series** - Same series name in different libraries - Works correctly, only checks within same library ### Automated Testing - ✅ All 315 existing tests pass - ✅ No regressions introduced ### Edge Cases Tested - Renaming to same name (no-op, no error) - Renaming with different capitalization (allowed) - Multiple books in renamed series (all updated) - Socket updates propagate to other clients ## Screenshots <details> <summary>Screenshots (click to expand)</summary> Before (series name disabled): <img width="2154" height="1287" alt="image" src="https://github.com/user-attachments/assets/9ecec189-bbec-4ff9-8139-01e840fcd0fc" /> After (series name editable): <img width="2208" height="1187" alt="image" src="https://github.com/user-attachments/assets/35c04d07-8b7a-41d5-8c59-e9fcce7c92dd" /> </details> **Validation in action:** When attempting to rename to existing series name: - Toast appears: "A series with that name already exists in this library" - Form doesn't submit - Original name preserved --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
adam added the pull-request label 2026-04-25 00:19:32 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/audiobookshelf#4383